]> gcc.gnu.org Git - gcc.git/blob - gcc/config/arm/arm.md
(attributes): Rearrange order, so that condition clobbering can be automatically...
[gcc.git] / gcc / config / arm / arm.md
1 ;;- Machine description for Advanced RISC Machines' ARM for GNU compiler
2 ;; Copyright (C) 1991, 1993, 1994, 1995 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 (rwe11@cl.cam.ac.uk)
6
7 ;; This file is part of GNU CC.
8
9 ;; GNU CC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
12 ;; any later version.
13
14 ;; GNU CC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU CC; see the file COPYING. If not, write to
21 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
23
24 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
25
26 ;; There are patterns in this file to support XFmode arithmetic.
27 ;; Unfortunately RISC iX doesn't work well with these so they are disabled.
28 ;; (See arm.h)
29 \f
30 ;; UNSPEC Usage:
31 ;; 0 `sin' operation: operand 0 is the result, operand 1 the parameter,
32 ;; the mode is MODE_FLOAT
33 ;; 1 `cos' operation: operand 0 is the result, operand 1 the parameter,
34 ;; the mode is MODE_FLOAT
35 ;; 2 `push multiple' operation: operand 0 is the first register. Subsequent
36 ;; registers are in parallel (use...) expressions.
37 ;; 3 A symbol that has been treated properly for pic usage, that is, we
38 ;; will add the pic_register value to it before trying to dereference it.
39 \f
40 ;; Attributes
41
42 ; PROG_MODE attribute is used to determine whether condition codes are
43 ; clobbered by a call insn: they are if in prog32 mode. This is controlled
44 ; by the -mapcs-{32,26} flag, and possibly the -mcpu=... option.
45 (define_attr "prog_mode" "prog26,prog32" (const (symbol_ref "arm_prog_mode")))
46
47 ; CPU attribute is used to determine whether condition codes are clobbered
48 ; by a call insn: on the arm6 they are if in 32-bit addressing mode; on the
49 ; arm2 and arm3 the condition codes are restored by the return.
50
51 (define_attr "cpu" "arm2,arm3,arm6,arm7"
52 (const (symbol_ref "arm_cpu_attr")))
53
54 ; Floating Point Unit. If we only have floating point emulation, then there
55 ; is no point in scheduling the floating point insns. (Well, for best
56 ; performance we should try and group them together).
57
58 (define_attr "fpu" "fpa,fpe2,fpe3" (const (symbol_ref "arm_fpu_attr")))
59
60 ; LENGTH of an instruction (in bytes)
61 (define_attr "length" "" (const_int 4))
62
63 ; An assembler sequence may clobber the condition codes without us knowing
64 (define_asm_attributes
65 [(set_attr "conds" "clob")
66 (set_attr "length" "4")])
67
68 ; TYPE attribute is used to detect floating point instructions which, if
69 ; running on a co-processor can run in parallel with other, basic instructions
70 ; If write-buffer scheduling is enabled then it can also be used in the
71 ; scheduling of writes.
72
73 ; Classification of each insn
74 ; normal any data instruction that doesn't hit memory or fp regs
75 ; mult a multiply instruction
76 ; block blockage insn, this blocks all functional units
77 ; float a floating point arithmetic operation (subject to expansion)
78 ; fdivx XFmode floating point division
79 ; fdivd DFmode floating point division
80 ; fdivs SFmode floating point division
81 ; fmul Floating point multiply
82 ; ffmul Fast floating point multiply
83 ; farith Floating point arithmetic (4 cycle)
84 ; ffarith Fast floating point arithmetic (2 cycle)
85 ; float_em a floating point arithmetic operation that is normally emulated
86 ; even on a machine with an fpa.
87 ; f_load a floating point load from memory
88 ; f_store a floating point store to memory
89 ; f_mem_r a transfer of a floating point register to a real reg via mem
90 ; r_mem_f the reverse of f_mem_r
91 ; f_2_r fast transfer float to arm (no memory needed)
92 ; r_2_f fast transfer arm to float
93 ; call a subroutine call
94 ; load any load from memory
95 ; store1 store 1 word to memory from arm registers
96 ; store2 store 2 words
97 ; store3 store 3 words
98 ; store4 store 4 words
99 ;
100 (define_attr "type"
101 "normal,mult,block,float,fdivx,fdivd,fdivs,fmul,ffmul,farith,ffarith,float_em,f_load,f_store,f_mem_r,r_mem_f,f_2_r,r_2_f,call,load,store1,store2,store3,store4"
102 (const_string "normal"))
103
104 ; condition codes: this one is used by final_prescan_insn to speed up
105 ; conditionalizing instructions. It saves having to scan the rtl to see if
106 ; it uses or alters the condition codes.
107
108 ; USE means that the condition codes are used by the insn in the process of
109 ; outputting code, this means (at present) that we can't use the insn in
110 ; inlined branches
111
112 ; SET means that the purpose of the insn is to set the condition codes in a
113 ; well defined manner.
114
115 ; CLOB means that the condition codes are altered in an undefined manner, if
116 ; they are altered at all
117
118 ; JUMP_CLOB is used when the conditions are not defined if a branch is taken,
119 ; but are if the branch wasn't taken; the effect is to limit the branch
120 ; elimination scanning.
121
122 ; NOCOND means that the condition codes are neither altered nor affect the
123 ; output of this insn
124
125 (define_attr "conds" "use,set,clob,jump_clob,nocond"
126 (if_then_else (eq_attr "type" "call")
127 (if_then_else (eq_attr "prog_mode" "prog32")
128 (const_string "clob") (const_string "nocond"))
129 (const_string "nocond")))
130
131 (define_attr "write_conflict" "no,yes"
132 (if_then_else (eq_attr "type"
133 "block,float_em,f_load,f_store,f_mem_r,r_mem_f,call,load")
134 (const_string "yes")
135 (const_string "no")))
136
137 (define_attr "core_cycles" "single,multi"
138 (if_then_else (eq_attr "type"
139 "normal,float,fdivx,fdivd,fdivs,fmul,ffmul,farith,ffarith")
140 (const_string "single")
141 (const_string "multi")))
142
143 ; The write buffer on some of the arm6 processors is hard to model exactly.
144 ; There is room in the buffer for up to two addresses and up to eight words
145 ; of memory, but the two needn't be split evenly. When writing the two
146 ; addresses are fully pipelined. However, a read from memory that is not
147 ; currently in the cache will block until the writes have completed.
148 ; It is normally the case that FCLK and MCLK will be in the ratio 2:1, so
149 ; writes will take 2 FCLK cycles per word, if FCLK and MCLK are asynchronous
150 ; (they aren't allowed to be at present) then there is a startup cost of 1MCLK
151 ; cycle to add as well.
152
153 ;; (define_function_unit {name} {num-units} {n-users} {test}
154 ;; {ready-delay} {issue-delay} [{conflict-list}])
155 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
156 (eq_attr "type" "fdivx")) 71 69)
157
158 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
159 (eq_attr "type" "fdivd")) 59 57)
160
161 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
162 (eq_attr "type" "fdivs")) 31 29)
163
164 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
165 (eq_attr "type" "fmul")) 9 7)
166
167 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
168 (eq_attr "type" "ffmul")) 6 4)
169
170 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
171 (eq_attr "type" "farith")) 4 2)
172
173 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
174 (eq_attr "type" "ffarith")) 2 2)
175
176 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
177 (eq_attr "type" "r_2_f")) 5 3)
178
179 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
180 (eq_attr "type" "f_2_r")) 1 2)
181
182 ;; The fpa10 doesn't really have a memory read unit, but it can start to
183 ;; speculatively execute the instruction in the pipeline, provided the data
184 ;; is already loaded, so pretend reads have a delay of 2 (and that the
185 ;; pipeline is infinite.
186
187 (define_function_unit "fpa_mem" 1 0 (and (eq_attr "fpu" "fpa")
188 (eq_attr "type" "f_load")) 3 1)
189
190 (define_function_unit "write_buf" 1 2 (eq_attr "type" "store1") 5 3)
191 (define_function_unit "write_buf" 1 2 (eq_attr "type" "store2") 7 4)
192 (define_function_unit "write_buf" 1 2 (eq_attr "type" "store3") 9 5)
193 (define_function_unit "write_buf" 1 2 (eq_attr "type" "store4") 11 6)
194 (define_function_unit "write_buf" 1 2 (eq_attr "type" "r_mem_f") 5 3)
195
196 ;; The write_blockage unit models (partially), the fact that writes will stall
197 ;; until the write buffer empties.
198
199 (define_function_unit "write_blockage" 1 0 (eq_attr "type" "store1") 5 5
200 [(eq_attr "write_conflict" "yes")])
201 (define_function_unit "write_blockage" 1 0 (eq_attr "type" "store2") 7 7
202 [(eq_attr "write_conflict" "yes")])
203 (define_function_unit "write_blockage" 1 0 (eq_attr "type" "store3") 9 9
204 [(eq_attr "write_conflict" "yes")])
205 (define_function_unit "write_blockage" 1 0 (eq_attr "type" "store4") 11 11
206 [(eq_attr "write_conflict" "yes")])
207 (define_function_unit "write_blockage" 1 0 (eq_attr "type" "r_mem_f") 5 5
208 [(eq_attr "write_conflict" "yes")])
209 (define_function_unit "write_blockage" 1 0
210 (eq_attr "write_conflict" "yes") 1 1)
211
212 (define_function_unit "core" 1 1 (eq_attr "core_cycles" "single") 1 1)
213
214 (define_function_unit "core" 1 1 (eq_attr "type" "load") 2 2)
215
216 (define_function_unit "core" 1 1 (eq_attr "type" "mult") 16 16)
217
218 (define_function_unit "core" 1 1 (eq_attr "type" "store1") 2 2)
219
220 (define_function_unit "core" 1 1 (eq_attr "type" "store2") 3 3)
221
222 (define_function_unit "core" 1 1 (eq_attr "type" "store3") 4 4)
223
224 (define_function_unit "core" 1 1 (eq_attr "type" "store4") 5 5)
225
226 (define_function_unit "core" 1 1
227 (and (eq_attr "core_cycles" "multi")
228 (eq_attr "type" "!mult,load,store2,store3,store4")) 32 32)
229
230 \f
231 ;; Note: For DImode insns, there is normally no reason why operands should
232 ;; not be in the same register, what we don't want is for something being
233 ;; written to partially overlap something that is an input.
234
235 ;; Addition insns.
236
237 (define_insn "adddi3"
238 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
239 (plus:DI (match_operand:DI 1 "s_register_operand" "%0,0")
240 (match_operand:DI 2 "s_register_operand" "r,0")))
241 (clobber (reg:CC 24))]
242 ""
243 "adds\\t%0, %1, %2\;adc\\t%R0, %R1, %R2"
244 [(set_attr "conds" "clob")
245 (set_attr "length" "8")])
246
247 (define_insn "*adddi_sesidi_di"
248 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
249 (plus:DI (sign_extend:DI
250 (match_operand:SI 1 "s_register_operand" "r,r"))
251 (match_operand:DI 2 "s_register_operand" "r,0")))
252 (clobber (reg:CC 24))]
253 ""
254 "adds\\t%0, %2, %1\;adc\\t%R0, %R2, %1, asr #31"
255 [(set_attr "conds" "clob")
256 (set_attr "length" "8")])
257
258 (define_insn "*adddi_zesidi_di"
259 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
260 (plus:DI (zero_extend:DI
261 (match_operand:SI 1 "s_register_operand" "r,r"))
262 (match_operand:DI 2 "s_register_operand" "r,0")))
263 (clobber (reg:CC 24))]
264 ""
265 "adds\\t%0, %2, %1\;adc\\t%R0, %R2, #0"
266 [(set_attr "conds" "clob")
267 (set_attr "length" "8")])
268
269 (define_expand "addsi3"
270 [(set (match_operand:SI 0 "s_register_operand" "")
271 (plus:SI (match_operand:SI 1 "s_register_operand" "")
272 (match_operand:SI 2 "reg_or_int_operand" "")))]
273 ""
274 "
275 if (GET_CODE (operands[2]) == CONST_INT)
276 {
277 arm_split_constant (PLUS, SImode, INTVAL (operands[2]), operands[0],
278 operands[1],
279 (reload_in_progress || reload_completed ? 0
280 : preserve_subexpressions_p ()));
281 DONE;
282 }
283 ")
284
285 (define_split
286 [(set (match_operand:SI 0 "s_register_operand" "")
287 (plus:SI (match_operand:SI 1 "s_register_operand" "")
288 (match_operand:SI 2 "const_int_operand" "")))]
289 "! (const_ok_for_arm (INTVAL (operands[2]))
290 || const_ok_for_arm (-INTVAL (operands[2])))"
291 [(clobber (const_int 0))]
292 "
293 arm_split_constant (PLUS, SImode, INTVAL (operands[2]), operands[0],
294 operands[1], 0);
295 DONE;
296 ")
297
298 (define_insn "*addsi3_insn"
299 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
300 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
301 (match_operand:SI 2 "reg_or_int_operand" "rI,L,?n")))]
302 ""
303 "@
304 add%?\\t%0, %1, %2
305 sub%?\\t%0, %1, #%n2
306 #"
307 [(set_attr "length" "4,4,16")])
308
309 (define_insn "*addsi3_compare0"
310 [(set (reg:CC_NOOV 24)
311 (compare:CC_NOOV
312 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r")
313 (match_operand:SI 2 "arm_add_operand" "rI,L"))
314 (const_int 0)))
315 (set (match_operand:SI 0 "s_register_operand" "=r,r")
316 (plus:SI (match_dup 1) (match_dup 2)))]
317 ""
318 "@
319 add%?s\\t%0, %1, %2
320 sub%?s\\t%0, %1, #%n2"
321 [(set_attr "conds" "set")])
322
323 (define_insn "*addsi3_compareneg"
324 [(set (reg:CC 24)
325 (compare:CC (match_operand:SI 1 "s_register_operand" "r,r")
326 (neg:SI (match_operand:SI 2 "arm_add_operand" "rI,L"))))
327 (set (match_operand:SI 0 "s_register_operand" "=r,r")
328 (plus:SI (match_dup 1) (match_dup 2)))]
329 ""
330 "@
331 add%?s\\t%0, %1, %2
332 sub%?s\\t%0, %1, #%n2"
333 [(set_attr "conds" "set")])
334
335 (define_insn "incscc"
336 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
337 (plus:SI (match_operator:SI 2 "comparison_operator"
338 [(reg 24) (const_int 0)])
339 (match_operand:SI 1 "s_register_operand" "0,?r")))]
340 ""
341 "@
342 add%d2\\t%0, %1, #1
343 mov%D2\\t%0, %1\;add%d2\\t%0, %1, #1"
344 [(set_attr "conds" "use")
345 (set_attr "length" "4,8")])
346
347 ; If a constant is too big to fit in a single instruction then the constant
348 ; will be pre-loaded into a register taking at least two insns, we might be
349 ; able to merge it with an add, but it depends on the exact value.
350
351 (define_split
352 [(set (match_operand:SI 0 "s_register_operand" "=r")
353 (plus:SI (match_operand:SI 1 "s_register_operand" "r")
354 (match_operand:SI 2 "immediate_operand" "n")))]
355 "!(const_ok_for_arm (INTVAL (operands[2]))
356 || const_ok_for_arm (-INTVAL (operands[2])))"
357 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
358 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
359 "
360 {
361 unsigned int val = (unsigned) INTVAL (operands[2]);
362 int i;
363 unsigned int temp;
364
365 /* this code is similar to the approach followed in movsi, but it must
366 generate exactly two insns */
367
368 for (i = 30; i >= 0; i -= 2)
369 {
370 if (val & (3 << i))
371 {
372 i -= 6;
373 if (i < 0) i = 0;
374 if (const_ok_for_arm (temp = (val & ~(255 << i))))
375 {
376 val &= 255 << i;
377 break;
378 }
379 /* we might be able to do this as (larger number - small number) */
380 temp = ((val >> i) & 255) + 1;
381 if (temp > 255 && i < 24)
382 {
383 i += 2;
384 temp = ((val >> i) & 255) + 1;
385 }
386 if (const_ok_for_arm ((temp << i) - val))
387 {
388 i = temp << i;
389 temp = (unsigned) - (int) (i - val);
390 val = i;
391 break;
392 }
393 FAIL;
394 }
395 }
396 /* if we got here, we have found a way of doing it in two instructions.
397 the two constants are in val and temp */
398 operands[2] = GEN_INT ((int)val);
399 operands[3] = GEN_INT ((int)temp);
400 }
401 ")
402
403 (define_insn "addsf3"
404 [(set (match_operand:SF 0 "s_register_operand" "=f,f")
405 (plus:SF (match_operand:SF 1 "s_register_operand" "f,f")
406 (match_operand:SF 2 "fpu_add_operand" "fG,H")))]
407 "TARGET_HARD_FLOAT"
408 "@
409 adf%?s\\t%0, %1, %2
410 suf%?s\\t%0, %1, #%N2"
411 [(set_attr "type" "farith")])
412
413 (define_insn "adddf3"
414 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
415 (plus:DF (match_operand:DF 1 "s_register_operand" "f,f")
416 (match_operand:DF 2 "fpu_add_operand" "fG,H")))]
417 "TARGET_HARD_FLOAT"
418 "@
419 adf%?d\\t%0, %1, %2
420 suf%?d\\t%0, %1, #%N2"
421 [(set_attr "type" "farith")])
422
423 (define_insn "*adddf_df_esfdf"
424 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
425 (plus:DF (float_extend:DF
426 (match_operand:SF 1 "s_register_operand" "f,f"))
427 (match_operand:DF 2 "fpu_add_operand" "fG,H")))]
428 "TARGET_HARD_FLOAT"
429 "@
430 adf%?d\\t%0, %1, %2
431 suf%?d\\t%0, %1, #%N2"
432 [(set_attr "type" "farith")])
433
434 (define_insn "*adddf_df_esfdf"
435 [(set (match_operand:DF 0 "s_register_operand" "=f")
436 (plus:DF (match_operand:DF 1 "s_register_operand" "f")
437 (float_extend:DF
438 (match_operand:SF 2 "s_register_operand" "f"))))]
439 "TARGET_HARD_FLOAT"
440 "adf%?d\\t%0, %1, %2"
441 [(set_attr "type" "farith")])
442
443 (define_insn "*adddf_esfdf_esfdf"
444 [(set (match_operand:DF 0 "s_register_operand" "=f")
445 (plus:DF (float_extend:DF
446 (match_operand:SF 1 "s_register_operand" "f"))
447 (float_extend:DF
448 (match_operand:SF 2 "s_register_operand" "f"))))]
449 "TARGET_HARD_FLOAT"
450 "adf%?d\\t%0, %1, %2"
451 [(set_attr "type" "farith")])
452
453 (define_insn "addxf3"
454 [(set (match_operand:XF 0 "s_register_operand" "=f,f")
455 (plus:XF (match_operand:XF 1 "s_register_operand" "f,f")
456 (match_operand:XF 2 "fpu_add_operand" "fG,H")))]
457 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
458 "@
459 adf%?e\\t%0, %1, %2
460 suf%?e\\t%0, %1, #%N2"
461 [(set_attr "type" "farith")])
462
463 (define_insn "subdi3"
464 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
465 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
466 (match_operand:DI 2 "s_register_operand" "r,0,0")))
467 (clobber (reg:CC 24))]
468 ""
469 "subs\\t%0, %1, %2\;sbc\\t%R0, %R1, %R2"
470 [(set_attr "conds" "clob")
471 (set_attr "length" "8")])
472
473 (define_insn "*subdi_di_zesidi"
474 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
475 (minus:DI (match_operand:DI 1 "s_register_operand" "?r,0")
476 (zero_extend:DI
477 (match_operand:SI 2 "s_register_operand" "r,r"))))
478 (clobber (reg:CC 24))]
479 ""
480 "subs\\t%0, %1, %2\;sbc\\t%R0, %R1, #0"
481 [(set_attr "conds" "clob")
482 (set_attr "length" "8")])
483
484 (define_insn "*subdi_di_sesidi"
485 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
486 (minus:DI (match_operand:DI 1 "s_register_operand" "r,0")
487 (sign_extend:DI
488 (match_operand:SI 2 "s_register_operand" "r,r"))))
489 (clobber (reg:CC 24))]
490 ""
491 "subs\\t%0, %1, %2\;sbc\\t%R0, %R1, %2, asr #31"
492 [(set_attr "conds" "clob")
493 (set_attr "length" "8")])
494
495 (define_insn "*subdi_zesidi_di"
496 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
497 (minus:DI (zero_extend:DI
498 (match_operand:SI 2 "s_register_operand" "r,r"))
499 (match_operand:DI 1 "s_register_operand" "?r,0")))
500 (clobber (reg:CC 24))]
501 ""
502 "rsbs\\t%0, %1, %2\;rsc\\t%R0, %R1, #0"
503 [(set_attr "conds" "clob")
504 (set_attr "length" "8")])
505
506 (define_insn "*subdi_sesidi_di"
507 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
508 (minus:DI (sign_extend:DI
509 (match_operand:SI 2 "s_register_operand" "r,r"))
510 (match_operand:DI 1 "s_register_operand" "?r,0")))
511 (clobber (reg:CC 24))]
512 ""
513 "rsbs\\t%0, %1, %2\;rsc\\t%R0, %R1, %2, asr #31"
514 [(set_attr "conds" "clob")
515 (set_attr "length" "8")])
516
517 (define_insn "*subdi_zesidi_zesidi"
518 [(set (match_operand:DI 0 "s_register_operand" "=r")
519 (minus:DI (zero_extend:DI
520 (match_operand:SI 1 "s_register_operand" "r"))
521 (zero_extend:DI
522 (match_operand:SI 2 "s_register_operand" "r"))))
523 (clobber (reg:CC 24))]
524 ""
525 "subs\\t%0, %1, %2\;rsc\\t%R0, %1, %1"
526 [(set_attr "conds" "clob")
527 (set_attr "length" "8")])
528
529 (define_expand "subsi3"
530 [(set (match_operand:SI 0 "s_register_operand" "")
531 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
532 (match_operand:SI 2 "s_register_operand" "")))]
533 ""
534 "
535 if (GET_CODE (operands[1]) == CONST_INT)
536 {
537 arm_split_constant (MINUS, SImode, INTVAL (operands[1]), operands[0],
538 operands[2],
539 (reload_in_progress || reload_completed ? 0
540 : preserve_subexpressions_p ()));
541 DONE;
542 }
543 ")
544
545 (define_insn "*subsi3_insn"
546 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
547 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "rI,?n")
548 (match_operand:SI 2 "s_register_operand" "r,r")))]
549 ""
550 "@
551 rsb%?\\t%0, %2, %1
552 #"
553 [(set_attr "length" "4,16")])
554
555 (define_split
556 [(set (match_operand:SI 0 "s_register_operand" "")
557 (minus:SI (match_operand:SI 1 "const_int_operand" "")
558 (match_operand:SI 2 "s_register_operand" "")))]
559 "! const_ok_for_arm (INTVAL (operands[1]))"
560 [(clobber (const_int 0))]
561 "
562 arm_split_constant (MINUS, SImode, INTVAL (operands[1]), operands[0],
563 operands[2], 0);
564 DONE;
565 ")
566
567 (define_insn "*subsi3_compare0"
568 [(set (reg:CC_NOOV 24)
569 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,I")
570 (match_operand:SI 2 "arm_rhs_operand" "rI,r"))
571 (const_int 0)))
572 (set (match_operand:SI 0 "s_register_operand" "=r,r")
573 (minus:SI (match_dup 1) (match_dup 2)))]
574 ""
575 "@
576 sub%?s\\t%0, %1, %2
577 rsb%?s\\t%0, %2, %1"
578 [(set_attr "conds" "set")])
579
580 (define_insn "decscc"
581 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
582 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
583 (match_operator:SI 2 "comparison_operator"
584 [(reg 24) (const_int 0)])))]
585 ""
586 "@
587 sub%d2\\t%0, %1, #1
588 mov%D2\\t%0, %1\;sub%d2\\t%0, %1, #1"
589 [(set_attr "conds" "use")
590 (set_attr "length" "*,8")])
591
592 (define_insn "subsf3"
593 [(set (match_operand:SF 0 "s_register_operand" "=f,f")
594 (minus:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
595 (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
596 "TARGET_HARD_FLOAT"
597 "@
598 suf%?s\\t%0, %1, %2
599 rsf%?s\\t%0, %2, %1"
600 [(set_attr "type" "farith")])
601
602 (define_insn "subdf3"
603 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
604 (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
605 (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
606 "TARGET_HARD_FLOAT"
607 "@
608 suf%?d\\t%0, %1, %2
609 rsf%?d\\t%0, %2, %1"
610 [(set_attr "type" "farith")])
611
612 (define_insn "*subdf_esfdf_df"
613 [(set (match_operand:DF 0 "s_register_operand" "=f")
614 (minus:DF (float_extend:DF
615 (match_operand:SF 1 "s_register_operand" "f"))
616 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
617 "TARGET_HARD_FLOAT"
618 "suf%?d\\t%0, %1, %2"
619 [(set_attr "type" "farith")])
620
621 (define_insn "*subdf_df_esfdf"
622 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
623 (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
624 (float_extend:DF
625 (match_operand:SF 2 "s_register_operand" "f,f"))))]
626 "TARGET_HARD_FLOAT"
627 "@
628 suf%?d\\t%0, %1, %2
629 rsf%?d\\t%0, %2, %1"
630 [(set_attr "type" "farith")])
631
632 (define_insn "*subdf_esfdf_esfdf"
633 [(set (match_operand:DF 0 "s_register_operand" "=f")
634 (minus:DF (float_extend:DF
635 (match_operand:SF 1 "s_register_operand" "f"))
636 (float_extend:DF
637 (match_operand:SF 2 "s_register_operand" "f"))))]
638 "TARGET_HARD_FLOAT"
639 "suf%?d\\t%0, %1, %2"
640 [(set_attr "type" "farith")])
641
642 (define_insn "subxf3"
643 [(set (match_operand:XF 0 "s_register_operand" "=f,f")
644 (minus:XF (match_operand:XF 1 "fpu_rhs_operand" "f,G")
645 (match_operand:XF 2 "fpu_rhs_operand" "fG,f")))]
646 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
647 "@
648 suf%?e\\t%0, %1, %2
649 rsf%?e\\t%0, %2, %1"
650 [(set_attr "type" "farith")])
651 \f
652 ;; Multiplication insns
653
654 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
655 (define_insn "mulsi3"
656 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
657 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
658 (match_operand:SI 1 "s_register_operand" "%?r,0")))]
659 ""
660 "mul%?\\t%0, %2, %1"
661 [(set_attr "type" "mult")])
662
663 (define_insn "*mulsi3_compare0"
664 [(set (reg:CC_NOOV 24)
665 (compare:CC_NOOV (mult:SI
666 (match_operand:SI 2 "s_register_operand" "r,r")
667 (match_operand:SI 1 "s_register_operand" "%?r,0"))
668 (const_int 0)))
669 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
670 (mult:SI (match_dup 2) (match_dup 1)))]
671 ""
672 "mul%?s\\t%0, %2, %1"
673 [(set_attr "conds" "set")
674 (set_attr "type" "mult")])
675
676 (define_insn "*mulsi_compare0_scratch"
677 [(set (reg:CC_NOOV 24)
678 (compare:CC_NOOV (mult:SI
679 (match_operand:SI 2 "s_register_operand" "r,r")
680 (match_operand:SI 1 "s_register_operand" "%?r,0"))
681 (const_int 0)))
682 (clobber (match_scratch:SI 0 "=&r,&r"))]
683 ""
684 "mul%?s\\t%0, %2, %1"
685 [(set_attr "conds" "set")
686 (set_attr "type" "mult")])
687
688 ;; Unnamed templates to match MLA instruction.
689
690 (define_insn "*mulsi3addsi"
691 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
692 (plus:SI
693 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
694 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
695 (match_operand:SI 3 "s_register_operand" "?r,r,0,0")))]
696 ""
697 "mla%?\\t%0, %2, %1, %3"
698 [(set_attr "type" "mult")])
699
700 (define_insn "*mulsi3addsi_compare0"
701 [(set (reg:CC_NOOV 24)
702 (compare:CC_NOOV (plus:SI
703 (mult:SI
704 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
705 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
706 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
707 (const_int 0)))
708 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
709 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
710 (match_dup 3)))]
711 ""
712 "mla%?s\\t%0, %2, %1, %3"
713 [(set_attr "conds" "set")
714 (set_attr "type" "mult")])
715
716 (define_insn "*mulsi3addsi_compare0_scratch"
717 [(set (reg:CC_NOOV 24)
718 (compare:CC_NOOV (plus:SI
719 (mult:SI
720 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
721 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
722 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
723 (const_int 0)))
724 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
725 ""
726 "mla%?s\\t%0, %2, %1, %3"
727 [(set_attr "conds" "set")
728 (set_attr "type" "mult")])
729
730 (define_insn "mulsidi3"
731 [(set (match_operand:DI 0 "s_register_operand" "=&r")
732 (mult:DI (sign_extend:DI
733 (match_operand:SI 1 "s_register_operand" "%r"))
734 (sign_extend:DI
735 (match_operand:SI 2 "s_register_operand" "r"))))]
736 "arm_fast_multiply"
737 "smull%?\\t%0, %R0, %1, %2"
738 [(set_attr "type" "mult")])
739
740 (define_insn "umulsidi3"
741 [(set (match_operand:DI 0 "s_register_operand" "=&r")
742 (mult:DI (zero_extend:DI
743 (match_operand:SI 1 "s_register_operand" "%r"))
744 (zero_extend:DI
745 (match_operand:SI 2 "s_register_operand" "r"))))]
746 "arm_fast_multiply"
747 "umull%?\\t%0, %R0, %1, %2"
748 [(set_attr "type" "mult")])
749
750 (define_insn "mulsf3"
751 [(set (match_operand:SF 0 "s_register_operand" "=f")
752 (mult:SF (match_operand:SF 1 "s_register_operand" "f")
753 (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
754 "TARGET_HARD_FLOAT"
755 "fml%?s\\t%0, %1, %2"
756 [(set_attr "type" "ffmul")])
757
758 (define_insn "muldf3"
759 [(set (match_operand:DF 0 "s_register_operand" "=f")
760 (mult:DF (match_operand:DF 1 "s_register_operand" "f")
761 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
762 "TARGET_HARD_FLOAT"
763 "muf%?d\\t%0, %1, %2"
764 [(set_attr "type" "fmul")])
765
766 (define_insn "*muldf_esfdf_df"
767 [(set (match_operand:DF 0 "s_register_operand" "=f")
768 (mult:DF (float_extend:DF
769 (match_operand:SF 1 "s_register_operand" "f"))
770 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
771 "TARGET_HARD_FLOAT"
772 "muf%?d\\t%0, %1, %2"
773 [(set_attr "type" "fmul")])
774
775 (define_insn "*muldf_df_esfdf"
776 [(set (match_operand:DF 0 "s_register_operand" "=f")
777 (mult:DF (match_operand:DF 1 "s_register_operand" "f")
778 (float_extend:DF
779 (match_operand:SF 2 "s_register_operand" "f"))))]
780 "TARGET_HARD_FLOAT"
781 "muf%?d\\t%0, %1, %2"
782 [(set_attr "type" "fmul")])
783
784 (define_insn "*muldf_esfdf_esfdf"
785 [(set (match_operand:DF 0 "s_register_operand" "=f")
786 (mult:DF (float_extend:DF
787 (match_operand:SF 1 "s_register_operand" "f"))
788 (float_extend:DF
789 (match_operand:SF 2 "s_register_operand" "f"))))]
790 "TARGET_HARD_FLOAT"
791 "muf%?d\\t%0, %1, %2"
792 [(set_attr "type" "fmul")])
793
794 (define_insn "mulxf3"
795 [(set (match_operand:XF 0 "s_register_operand" "=f")
796 (mult:XF (match_operand:XF 1 "s_register_operand" "f")
797 (match_operand:XF 2 "fpu_rhs_operand" "fG")))]
798 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
799 "muf%?e\\t%0, %1, %2"
800 [(set_attr "type" "fmul")])
801 \f
802 ;; Division insns
803
804 (define_insn "divsf3"
805 [(set (match_operand:SF 0 "s_register_operand" "=f,f")
806 (div:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
807 (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
808 "TARGET_HARD_FLOAT"
809 "@
810 fdv%?s\\t%0, %1, %2
811 frd%?s\\t%0, %2, %1"
812 [(set_attr "type" "fdivs")])
813
814 (define_insn "divdf3"
815 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
816 (div:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
817 (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
818 "TARGET_HARD_FLOAT"
819 "@
820 dvf%?d\\t%0, %1, %2
821 rdf%?d\\t%0, %2, %1"
822 [(set_attr "type" "fdivd")])
823
824 (define_insn "*divdf_esfdf_df"
825 [(set (match_operand:DF 0 "s_register_operand" "=f")
826 (div:DF (float_extend:DF
827 (match_operand:SF 1 "s_register_operand" "f"))
828 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
829 "TARGET_HARD_FLOAT"
830 "dvf%?d\\t%0, %1, %2"
831 [(set_attr "type" "fdivd")])
832
833 (define_insn "*divdf_df_esfdf"
834 [(set (match_operand:DF 0 "s_register_operand" "=f")
835 (div:DF (match_operand:DF 1 "fpu_rhs_operand" "fG")
836 (float_extend:DF
837 (match_operand:SF 2 "s_register_operand" "f"))))]
838 "TARGET_HARD_FLOAT"
839 "rdf%?d\\t%0, %2, %1"
840 [(set_attr "type" "fdivd")])
841
842 (define_insn "*divdf_esfdf_esfdf"
843 [(set (match_operand:DF 0 "s_register_operand" "=f")
844 (div:DF (float_extend:DF
845 (match_operand:SF 1 "s_register_operand" "f"))
846 (float_extend:DF
847 (match_operand:SF 2 "s_register_operand" "f"))))]
848 "TARGET_HARD_FLOAT"
849 "dvf%?d\\t%0, %1, %2"
850 [(set_attr "type" "fdivd")])
851
852 (define_insn "divxf3"
853 [(set (match_operand:XF 0 "s_register_operand" "=f,f")
854 (div:XF (match_operand:XF 1 "fpu_rhs_operand" "f,G")
855 (match_operand:XF 2 "fpu_rhs_operand" "fG,f")))]
856 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
857 "@
858 dvf%?e\\t%0, %1, %2
859 rdf%?e\\t%0, %2, %1"
860 [(set_attr "type" "fdivx")])
861 \f
862 ;; Modulo insns
863
864 (define_insn "modsf3"
865 [(set (match_operand:SF 0 "s_register_operand" "=f")
866 (mod:SF (match_operand:SF 1 "s_register_operand" "f")
867 (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
868 "TARGET_HARD_FLOAT"
869 "rmf%?s\\t%0, %1, %2"
870 [(set_attr "type" "fdivs")])
871
872 (define_insn "moddf3"
873 [(set (match_operand:DF 0 "s_register_operand" "=f")
874 (mod:DF (match_operand:DF 1 "s_register_operand" "f")
875 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
876 "TARGET_HARD_FLOAT"
877 "rmf%?d\\t%0, %1, %2"
878 [(set_attr "type" "fdivd")])
879
880 (define_insn "*moddf_esfdf_df"
881 [(set (match_operand:DF 0 "s_register_operand" "=f")
882 (mod:DF (float_extend:DF
883 (match_operand:SF 1 "s_register_operand" "f"))
884 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
885 "TARGET_HARD_FLOAT"
886 "rmf%?d\\t%0, %1, %2"
887 [(set_attr "type" "fdivd")])
888
889 (define_insn "*moddf_df_esfdf"
890 [(set (match_operand:DF 0 "s_register_operand" "=f")
891 (mod:DF (match_operand:DF 1 "s_register_operand" "f")
892 (float_extend:DF
893 (match_operand:SF 2 "s_register_operand" "f"))))]
894 "TARGET_HARD_FLOAT"
895 "rmf%?d\\t%0, %1, %2"
896 [(set_attr "type" "fdivd")])
897
898 (define_insn "*moddf_esfdf_esfdf"
899 [(set (match_operand:DF 0 "s_register_operand" "=f")
900 (mod:DF (float_extend:DF
901 (match_operand:SF 1 "s_register_operand" "f"))
902 (float_extend:DF
903 (match_operand:SF 2 "s_register_operand" "f"))))]
904 "TARGET_HARD_FLOAT"
905 "rmf%?d\\t%0, %1, %2"
906 [(set_attr "type" "fdivd")])
907
908 (define_insn "modxf3"
909 [(set (match_operand:XF 0 "s_register_operand" "=f")
910 (mod:XF (match_operand:XF 1 "s_register_operand" "f")
911 (match_operand:XF 2 "fpu_rhs_operand" "fG")))]
912 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
913 "rmf%?e\\t%0, %1, %2"
914 [(set_attr "type" "fdivx")])
915 \f
916 ;; Boolean and,ior,xor insns
917
918 (define_insn "anddi3"
919 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
920 (and:DI (match_operand:DI 1 "s_register_operand" "%0,0")
921 (match_operand:DI 2 "s_register_operand" "r,0")))]
922 ""
923 "and%?\\t%0, %1, %2\;and%?\\t%R0, %R1, %R2"
924 [(set_attr "length" "8")])
925
926 (define_insn "*anddi_zesidi_di"
927 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
928 (and:DI (zero_extend:DI
929 (match_operand:SI 2 "s_register_operand" "r,r"))
930 (match_operand:DI 1 "s_register_operand" "?r,0")))]
931 ""
932 "and%?\\t%0, %1, %2\;mov%?\\t%R0, #0"
933 [(set_attr "length" "8")])
934
935 (define_insn "*anddi_sesdi_di"
936 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
937 (and:DI (sign_extend:DI
938 (match_operand:SI 2 "s_register_operand" "r,r"))
939 (match_operand:DI 1 "s_register_operand" "?r,0")))]
940 ""
941 "and%?\\t%0, %1, %2\;and%?\\t%R0, %R1, %2, asr #31"
942 [(set_attr "length" "8")])
943
944 (define_expand "andsi3"
945 [(set (match_operand:SI 0 "s_register_operand" "")
946 (and:SI (match_operand:SI 1 "s_register_operand" "")
947 (match_operand:SI 2 "reg_or_int_operand" "")))]
948 ""
949 "
950 if (GET_CODE (operands[2]) == CONST_INT)
951 {
952 arm_split_constant (AND, SImode, INTVAL (operands[2]), operands[0],
953 operands[1],
954 (reload_in_progress || reload_completed
955 ? 0 : preserve_subexpressions_p ()));
956 DONE;
957 }
958 ")
959
960 (define_insn "*andsi3_insn"
961 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
962 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
963 (match_operand:SI 2 "reg_or_int_operand" "rI,K,?n")))]
964 ""
965 "@
966 and%?\\t%0, %1, %2
967 bic%?\\t%0, %1, #%B2
968 #"
969 [(set_attr "length" "4,4,16")])
970
971 (define_split
972 [(set (match_operand:SI 0 "s_register_operand" "")
973 (and:SI (match_operand:SI 1 "s_register_operand" "")
974 (match_operand:SI 2 "const_int_operand" "")))]
975 "! (const_ok_for_arm (INTVAL (operands[2]))
976 || const_ok_for_arm (~ INTVAL (operands[2])))"
977 [(clobber (const_int 0))]
978 "
979 arm_split_constant (AND, SImode, INTVAL (operands[2]), operands[0],
980 operands[1], 0);
981 DONE;
982 ")
983
984 (define_insn "*andsi3_compare0"
985 [(set (reg:CC_NOOV 24)
986 (compare:CC_NOOV
987 (and:SI (match_operand:SI 1 "s_register_operand" "r,r")
988 (match_operand:SI 2 "arm_not_operand" "rI,K"))
989 (const_int 0)))
990 (set (match_operand:SI 0 "s_register_operand" "=r,r")
991 (and:SI (match_dup 1) (match_dup 2)))]
992 ""
993 "@
994 and%?s\\t%0, %1, %2
995 bic%?s\\t%0, %1, #%B2"
996 [(set_attr "conds" "set")])
997
998 (define_insn "*andsi3_compare0_scratch"
999 [(set (reg:CC_NOOV 24)
1000 (compare:CC_NOOV
1001 (and:SI (match_operand:SI 0 "s_register_operand" "r,r")
1002 (match_operand:SI 1 "arm_not_operand" "rI,K"))
1003 (const_int 0)))
1004 (clobber (match_scratch:SI 3 "=X,r"))]
1005 ""
1006 "@
1007 tst%?\\t%0, %1
1008 bic%?s\\t%3, %0, #%B1"
1009 [(set_attr "conds" "set")])
1010
1011 (define_insn "*zeroextractsi_compare0_scratch"
1012 [(set (reg:CC_NOOV 24)
1013 (compare:CC_NOOV (zero_extract:SI
1014 (match_operand:SI 0 "s_register_operand" "r")
1015 (match_operand:SI 1 "immediate_operand" "n")
1016 (match_operand:SI 2 "immediate_operand" "n"))
1017 (const_int 0)))]
1018 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
1019 && INTVAL (operands[1]) > 0
1020 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
1021 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32"
1022 "*
1023 {
1024 unsigned int mask = 0;
1025 int cnt = INTVAL (operands[1]);
1026
1027 while (cnt--)
1028 mask = (mask << 1) | 1;
1029 operands[1] = GEN_INT (mask << INTVAL (operands[2]));
1030 output_asm_insn (\"tst%?\\t%0, %1\", operands);
1031 return \"\";
1032 }
1033 "
1034 [(set_attr "conds" "set")])
1035
1036 (define_insn "*zeroextractqi_compare0_scratch"
1037 [(set (reg:CC_NOOV 24)
1038 (compare:CC_NOOV (zero_extract:SI
1039 (match_operand:QI 0 "memory_operand" "m")
1040 (match_operand 1 "immediate_operand" "n")
1041 (match_operand 2 "immediate_operand" "n"))
1042 (const_int 0)))
1043 (clobber (match_scratch:QI 3 "=r"))]
1044 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 8
1045 && INTVAL (operands[1]) > 0 && INTVAL (operands[1]) <= 8"
1046 "*
1047 {
1048 unsigned int mask = 0;
1049 int cnt = INTVAL (operands[1]);
1050
1051 while (cnt--)
1052 mask = (mask << 1) | 1;
1053 operands[1] = GEN_INT (mask << INTVAL (operands[2]));
1054 output_asm_insn (\"ldr%?b\\t%3, %0\", operands);
1055 output_asm_insn (\"tst%?\\t%3, %1\", operands);
1056 return \"\";
1057 }
1058 "
1059 [(set_attr "conds" "set")
1060 (set_attr "length" "8")])
1061
1062 ;; constants for op 2 will never be given to these patterns.
1063 (define_insn "*anddi_notdi_di"
1064 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1065 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r,0"))
1066 (match_operand:DI 1 "s_register_operand" "0,r")))]
1067 ""
1068 "bic%?\\t%0, %1, %2\;bic%?\\t%R0, %R1, %R2"
1069 [(set_attr "length" "8")])
1070
1071 (define_insn "*anddi_notzesidi_di"
1072 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1073 (and:DI (not:DI (zero_extend:DI
1074 (match_operand:SI 2 "s_register_operand" "r,r")))
1075 (match_operand:DI 1 "s_register_operand" "0,?r")))]
1076 ""
1077 "@
1078 bic%?\\t%0, %1, %2
1079 bic%?\\t%0, %1, %2\;mov%?\\t%R0, %R1"
1080 [(set_attr "length" "4,8")])
1081
1082 (define_insn "*anddi_notsesidi_di"
1083 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1084 (and:DI (not:DI (sign_extend:DI
1085 (match_operand:SI 2 "s_register_operand" "r,r")))
1086 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1087 ""
1088 "bic%?\\t%0, %1, %2\;bic%?\\t%R0, %R1, %2, asr #31"
1089 [(set_attr "length" "8")])
1090
1091 (define_insn "*andsi_notsi_si"
1092 [(set (match_operand:SI 0 "s_register_operand" "=r")
1093 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
1094 (match_operand:SI 1 "s_register_operand" "r")))]
1095 ""
1096 "bic%?\\t%0, %1, %2")
1097
1098 (define_insn "*andsi_notsi_si_compare0"
1099 [(set (reg:CC_NOOV 24)
1100 (compare:CC_NOOV
1101 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
1102 (match_operand:SI 1 "s_register_operand" "r"))
1103 (const_int 0)))
1104 (set (match_operand:SI 0 "s_register_operand" "=r")
1105 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
1106 ""
1107 "bic%?s\\t%0, %1, %2"
1108 [(set_attr "conds" "set")])
1109
1110 (define_insn "*andsi_notsi_si_compare0_scratch"
1111 [(set (reg:CC_NOOV 24)
1112 (compare:CC_NOOV
1113 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
1114 (match_operand:SI 1 "s_register_operand" "r"))
1115 (const_int 0)))
1116 (clobber (match_scratch:SI 0 "=r"))]
1117 ""
1118 "bic%?s\\t%0, %1, %2"
1119 [(set_attr "conds" "set")])
1120
1121 (define_insn "iordi3"
1122 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1123 (ior:DI (match_operand:DI 1 "s_register_operand" "%0")
1124 (match_operand:DI 2 "s_register_operand" "r")))]
1125 ""
1126 "orr%?\\t%0, %1, %2\;orr%?\\t%R0, %R1, %R2"
1127 [(set_attr "length" "8")])
1128
1129 (define_insn "*iordi_zesidi_di"
1130 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1131 (ior:DI (zero_extend:DI
1132 (match_operand:SI 2 "s_register_operand" "r,r"))
1133 (match_operand:DI 1 "s_register_operand" "0,?r")))]
1134 ""
1135 "@
1136 orr%?\\t%0, %1, %2
1137 orr%?\\t%0, %1, %2\;mov%?\\t%R0, %R1"
1138 [(set_attr "length" "4,8")])
1139
1140 (define_insn "*iordi_sesidi_di"
1141 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1142 (ior:DI (sign_extend:DI
1143 (match_operand:SI 2 "s_register_operand" "r,r"))
1144 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1145 ""
1146 "orr%?\\t%0, %1, %2\;orr%?\\t%R0, %R1, %2, asr #31"
1147 [(set_attr "length" "8")])
1148
1149 (define_expand "iorsi3"
1150 [(set (match_operand:SI 0 "s_register_operand" "")
1151 (ior:SI (match_operand:SI 1 "s_register_operand" "")
1152 (match_operand:SI 2 "reg_or_int_operand" "")))]
1153 ""
1154 "
1155 if (GET_CODE (operands[2]) == CONST_INT)
1156 {
1157 arm_split_constant (IOR, SImode, INTVAL (operands[2]), operands[0],
1158 operands[1],
1159 (reload_in_progress || reload_completed
1160 ? 0 : preserve_subexpressions_p ()));
1161 DONE;
1162 }
1163 ")
1164
1165 (define_insn "*iorsi3_insn"
1166 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1167 (ior:SI (match_operand:SI 1 "s_register_operand" "r,r")
1168 (match_operand:SI 2 "reg_or_int_operand" "rI,?n")))]
1169 ""
1170 "@
1171 orr%?\\t%0, %1, %2
1172 #"
1173 [(set_attr "length" "4,16")])
1174
1175 (define_split
1176 [(set (match_operand:SI 0 "s_register_operand" "")
1177 (ior:SI (match_operand:SI 1 "s_register_operand" "")
1178 (match_operand:SI 2 "const_int_operand" "")))]
1179 "! const_ok_for_arm (INTVAL (operands[2]))"
1180 [(clobber (const_int 0))]
1181 "
1182 arm_split_constant (IOR, SImode, INTVAL (operands[2]), operands[0],
1183 operands[1], 0);
1184 DONE;
1185 ")
1186
1187 (define_insn "*iorsi3_compare0"
1188 [(set (reg:CC_NOOV 24)
1189 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
1190 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1191 (const_int 0)))
1192 (set (match_operand:SI 0 "s_register_operand" "=r")
1193 (ior:SI (match_dup 1) (match_dup 2)))]
1194 ""
1195 "orr%?s\\t%0, %1, %2"
1196 [(set_attr "conds" "set")])
1197
1198 (define_insn "*iorsi3_compare0_scratch"
1199 [(set (reg:CC_NOOV 24)
1200 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
1201 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1202 (const_int 0)))
1203 (clobber (match_scratch:SI 0 "=r"))]
1204 ""
1205 "orr%?s\\t%0, %1, %2"
1206 [(set_attr "conds" "set")])
1207
1208 (define_insn "xordi3"
1209 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1210 (xor:DI (match_operand:DI 1 "s_register_operand" "%0,0")
1211 (match_operand:DI 2 "s_register_operand" "r,0")))]
1212 ""
1213 "eor%?\\t%0, %1, %2\;eor%?\\t%R0, %R1, %R2"
1214 [(set_attr "length" "8")])
1215
1216 (define_insn "*xordi_zesidi_di"
1217 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1218 (xor:DI (zero_extend:DI
1219 (match_operand:SI 2 "s_register_operand" "r,r"))
1220 (match_operand:DI 1 "s_register_operand" "0,?r")))]
1221 ""
1222 "@
1223 eor%?\\t%0, %1, %2
1224 eor%?\\t%0, %1, %2\;mov%?\\t%R0, %R1"
1225 [(set_attr "length" "4,8")])
1226
1227 (define_insn "*xordi_sesidi_di"
1228 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1229 (xor:DI (sign_extend:DI
1230 (match_operand:SI 2 "s_register_operand" "r,r"))
1231 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1232 ""
1233 "eor%?\\t%0, %1, %2\;eor%?\\t%R0, %R1, %2, asr #31"
1234 [(set_attr "length" "8")])
1235
1236 (define_insn "xorsi3"
1237 [(set (match_operand:SI 0 "s_register_operand" "=r")
1238 (xor:SI (match_operand:SI 1 "s_register_operand" "r")
1239 (match_operand:SI 2 "arm_rhs_operand" "rI")))]
1240 ""
1241 "eor%?\\t%0, %1, %2")
1242
1243 (define_insn "*xorsi3_compare0"
1244 [(set (reg:CC_NOOV 24)
1245 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r")
1246 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1247 (const_int 0)))
1248 (set (match_operand:SI 0 "s_register_operand" "=r")
1249 (xor:SI (match_dup 1) (match_dup 2)))]
1250 ""
1251 "eor%?s\\t%0, %1, %2"
1252 [(set_attr "conds" "set")])
1253
1254 (define_insn "*xorsi3_compare0_scratch"
1255 [(set (reg:CC_NOOV 24)
1256 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r")
1257 (match_operand:SI 1 "arm_rhs_operand" "rI"))
1258 (const_int 0)))]
1259 ""
1260 "teq%?\\t%0, %1"
1261 [(set_attr "conds" "set")])
1262
1263 ;; by splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
1264 ;; (NOT D) we can sometimes merge the final NOT into one of the following
1265 ;; insns
1266
1267 (define_split
1268 [(set (match_operand:SI 0 "s_register_operand" "=r")
1269 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" "r"))
1270 (not:SI (match_operand:SI 2 "arm_rhs_operand" "rI")))
1271 (match_operand:SI 3 "arm_rhs_operand" "rI")))
1272 (clobber (match_operand:SI 4 "s_register_operand" "=r"))]
1273 ""
1274 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
1275 (not:SI (match_dup 3))))
1276 (set (match_dup 0) (not:SI (match_dup 4)))]
1277 ""
1278 )
1279
1280 (define_insn "*andsi_iorsi3_notsi"
1281 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
1282 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "r,r,0")
1283 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
1284 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
1285 ""
1286 "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
1287 [(set_attr "length" "8")])
1288
1289 \f
1290
1291 ;; Minimum and maximum insns
1292
1293 (define_insn "smaxsi3"
1294 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1295 (smax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
1296 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
1297 (clobber (reg:CC 24))]
1298 ""
1299 "@
1300 cmp\\t%1, %2\;movlt\\t%0, %2
1301 cmp\\t%1, %2\;movge\\t%0, %1
1302 cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
1303 [(set_attr "conds" "clob")
1304 (set_attr "length" "8,8,12")])
1305
1306 (define_insn "sminsi3"
1307 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1308 (smin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
1309 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
1310 (clobber (reg:CC 24))]
1311 ""
1312 "@
1313 cmp\\t%1, %2\;movge\\t%0, %2
1314 cmp\\t%1, %2\;movlt\\t%0, %1
1315 cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
1316 [(set_attr "conds" "clob")
1317 (set_attr "length" "8,8,12")])
1318
1319 (define_insn "umaxsi3"
1320 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1321 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
1322 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
1323 (clobber (reg:CC 24))]
1324 ""
1325 "@
1326 cmp\\t%1, %2\;movcc\\t%0, %2
1327 cmp\\t%1, %2\;movcs\\t%0, %1
1328 cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
1329 [(set_attr "conds" "clob")
1330 (set_attr "length" "8,8,12")])
1331
1332 (define_insn "uminsi3"
1333 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1334 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
1335 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
1336 (clobber (reg:CC 24))]
1337 ""
1338 "@
1339 cmp\\t%1, %2\;movcs\\t%0, %2
1340 cmp\\t%1, %2\;movcc\\t%0, %1
1341 cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
1342 [(set_attr "conds" "clob")
1343 (set_attr "length" "8,8,12")])
1344
1345 (define_insn "*store_minmansi"
1346 [(set (match_operand:SI 0 "memory_operand" "=m")
1347 (match_operator:SI 3 "minmax_operator"
1348 [(match_operand:SI 1 "s_register_operand" "r")
1349 (match_operand:SI 2 "s_register_operand" "r")]))
1350 (clobber (reg:CC 24))]
1351 ""
1352 "*
1353 operands[3] = gen_rtx (minmax_code (operands[3]), SImode, operands[1],
1354 operands[2]);
1355 output_asm_insn (\"cmp\\t%1, %2\", operands);
1356 output_asm_insn (\"str%d3\\t%1, %0\", operands);
1357 output_asm_insn (\"str%D3\\t%2, %0\", operands);
1358 return \"\";
1359 "
1360 [(set_attr "conds" "clob")
1361 (set_attr "length" "12")
1362 (set_attr "type" "store1")])
1363
1364 (define_insn "*minmax_arithsi"
1365 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1366 (match_operator:SI 4 "shiftable_operator"
1367 [(match_operator:SI 5 "minmax_operator"
1368 [(match_operand:SI 2 "s_register_operand" "r,r")
1369 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
1370 (match_operand:SI 1 "s_register_operand" "0,?r")]))
1371 (clobber (reg:CC 24))]
1372 ""
1373 "*
1374 {
1375 enum rtx_code code = GET_CODE (operands[4]);
1376
1377 operands[5] = gen_rtx (minmax_code (operands[5]), SImode, operands[2],
1378 operands[3]);
1379 output_asm_insn (\"cmp\\t%2, %3\", operands);
1380 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
1381 if (which_alternative != 0 || operands[3] != const0_rtx
1382 || (code != PLUS && code != MINUS && code != IOR && code != XOR))
1383 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
1384 return \"\";
1385 }
1386 "
1387 [(set_attr "conds" "clob")
1388 (set_attr "length" "12")])
1389
1390 \f
1391 ;; Shift and rotation insns
1392
1393 (define_expand "ashlsi3"
1394 [(set (match_operand:SI 0 "s_register_operand" "")
1395 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
1396 (match_operand:SI 2 "arm_rhs_operand" "")))]
1397 ""
1398 "
1399 if (GET_CODE (operands[2]) == CONST_INT
1400 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1401 {
1402 emit_insn (gen_movsi (operands[0], const0_rtx));
1403 DONE;
1404 }
1405 ")
1406
1407 (define_expand "ashrsi3"
1408 [(set (match_operand:SI 0 "s_register_operand" "")
1409 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
1410 (match_operand:SI 2 "arm_rhs_operand" "")))]
1411 ""
1412 "
1413 if (GET_CODE (operands[2]) == CONST_INT
1414 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1415 operands[2] = GEN_INT (31);
1416 ")
1417
1418 (define_expand "lshrsi3"
1419 [(set (match_operand:SI 0 "s_register_operand" "")
1420 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
1421 (match_operand:SI 2 "arm_rhs_operand" "")))]
1422 ""
1423 "
1424 if (GET_CODE (operands[2]) == CONST_INT
1425 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1426 {
1427 emit_insn (gen_movsi (operands[0], const0_rtx));
1428 DONE;
1429 }
1430 ")
1431
1432 (define_expand "rotlsi3"
1433 [(set (match_operand:SI 0 "s_register_operand" "")
1434 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
1435 (match_operand:SI 2 "reg_or_int_operand" "")))]
1436 ""
1437 "
1438 if (GET_CODE (operands[2]) == CONST_INT)
1439 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
1440 else
1441 {
1442 rtx reg = gen_reg_rtx (SImode);
1443 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
1444 operands[2] = reg;
1445 }
1446 ")
1447
1448 (define_expand "rotrsi3"
1449 [(set (match_operand:SI 0 "s_register_operand" "")
1450 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
1451 (match_operand:SI 2 "arm_rhs_operand" "")))]
1452 ""
1453 "
1454 if (GET_CODE (operands[2]) == CONST_INT
1455 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1456 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
1457 ")
1458
1459 (define_insn "*shiftsi3"
1460 [(set (match_operand:SI 0 "s_register_operand" "=r")
1461 (match_operator:SI 3 "shift_operator"
1462 [(match_operand:SI 1 "s_register_operand" "r")
1463 (match_operand:SI 2 "reg_or_int_operand" "rM")]))]
1464 ""
1465 "mov%?\\t%0, %1%S3")
1466
1467 (define_insn "*shiftsi3_compare0"
1468 [(set (reg:CC_NOOV 24)
1469 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
1470 [(match_operand:SI 1 "s_register_operand" "r")
1471 (match_operand:SI 2 "arm_rhs_operand" "rM")])
1472 (const_int 0)))
1473 (set (match_operand:SI 0 "s_register_operand" "=r")
1474 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
1475 ""
1476 "mov%?s\\t%0, %1%S3"
1477 [(set_attr "conds" "set")])
1478
1479 (define_insn "*shiftsi3_compare0_scratch"
1480 [(set (reg:CC_NOOV 24)
1481 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
1482 [(match_operand:SI 1 "s_register_operand" "r")
1483 (match_operand:SI 2 "arm_rhs_operand" "rM")])
1484 (const_int 0)))
1485 (clobber (match_scratch:SI 0 "=r"))]
1486 ""
1487 "mov%?s\\t%0, %1%S3"
1488 [(set_attr "conds" "set")])
1489
1490 (define_insn "*notsi_shiftsi"
1491 [(set (match_operand:SI 0 "s_register_operand" "=r")
1492 (not:SI (match_operator:SI 3 "shift_operator"
1493 [(match_operand:SI 1 "s_register_operand" "r")
1494 (match_operand:SI 2 "arm_rhs_operand" "rM")])))]
1495 ""
1496 "mvn%?\\t%0, %1%S3")
1497
1498 (define_insn "*notsi_shiftsi_compare0"
1499 [(set (reg:CC_NOOV 24)
1500 (compare:CC_NOOV (not:SI (match_operator:SI 3 "shift_operator"
1501 [(match_operand:SI 1 "s_register_operand" "r")
1502 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
1503 (const_int 0)))
1504 (set (match_operand:SI 0 "s_register_operand" "=r")
1505 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
1506 ""
1507 "mvn%?s\\t%0, %1%S3"
1508 [(set_attr "conds" "set")])
1509
1510 (define_insn "*not_shiftsi_compare0_scratch"
1511 [(set (reg:CC_NOOV 24)
1512 (compare:CC_NOOV (not:SI (match_operator:SI 3 "shift_operator"
1513 [(match_operand:SI 1 "s_register_operand" "r")
1514 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
1515 (const_int 0)))
1516 (clobber (match_scratch:SI 0 "=r"))]
1517 ""
1518 "mvn%?s\\t%0, %1%S3"
1519 [(set_attr "conds" "set")])
1520
1521 \f
1522 ;; Unary arithmetic insns
1523
1524 (define_insn "negdi2"
1525 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1526 (neg:DI (match_operand:DI 1 "s_register_operand" "?r,0")))]
1527 ""
1528 "rsbs\\t%0, %1, #0\;rsc\\t%R0, %R1, #0"
1529 [(set_attr "conds" "clob")
1530 (set_attr "length" "8")])
1531
1532 (define_insn "negsi2"
1533 [(set (match_operand:SI 0 "s_register_operand" "=r")
1534 (neg:SI (match_operand:SI 1 "s_register_operand" "r")))]
1535 ""
1536 "rsb%?\\t%0, %1, #0")
1537
1538 (define_insn "negsf2"
1539 [(set (match_operand:SF 0 "s_register_operand" "=f")
1540 (neg:SF (match_operand:SF 1 "s_register_operand" "f")))]
1541 "TARGET_HARD_FLOAT"
1542 "mnf%?s\\t%0, %1"
1543 [(set_attr "type" "ffarith")])
1544
1545 (define_insn "negdf2"
1546 [(set (match_operand:DF 0 "s_register_operand" "=f")
1547 (neg:DF (match_operand:DF 1 "s_register_operand" "f")))]
1548 "TARGET_HARD_FLOAT"
1549 "mnf%?d\\t%0, %1"
1550 [(set_attr "type" "ffarith")])
1551
1552 (define_insn "*negdf_esfdf"
1553 [(set (match_operand:DF 0 "s_register_operand" "=f")
1554 (neg:DF (float_extend:DF
1555 (match_operand:SF 1 "s_register_operand" "f"))))]
1556 "TARGET_HARD_FLOAT"
1557 "mnf%?d\\t%0, %1"
1558 [(set_attr "type" "ffarith")])
1559
1560 (define_insn "negxf2"
1561 [(set (match_operand:XF 0 "s_register_operand" "=f")
1562 (neg:XF (match_operand:XF 1 "s_register_operand" "f")))]
1563 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
1564 "mnf%?e\\t%0, %1"
1565 [(set_attr "type" "ffarith")])
1566
1567 ;; abssi2 doesn't really clobber the condition codes if a different register
1568 ;; is being set. To keep things simple, assume during rtl manipulations that
1569 ;; it does, but tell the final scan operator the truth. Similarly for
1570 ;; (neg (abs...))
1571
1572 (define_insn "abssi2"
1573 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
1574 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
1575 (clobber (reg 24))]
1576 ""
1577 "@
1578 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
1579 eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31"
1580 [(set_attr "conds" "clob,*")
1581 (set_attr "length" "8")])
1582
1583 (define_insn "*neg_abssi2"
1584 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
1585 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
1586 (clobber (reg 24))]
1587 ""
1588 "@
1589 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
1590 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31"
1591 [(set_attr "conds" "clob,*")
1592 (set_attr "length" "8")])
1593
1594 (define_insn "abssf2"
1595 [(set (match_operand:SF 0 "s_register_operand" "=f")
1596 (abs:SF (match_operand:SF 1 "s_register_operand" "f")))]
1597 "TARGET_HARD_FLOAT"
1598 "abs%?s\\t%0, %1"
1599 [(set_attr "type" "ffarith")])
1600
1601 (define_insn "absdf2"
1602 [(set (match_operand:DF 0 "s_register_operand" "=f")
1603 (abs:DF (match_operand:DF 1 "s_register_operand" "f")))]
1604 "TARGET_HARD_FLOAT"
1605 "abs%?d\\t%0, %1"
1606 [(set_attr "type" "ffarith")])
1607
1608 (define_insn "*absdf_esfdf"
1609 [(set (match_operand:DF 0 "s_register_operand" "=f")
1610 (abs:DF (float_extend:DF
1611 (match_operand:SF 1 "s_register_operand" "f"))))]
1612 "TARGET_HARD_FLOAT"
1613 "abs%?d\\t%0, %1"
1614 [(set_attr "type" "ffarith")])
1615
1616 (define_insn "absxf2"
1617 [(set (match_operand:XF 0 "s_register_operand" "=f")
1618 (abs:XF (match_operand:XF 1 "s_register_operand" "f")))]
1619 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
1620 "abs%?e\\t%0, %1"
1621 [(set_attr "type" "ffarith")])
1622
1623 (define_insn "sqrtsf2"
1624 [(set (match_operand:SF 0 "s_register_operand" "=f")
1625 (sqrt:SF (match_operand:SF 1 "s_register_operand" "f")))]
1626 "TARGET_HARD_FLOAT"
1627 "sqt%?s\\t%0, %1"
1628 [(set_attr "type" "float_em")])
1629
1630 (define_insn "sqrtdf2"
1631 [(set (match_operand:DF 0 "s_register_operand" "=f")
1632 (sqrt:DF (match_operand:DF 1 "s_register_operand" "f")))]
1633 "TARGET_HARD_FLOAT"
1634 "sqt%?d\\t%0, %1"
1635 [(set_attr "type" "float_em")])
1636
1637 (define_insn "*sqrtdf_esfdf"
1638 [(set (match_operand:DF 0 "s_register_operand" "=f")
1639 (sqrt:DF (float_extend:DF
1640 (match_operand:SF 1 "s_register_operand" "f"))))]
1641 "TARGET_HARD_FLOAT"
1642 "sqt%?d\\t%0, %1"
1643 [(set_attr "type" "float_em")])
1644
1645 (define_insn "sqrtxf2"
1646 [(set (match_operand:XF 0 "s_register_operand" "=f")
1647 (sqrt:XF (match_operand:XF 1 "s_register_operand" "f")))]
1648 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
1649 "sqt%?e\\t%0, %1"
1650 [(set_attr "type" "float_em")])
1651
1652 (define_insn "sinsf2"
1653 [(set (match_operand:SF 0 "s_register_operand" "=f")
1654 (unspec:SF [(match_operand:SF 1 "s_register_operand" "f")] 0))]
1655 "TARGET_HARD_FLOAT"
1656 "sin%?s\\t%0, %1"
1657 [(set_attr "type" "float_em")])
1658
1659 (define_insn "sindf2"
1660 [(set (match_operand:DF 0 "s_register_operand" "=f")
1661 (unspec:DF [(match_operand:DF 1 "s_register_operand" "f")] 0))]
1662 "TARGET_HARD_FLOAT"
1663 "sin%?d\\t%0, %1"
1664 [(set_attr "type" "float_em")])
1665
1666 (define_insn "*sindf_esfdf"
1667 [(set (match_operand:DF 0 "s_register_operand" "=f")
1668 (unspec:DF [(float_extend:DF
1669 (match_operand:SF 1 "s_register_operand" "f"))] 0))]
1670 "TARGET_HARD_FLOAT"
1671 "sin%?d\\t%0, %1"
1672 [(set_attr "type" "float_em")])
1673
1674 (define_insn "sinxf2"
1675 [(set (match_operand:XF 0 "s_register_operand" "=f")
1676 (unspec:XF [(match_operand:XF 1 "s_register_operand" "f")] 0))]
1677 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
1678 "sin%?e\\t%0, %1"
1679 [(set_attr "type" "float_em")])
1680
1681 (define_insn "cossf2"
1682 [(set (match_operand:SF 0 "s_register_operand" "=f")
1683 (unspec:SF [(match_operand:SF 1 "s_register_operand" "f")] 1))]
1684 "TARGET_HARD_FLOAT"
1685 "cos%?s\\t%0, %1"
1686 [(set_attr "type" "float_em")])
1687
1688 (define_insn "cosdf2"
1689 [(set (match_operand:DF 0 "s_register_operand" "=f")
1690 (unspec:DF [(match_operand:DF 1 "s_register_operand" "f")] 1))]
1691 "TARGET_HARD_FLOAT"
1692 "cos%?d\\t%0, %1"
1693 [(set_attr "type" "float_em")])
1694
1695 (define_insn "*cosdf_esfdf"
1696 [(set (match_operand:DF 0 "s_register_operand" "=f")
1697 (unspec:DF [(float_extend:DF
1698 (match_operand:SF 1 "s_register_operand" "f"))] 1))]
1699 "TARGET_HARD_FLOAT"
1700 "cos%?d\\t%0, %1"
1701 [(set_attr "type" "float_em")])
1702
1703 (define_insn "cosxf2"
1704 [(set (match_operand:XF 0 "s_register_operand" "=f")
1705 (unspec:XF [(match_operand:XF 1 "s_register_operand" "f")] 1))]
1706 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
1707 "cos%?e\\t%0, %1"
1708 [(set_attr "type" "float_em")])
1709
1710 (define_insn "one_cmpldi2"
1711 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1712 (not:DI (match_operand:DI 1 "s_register_operand" "?r,0")))]
1713 ""
1714 "mvn%?\\t%0, %1\;mvn%?\\t%R0, %R1"
1715 [(set_attr "length" "8")])
1716
1717 (define_insn "one_cmplsi2"
1718 [(set (match_operand:SI 0 "s_register_operand" "=r")
1719 (not:SI (match_operand:SI 1 "s_register_operand" "r")))]
1720 ""
1721 "mvn%?\\t%0, %1")
1722
1723 (define_insn "*notsi_compare0"
1724 [(set (reg:CC_NOOV 24)
1725 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
1726 (const_int 0)))
1727 (set (match_operand:SI 0 "s_register_operand" "=r")
1728 (not:SI (match_dup 1)))]
1729 ""
1730 "mvn%?s\\t%0, %1"
1731 [(set_attr "conds" "set")])
1732
1733 (define_insn "*notsi_compare0_scratch"
1734 [(set (reg:CC_NOOV 24)
1735 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
1736 (const_int 0)))
1737 (clobber (match_scratch:SI 0 "=r"))]
1738 ""
1739 "mvn%?s\\t%0, %1"
1740 [(set_attr "conds" "set")])
1741 \f
1742 ;; Fixed <--> Floating conversion insns
1743
1744 (define_insn "floatsisf2"
1745 [(set (match_operand:SF 0 "s_register_operand" "=f")
1746 (float:SF (match_operand:SI 1 "s_register_operand" "r")))]
1747 "TARGET_HARD_FLOAT"
1748 "flt%?s\\t%0, %1"
1749 [(set_attr "type" "r_2_f")])
1750
1751 (define_insn "floatsidf2"
1752 [(set (match_operand:DF 0 "s_register_operand" "=f")
1753 (float:DF (match_operand:SI 1 "s_register_operand" "r")))]
1754 "TARGET_HARD_FLOAT"
1755 "flt%?d\\t%0, %1"
1756 [(set_attr "type" "r_2_f")])
1757
1758 (define_insn "floatsixf2"
1759 [(set (match_operand:XF 0 "s_register_operand" "=f")
1760 (float:XF (match_operand:SI 1 "s_register_operand" "r")))]
1761 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
1762 "flt%?e\\t%0, %1"
1763 [(set_attr "type" "r_2_f")])
1764
1765 (define_insn "fix_truncsfsi2"
1766 [(set (match_operand:SI 0 "s_register_operand" "=r")
1767 (fix:SI (match_operand:SF 1 "s_register_operand" "f")))]
1768 "TARGET_HARD_FLOAT"
1769 "fix%?z\\t%0, %1"
1770 [(set_attr "type" "f_2_r")])
1771
1772 (define_insn "fix_truncdfsi2"
1773 [(set (match_operand:SI 0 "s_register_operand" "=r")
1774 (fix:SI (match_operand:DF 1 "s_register_operand" "f")))]
1775 "TARGET_HARD_FLOAT"
1776 "fix%?z\\t%0, %1"
1777 [(set_attr "type" "f_2_r")])
1778
1779 (define_insn "fix_truncxfsi2"
1780 [(set (match_operand:SI 0 "s_register_operand" "=r")
1781 (fix:SI (match_operand:XF 1 "s_register_operand" "f")))]
1782 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
1783 "fix%?z\\t%0, %1"
1784 [(set_attr "type" "f_2_r")])
1785
1786 ;; Truncation insns
1787
1788 (define_insn "truncdfsf2"
1789 [(set (match_operand:SF 0 "s_register_operand" "=f")
1790 (float_truncate:SF
1791 (match_operand:DF 1 "s_register_operand" "f")))]
1792 "TARGET_HARD_FLOAT"
1793 "mvf%?s\\t%0, %1"
1794 [(set_attr "type" "ffarith")])
1795
1796 (define_insn "truncxfsf2"
1797 [(set (match_operand:SF 0 "s_register_operand" "=f")
1798 (float_truncate:SF
1799 (match_operand:XF 1 "s_register_operand" "f")))]
1800 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
1801 "mvf%?s\\t%0, %1"
1802 [(set_attr "type" "ffarith")])
1803
1804 (define_insn "truncxfdf2"
1805 [(set (match_operand:DF 0 "s_register_operand" "=f")
1806 (float_truncate:DF
1807 (match_operand:XF 1 "s_register_operand" "f")))]
1808 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
1809 "mvf%?d\\t%0, %1"
1810 [(set_attr "type" "ffarith")])
1811 \f
1812 ;; Zero and sign extension instructions.
1813
1814 (define_insn "zero_extendsidi2"
1815 [(set (match_operand:DI 0 "s_register_operand" "=r")
1816 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
1817 ""
1818 "*
1819 if (REGNO (operands[1]) != REGNO (operands[0]))
1820 output_asm_insn (\"mov%?\\t%0, %1\", operands);
1821 return \"mov%?\\t%R0, #0\";
1822 "
1823 [(set_attr "length" "8")])
1824
1825 (define_insn "zero_extendqidi2"
1826 [(set (match_operand:DI 0 "s_register_operand" "=r,r")
1827 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1828 ""
1829 "@
1830 and%?\\t%0, %1, #255\;mov%?\\t%R0, #0
1831 ldr%?b\\t%0, %1\;mov%?\\t%R0, #0"
1832 [(set_attr "length" "8")
1833 (set_attr "type" "*,load")])
1834
1835 (define_insn "extendsidi2"
1836 [(set (match_operand:DI 0 "s_register_operand" "=r")
1837 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
1838 ""
1839 "*
1840 if (REGNO (operands[1]) != REGNO (operands[0]))
1841 output_asm_insn (\"mov%?\\t%0, %1\", operands);
1842 return \"mov%?\\t%R0, %0, asr #31\";
1843 "
1844 [(set_attr "length" "8")])
1845
1846 (define_expand "zero_extendhisi2"
1847 [(set (match_dup 2) (ashift:SI (match_operand:HI 1 "nonimmediate_operand" "")
1848 (const_int 16)))
1849 (set (match_operand:SI 0 "s_register_operand" "")
1850 (lshiftrt:SI (match_dup 2) (const_int 16)))]
1851 ""
1852 "
1853 {
1854 if (arm_arch4 && GET_CODE (operands[1]) == MEM)
1855 {
1856 emit_insn (gen_rtx (SET, VOIDmode, operands[0],
1857 gen_rtx (ZERO_EXTEND, SImode, operands[1])));
1858 DONE;
1859 }
1860 if (TARGET_SHORT_BY_BYTES && GET_CODE (operands[1]) == MEM)
1861 {
1862 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
1863 DONE;
1864 }
1865 if (! s_register_operand (operands[1], HImode))
1866 operands[1] = copy_to_mode_reg (HImode, operands[1]);
1867 operands[1] = gen_lowpart (SImode, operands[1]);
1868 operands[2] = gen_reg_rtx (SImode);
1869 }")
1870
1871 (define_insn "*zero_extendhisi_insn"
1872 [(set (match_operand:SI 0 "s_register_operand" "=r")
1873 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
1874 "arm_arch4"
1875 "ldr%?h\\t%0, %1"
1876 [(set_attr "type" "load")])
1877
1878 (define_expand "zero_extendqisi2"
1879 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1880 (zero_extend:SI
1881 (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1882 ""
1883 "
1884 if (GET_CODE (operands[1]) != MEM)
1885 {
1886 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, operands[1]),
1887 GEN_INT (255)));
1888 DONE;
1889 }
1890 ")
1891
1892 (define_insn "*load_extendqisi"
1893 [(set (match_operand:SI 0 "s_register_operand" "=r")
1894 (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
1895 ""
1896 "ldr%?b\\t%0, %1\\t%@ zero_extendqisi2"
1897 [(set_attr "type" "load")])
1898
1899 (define_split
1900 [(set (match_operand:SI 0 "s_register_operand" "")
1901 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
1902 (clobber (match_operand:SI 2 "s_register_operand" ""))]
1903 "GET_CODE (operands[1]) != MEM"
1904 [(set (match_dup 2) (match_dup 1))
1905 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
1906 "")
1907
1908 (define_insn "*compareqi_eq0"
1909 [(set (reg:CC_NOOV 24)
1910 (compare:CC_NOOV (match_operand:QI 0 "s_register_operand" "r")
1911 (const_int 0)))]
1912 ""
1913 "tst\\t%0, #255"
1914 [(set_attr "conds" "set")])
1915
1916 (define_expand "extendhisi2"
1917 [(set (match_dup 2)
1918 (ashift:SI (match_operand:HI 1 "nonimmediate_operand" "")
1919 (const_int 16)))
1920 (set (match_operand:SI 0 "s_register_operand" "")
1921 (ashiftrt:SI (match_dup 2)
1922 (const_int 16)))]
1923 ""
1924 "
1925 {
1926 if (arm_arch4 && GET_CODE (operands[1]) == MEM)
1927 {
1928 emit_insn (gen_rtx (SET, VOIDmode, operands[0],
1929 gen_rtx (SIGN_EXTEND, SImode, operands[1])));
1930 DONE;
1931 }
1932
1933 if (TARGET_SHORT_BY_BYTES && GET_CODE (operands[1]) == MEM)
1934 {
1935 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
1936 DONE;
1937 }
1938 if (! s_register_operand (operands[1], HImode))
1939 operands[1] = copy_to_mode_reg (HImode, operands[1]);
1940 operands[1] = gen_lowpart (SImode, operands[1]);
1941 operands[2] = gen_reg_rtx (SImode);
1942 }")
1943
1944 (define_expand "extendhisi2_mem"
1945 [(set (match_dup 2) (zero_extend:SI (mem:QI (match_operand:HI 1 "" ""))))
1946 (set (match_dup 3)
1947 (zero_extend:SI (mem:QI (plus:SI (match_dup 1) (const_int 1)))))
1948 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
1949 (set (match_operand:SI 0 "" "")
1950 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
1951 ""
1952 "
1953 operands[0] = gen_lowpart (SImode, operands[0]);
1954 operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
1955 operands[2] = gen_reg_rtx (SImode);
1956 operands[3] = gen_reg_rtx (SImode);
1957 operands[6] = gen_reg_rtx (SImode);
1958
1959 if (BYTES_BIG_ENDIAN)
1960 {
1961 operands[4] = operands[2];
1962 operands[5] = operands[3];
1963 }
1964 else
1965 {
1966 operands[4] = operands[3];
1967 operands[5] = operands[2];
1968 }
1969 ")
1970
1971 (define_insn "*extendhisi_insn"
1972 [(set (match_operand:SI 0 "s_register_operand" "=r")
1973 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
1974 "arm_arch4"
1975 "ldr%?sh\\t%0, %1"
1976 [(set_attr "type" "load")])
1977
1978 (define_expand "extendqihi2"
1979 [(set (match_dup 2)
1980 (ashift:SI (match_operand:QI 1 "general_operand" "")
1981 (const_int 24)))
1982 (set (match_operand:HI 0 "s_register_operand" "")
1983 (ashiftrt:SI (match_dup 2)
1984 (const_int 24)))]
1985 ""
1986 "
1987 {
1988 if (arm_arch4 && GET_CODE (operands[1]) == MEM)
1989 {
1990 emit_insn (gen_rtx (SET, VOIDmode, operands[0],
1991 gen_rtx (SIGN_EXTEND, HImode, operands[1])));
1992 DONE;
1993 }
1994 if (! s_register_operand (operands[1], QImode))
1995 operands[1] = copy_to_mode_reg (QImode, operands[1]);
1996 operands[0] = gen_lowpart (SImode, operands[0]);
1997 operands[1] = gen_lowpart (SImode, operands[1]);
1998 operands[2] = gen_reg_rtx (SImode);
1999 }")
2000
2001 (define_insn "*extendqihi_insn"
2002 [(set (match_operand:HI 0 "s_register_operand" "=r")
2003 (sign_extend:HI (match_operand:QI 1 "memory_operand" "o<>")))]
2004 "arm_arch4"
2005 "ldr%?sb\\t%0, %1"
2006 [(set_attr "type" "load")])
2007
2008 (define_expand "extendqisi2"
2009 [(set (match_dup 2)
2010 (ashift:SI (match_operand:QI 1 "s_register_operand" "")
2011 (const_int 24)))
2012 (set (match_operand:SI 0 "s_register_operand" "")
2013 (ashiftrt:SI (match_dup 2)
2014 (const_int 24)))]
2015 ""
2016 "
2017 {
2018 if (arm_arch4 && GET_CODE (operands[1]) == MEM)
2019 {
2020 emit_insn (gen_rtx (SET, VOIDmode, operands[0],
2021 gen_rtx (SIGN_EXTEND, SImode, operands[1])));
2022 DONE;
2023 }
2024 if (! s_register_operand (operands[1], QImode))
2025 operands[1] = copy_to_mode_reg (QImode, operands[1]);
2026 operands[1] = gen_lowpart (SImode, operands[1]);
2027 operands[2] = gen_reg_rtx (SImode);
2028 }")
2029
2030 (define_insn "*extendqisi_insn"
2031 [(set (match_operand:SI 0 "s_register_operand" "=r")
2032 (sign_extend:SI (match_operand:QI 1 "memory_operand" "o<>")))]
2033 "arm_arch4"
2034 "ldr%?sb\\t%0, %1"
2035 [(set_attr "type" "load")])
2036
2037 (define_insn "extendsfdf2"
2038 [(set (match_operand:DF 0 "s_register_operand" "=f")
2039 (float_extend:DF (match_operand:SF 1 "s_register_operand" "f")))]
2040 "TARGET_HARD_FLOAT"
2041 "mvf%?d\\t%0, %1"
2042 [(set_attr "type" "ffarith")])
2043
2044 (define_insn "extendsfxf2"
2045 [(set (match_operand:XF 0 "s_register_operand" "=f")
2046 (float_extend:XF (match_operand:SF 1 "s_register_operand" "f")))]
2047 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
2048 "mvf%?e\\t%0, %1"
2049 [(set_attr "type" "ffarith")])
2050
2051 (define_insn "extenddfxf2"
2052 [(set (match_operand:XF 0 "s_register_operand" "=f")
2053 (float_extend:XF (match_operand:DF 1 "s_register_operand" "f")))]
2054 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
2055 "mvf%?e\\t%0, %1"
2056 [(set_attr "type" "ffarith")])
2057
2058 \f
2059 ;; Move insns (including loads and stores)
2060
2061 ;; XXX Just some ideas about movti.
2062 ;; I don't think these are a good idea on the arm, there just aren't enough
2063 ;; registers
2064 ;;(define_expand "loadti"
2065 ;; [(set (match_operand:TI 0 "s_register_operand" "")
2066 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
2067 ;; "" "")
2068
2069 ;;(define_expand "storeti"
2070 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
2071 ;; (match_operand:TI 1 "s_register_operand" ""))]
2072 ;; "" "")
2073
2074 ;;(define_expand "movti"
2075 ;; [(set (match_operand:TI 0 "general_operand" "")
2076 ;; (match_operand:TI 1 "general_operand" ""))]
2077 ;; ""
2078 ;; "
2079 ;;{
2080 ;; rtx insn;
2081 ;;
2082 ;; if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
2083 ;; operands[1] = copy_to_reg (operands[1]);
2084 ;; if (GET_CODE (operands[0]) == MEM)
2085 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
2086 ;; else if (GET_CODE (operands[1]) == MEM)
2087 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
2088 ;; else
2089 ;; FAIL;
2090 ;;
2091 ;; emit_insn (insn);
2092 ;; DONE;
2093 ;;}")
2094
2095 ;; Recognise garbage generated above.
2096
2097 ;;(define_insn ""
2098 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
2099 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
2100 ;; ""
2101 ;; "*
2102 ;; {
2103 ;; register mem = (which_alternative < 3);
2104 ;; register char *template;
2105 ;;
2106 ;; operands[mem] = XEXP (operands[mem], 0);
2107 ;; switch (which_alternative)
2108 ;; {
2109 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
2110 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
2111 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
2112 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
2113 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
2114 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
2115 ;; }
2116 ;; output_asm_insn (template, operands);
2117 ;; return \"\";
2118 ;; }")
2119
2120
2121 (define_insn "movdi"
2122 [(set (match_operand:DI 0 "di_operand" "=r,r,o<>")
2123 (match_operand:DI 1 "di_operand" "rIK,mi,r"))]
2124 ""
2125 "*
2126 return (output_move_double (operands));
2127 "
2128 [(set_attr "length" "8,8,8")
2129 (set_attr "type" "*,load,store2")])
2130
2131 (define_expand "movsi"
2132 [(set (match_operand:SI 0 "general_operand" "")
2133 (match_operand:SI 1 "general_operand" ""))]
2134 ""
2135 "
2136 /* Everything except mem = const or mem = mem can be done easily */
2137 if (GET_CODE (operands[0]) == MEM)
2138 operands[1] = force_reg (SImode, operands[1]);
2139 if (GET_CODE (operands[1]) == CONST_INT
2140 && !(const_ok_for_arm (INTVAL (operands[1]))
2141 || const_ok_for_arm (~INTVAL (operands[1]))))
2142 {
2143 arm_split_constant (SET, SImode, INTVAL (operands[1]), operands[0],
2144 NULL_RTX,
2145 (reload_in_progress || reload_completed ? 0
2146 : preserve_subexpressions_p ()));
2147 DONE;
2148 }
2149 ")
2150
2151 (define_insn "*movsi_insn"
2152 [(set (match_operand:SI 0 "general_operand" "=r,r,r,m")
2153 (match_operand:SI 1 "general_operand" "rI,K,mi,r"))]
2154 "register_operand (operands[0], SImode)
2155 || register_operand (operands[1], SImode)"
2156 "@
2157 mov%?\\t%0, %1
2158 mvn%?\\t%0, #%B1
2159 ldr%?\\t%0, %1
2160 str%?\\t%1, %0"
2161 [(set_attr "type" "*,*,load,store1")])
2162
2163 (define_split
2164 [(set (match_operand:SI 0 "s_register_operand" "")
2165 (match_operand:SI 1 "const_int_operand" ""))]
2166 "! (const_ok_for_arm (INTVAL (operands[1]))
2167 || const_ok_for_arm (~INTVAL (operands[1])))"
2168 [(clobber (const_int 0))]
2169 "
2170 arm_split_constant (SET, SImode, INTVAL (operands[1]), operands[0],
2171 NULL_RTX, 0);
2172 DONE;
2173 ")
2174
2175 (define_expand "movaddr"
2176 [(set (match_operand:SI 0 "s_register_operand" "")
2177 (match_operand:DI 1 "address_operand" ""))]
2178 ""
2179 "")
2180
2181 (define_insn "*movaddr_insn"
2182 [(set (match_operand:SI 0 "s_register_operand" "=r")
2183 (match_operand:DI 1 "address_operand" "p"))]
2184 "reload_completed
2185 && (GET_CODE (operands[1]) == LABEL_REF
2186 || (GET_CODE (operands[1]) == CONST
2187 && GET_CODE (XEXP (operands[1], 0)) == PLUS
2188 && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
2189 && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT))"
2190 "adr%?\\t%0, %a1")
2191
2192 ;; If copying one reg to another we can set the condition codes according to
2193 ;; its value. Such a move is common after a return from subroutine and the
2194 ;; result is being tested against zero.
2195
2196 (define_insn "*movsi_compare0"
2197 [(set (reg:CC 24) (compare (match_operand:SI 1 "s_register_operand" "0,r")
2198 (const_int 0)))
2199 (set (match_operand:SI 0 "s_register_operand" "=r,r") (match_dup 1))]
2200 ""
2201 "@
2202 cmp%?\\t%0, #0
2203 sub%?s\\t%0, %1, #0"
2204 [(set_attr "conds" "set")])
2205
2206 ;; Subroutine to store a half word from a register into memory.
2207 ;; Operand 0 is the source register (HImode)
2208 ;; Operand 1 is the destination address in a register (SImode)
2209
2210 ;; In both this routine and the next, we must be careful not to spill
2211 ;; a memory address of reg+large_const into a separate PLUS insn, since this
2212 ;; can generate unrecognizable rtl.
2213
2214 (define_expand "storehi"
2215 [;; store the low byte
2216 (set (mem:QI (match_operand:SI 1 "" "")) (match_dup 3))
2217 ;; extract the high byte
2218 (set (match_dup 2)
2219 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
2220 ;; store the high byte
2221 (set (mem:QI (match_dup 4))
2222 (subreg:QI (match_dup 2) 0))] ;explicit subreg safe
2223 ""
2224 "
2225 {
2226 enum rtx_code code = GET_CODE (operands[1]);
2227
2228 if ((code == PLUS || code == MINUS)
2229 && (GET_CODE (XEXP (operands[1], 1)) == REG
2230 || GET_CODE (XEXP (operands[1], 0)) != REG))
2231 operands[1] = force_reg (SImode, operands[1]);
2232 operands[4] = plus_constant (operands[1], 1);
2233 operands[3] = gen_lowpart (QImode, operands[0]);
2234 operands[0] = gen_lowpart (SImode, operands[0]);
2235 operands[2] = gen_reg_rtx (SImode);
2236 }
2237 ")
2238
2239 (define_expand "storehi_bigend"
2240 [(set (mem:QI (match_dup 4)) (match_dup 3))
2241 (set (match_dup 2)
2242 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
2243 (set (mem:QI (match_operand 1 "" ""))
2244 (subreg:QI (match_dup 2) 0))]
2245 ""
2246 "
2247 {
2248 enum rtx_code code = GET_CODE (operands[1]);
2249 if ((code == PLUS || code == MINUS)
2250 && (GET_CODE (XEXP (operands[1], 1)) == REG
2251 || GET_CODE (XEXP (operands[1], 0)) != REG))
2252 operands[1] = force_reg (SImode, operands[1]);
2253
2254 operands[4] = plus_constant (operands[1], 1);
2255 operands[3] = gen_lowpart (QImode, operands[0]);
2256 operands[0] = gen_lowpart (SImode, operands[0]);
2257 operands[2] = gen_reg_rtx (SImode);
2258 }
2259 ")
2260
2261 ;; Subroutine to store a half word integer constant into memory.
2262 (define_expand "storeinthi"
2263 [(set (mem:QI (match_operand:SI 0 "" ""))
2264 (subreg:QI (match_operand 1 "" "") 0))
2265 (set (mem:QI (match_dup 3)) (subreg:QI (match_dup 2) 0))]
2266 ""
2267 "
2268 {
2269 HOST_WIDE_INT value = INTVAL (operands[1]);
2270 enum rtx_code code = GET_CODE (operands[0]);
2271
2272 if ((code == PLUS || code == MINUS)
2273 && (GET_CODE (XEXP (operands[0], 1)) == REG
2274 || GET_CODE (XEXP (operands[0], 0)) != REG))
2275 operands[0] = force_reg (SImode, operands[0]);
2276
2277 operands[1] = gen_reg_rtx (SImode);
2278 if (BYTES_BIG_ENDIAN)
2279 {
2280 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
2281 if ((value & 255) == ((value >> 8) & 255))
2282 operands[2] = operands[1];
2283 else
2284 {
2285 operands[2] = gen_reg_rtx (SImode);
2286 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
2287 }
2288 }
2289 else
2290 {
2291 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
2292 if ((value & 255) == ((value >> 8) & 255))
2293 operands[2] = operands[1];
2294 else
2295 {
2296 operands[2] = gen_reg_rtx (SImode);
2297 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
2298 }
2299 }
2300
2301 operands[3] = plus_constant (operands[0], 1);
2302 }
2303 ")
2304
2305 (define_expand "storehi_single_op"
2306 [(set (match_operand:HI 0 "memory_operand" "")
2307 (match_operand:HI 1 "general_operand" ""))]
2308 "arm_arch4"
2309 "
2310 if (! s_register_operand (operands[1], HImode))
2311 operands[1] = copy_to_mode_reg (HImode, operands[1]);
2312 ")
2313
2314 (define_expand "movhi"
2315 [(set (match_operand:HI 0 "general_operand" "")
2316 (match_operand:HI 1 "general_operand" ""))]
2317 ""
2318 "
2319 {
2320 rtx insn;
2321
2322 if (! (reload_in_progress || reload_completed))
2323 {
2324 if (GET_CODE (operands[0]) == MEM)
2325 {
2326 if (arm_arch4)
2327 {
2328 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
2329 DONE;
2330 }
2331 if (GET_CODE (operands[1]) == CONST_INT)
2332 emit_insn (gen_storeinthi (XEXP (operands[0], 0), operands[1]));
2333 else
2334 {
2335 if (GET_CODE (operands[1]) == MEM)
2336 operands[1] = force_reg (HImode, operands[1]);
2337 if (BYTES_BIG_ENDIAN)
2338 emit_insn (gen_storehi_bigend (operands[1],
2339 XEXP (operands[0], 0)));
2340 else
2341 emit_insn (gen_storehi (operands[1], XEXP (operands[0], 0)));
2342 }
2343 DONE;
2344 }
2345 /* Sign extend a constant, and keep it in an SImode reg. */
2346 else if (GET_CODE (operands[1]) == CONST_INT)
2347 {
2348 rtx reg = gen_reg_rtx (SImode);
2349 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
2350
2351 /* If the constant is already valid, leave it alone. */
2352 if (! const_ok_for_arm (val))
2353 {
2354 /* If setting all the top bits will make the constant
2355 loadable in a single instruction, then set them.
2356 Otherwise, sign extend the number. */
2357
2358 if (const_ok_for_arm (~ (val | ~0xffff)))
2359 val |= ~0xffff;
2360 else if (val & 0x8000)
2361 val |= ~0xffff;
2362 }
2363
2364 emit_insn (gen_movsi (reg, GEN_INT (val)));
2365 operands[1] = gen_rtx (SUBREG, HImode, reg, 0);
2366 }
2367 else if (! arm_arch4)
2368 {
2369 if (TARGET_SHORT_BY_BYTES && GET_CODE (operands[1]) == MEM)
2370 {
2371 rtx reg = gen_reg_rtx (SImode);
2372 emit_insn (gen_movhi_bytes (reg, operands[1]));
2373 operands[1] = gen_lowpart (HImode, reg);
2374 }
2375 else if (BYTES_BIG_ENDIAN && GET_CODE (operands[1]) == MEM)
2376 {
2377 emit_insn (gen_movhi_bigend (operands[0], operands[1]));
2378 DONE;
2379 }
2380 }
2381 }
2382 }
2383 ")
2384
2385 (define_expand "movhi_bytes"
2386 [(set (match_dup 2) (zero_extend:SI (mem:QI (match_operand:HI 1 "" ""))))
2387 (set (match_dup 3)
2388 (zero_extend:SI (mem:QI (plus:SI (match_dup 1) (const_int 1)))))
2389 (set (match_operand:SI 0 "" "")
2390 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
2391 ""
2392 "
2393 operands[0] = gen_lowpart (SImode, operands[0]);
2394 operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
2395 operands[2] = gen_reg_rtx (SImode);
2396 operands[3] = gen_reg_rtx (SImode);
2397
2398 if (BYTES_BIG_ENDIAN)
2399 {
2400 operands[4] = operands[2];
2401 operands[5] = operands[3];
2402 }
2403 else
2404 {
2405 operands[4] = operands[3];
2406 operands[5] = operands[2];
2407 }
2408 ")
2409
2410 (define_expand "movhi_bigend"
2411 [(set (match_dup 2)
2412 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
2413 (const_int 16)))
2414 (set (match_dup 3)
2415 (ashiftrt:SI (match_dup 2) (const_int 16)))
2416 (set (match_operand:HI 0 "s_register_operand" "")
2417 (subreg:HI (match_dup 3) 0))]
2418 ""
2419 "
2420 operands[2] = gen_reg_rtx (SImode);
2421 operands[3] = gen_reg_rtx (SImode);
2422 ")
2423
2424 ;; Pattern to recognise insn generated default case above
2425
2426 (define_insn "*movhi_insn_arch4"
2427 [(set (match_operand:HI 0 "general_operand" "=r,r,r,m")
2428 (match_operand:HI 1 "general_operand" "rI,K,m,r"))]
2429 "arm_arch4
2430 && (GET_CODE (operands[1]) != CONST_INT
2431 || const_ok_for_arm (INTVAL (operands[1]))
2432 || const_ok_for_arm (~INTVAL (operands[1])))"
2433 "@
2434 mov%?\\t%0, %1\\t%@ movhi
2435 mvn%?\\t%0, #%B1\\t%@ movhi
2436 ldr%?h\\t%0, %1\\t%@ movhi
2437 str%?h\\t%1, %0\\t%@ movhi"
2438 [(set_attr "type" "*,*,load,store1")])
2439
2440 (define_insn "*movhi_insn_littleend"
2441 [(set (match_operand:HI 0 "general_operand" "=r,r,r")
2442 (match_operand:HI 1 "general_operand" "rI,K,m"))]
2443 "! arm_arch4
2444 && ! BYTES_BIG_ENDIAN
2445 && ! TARGET_SHORT_BY_BYTES
2446 && (GET_CODE (operands[1]) != CONST_INT
2447 || const_ok_for_arm (INTVAL (operands[1]))
2448 || const_ok_for_arm (~INTVAL (operands[1])))"
2449 "@
2450 mov%?\\t%0, %1\\t%@ movhi
2451 mvn%?\\t%0, #%B1\\t%@ movhi
2452 ldr%?\\t%0, %1\\t%@ movhi"
2453 [(set_attr "type" "*,*,load")])
2454
2455 (define_insn "*movhi_insn_bigend"
2456 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
2457 (match_operand:HI 1 "general_operand" "rI,K,m"))]
2458 "! arm_arch4
2459 && BYTES_BIG_ENDIAN
2460 && ! TARGET_SHORT_BY_BYTES
2461 && (GET_CODE (operands[1]) != CONST_INT
2462 || const_ok_for_arm (INTVAL (operands[1]))
2463 || const_ok_for_arm (~INTVAL (operands[1])))"
2464 "@
2465 mov%?\\t%0, %1\\t%@ movhi
2466 mvn%?\\t%0, #%B1\\t%@ movhi
2467 ldr%?\\t%0, %1\\t%@ movhi_bigend\;mov%?\\t%0, %0, asr #16"
2468 [(set_attr "type" "*,*,load")
2469 (set_attr "length" "4,4,8")])
2470
2471 (define_insn "*loadhi_si_bigend"
2472 [(set (match_operand:SI 0 "s_register_operand" "=r")
2473 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "m") 0)
2474 (const_int 16)))]
2475 "BYTES_BIG_ENDIAN
2476 && ! TARGET_SHORT_BY_BYTES"
2477 "ldr%?\\t%0, %1\\t%@ movhi_bigend"
2478 [(set_attr "type" "load")])
2479
2480 (define_insn "*movhi_bytes"
2481 [(set (match_operand:HI 0 "s_register_operand" "=r,r")
2482 (match_operand:HI 1 "arm_rhs_operand" "rI,K"))]
2483 "TARGET_SHORT_BY_BYTES"
2484 "@
2485 mov%?\\t%0, %1\\t%@ movhi
2486 mvn%?\\t%0, #%B1\\t%@ movhi")
2487
2488
2489 (define_expand "reload_outhi"
2490 [(parallel [(match_operand:HI 0 "reload_memory_operand" "=o")
2491 (match_operand:HI 1 "s_register_operand" "r")
2492 (match_operand:SI 2 "s_register_operand" "=&r")])]
2493 ""
2494 "
2495 arm_reload_out_hi (operands);
2496 DONE;
2497 ")
2498
2499 (define_expand "reload_inhi"
2500 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
2501 (match_operand:HI 1 "reload_memory_operand" "o")
2502 (match_operand:SI 2 "s_register_operand" "=&r")])]
2503 "TARGET_SHORT_BY_BYTES"
2504 "
2505 arm_reload_in_hi (operands);
2506 DONE;
2507 ")
2508
2509 (define_expand "movqi"
2510 [(set (match_operand:QI 0 "general_operand" "")
2511 (match_operand:QI 1 "general_operand" ""))]
2512 ""
2513 "
2514 /* Everything except mem = const or mem = mem can be done easily */
2515
2516 if (!(reload_in_progress || reload_completed))
2517 {
2518 if (GET_CODE (operands[1]) == CONST_INT)
2519 {
2520 rtx reg = gen_reg_rtx (SImode);
2521
2522 emit_insn (gen_movsi (reg, operands[1]));
2523 operands[1] = gen_rtx (SUBREG, QImode, reg, 0);
2524 }
2525 if (GET_CODE (operands[0]) == MEM)
2526 operands[1] = force_reg (QImode, operands[1]);
2527 }
2528 ")
2529
2530
2531 (define_insn "*movqi_insn"
2532 [(set (match_operand:QI 0 "general_operand" "=r,r,r,m")
2533 (match_operand:QI 1 "general_operand" "rI,K,m,r"))]
2534 "register_operand (operands[0], QImode)
2535 || register_operand (operands[1], QImode)"
2536 "@
2537 mov%?\\t%0, %1
2538 mvn%?\\t%0, #%B1
2539 ldr%?b\\t%0, %1
2540 str%?b\\t%1, %0"
2541 [(set_attr "type" "*,*,load,store1")])
2542
2543 (define_expand "movsf"
2544 [(set (match_operand:SF 0 "general_operand" "")
2545 (match_operand:SF 1 "general_operand" ""))]
2546 ""
2547 "
2548 if (GET_CODE (operands[0]) == MEM)
2549 operands[1] = force_reg (SFmode, operands[1]);
2550 ")
2551
2552 (define_insn "*movsf_hard_insn"
2553 [(set (match_operand:SF 0 "general_operand" "=f,f,f,m,f,r,r,r,m")
2554 (match_operand:SF 1 "general_operand" "fG,H,mE,f,r,f,r,mE,r"))]
2555 "TARGET_HARD_FLOAT
2556 && (GET_CODE (operands[0]) != MEM || register_operand (operands[1], SFmode))"
2557 "@
2558 mvf%?s\\t%0, %1
2559 mnf%?s\\t%0, #%N1
2560 ldf%?s\\t%0, %1
2561 stf%?s\\t%1, %0
2562 str%?\\t%1, [%|sp, #-4]!\;ldf%?s\\t%0, [%|sp], #4
2563 stf%?s\\t%1, [%|sp, #-4]!\;ldr%?\\t%0, [%|sp], #4
2564 mov%?\\t%0, %1
2565 ldr%?\\t%0, %1\\t%@ float
2566 str%?\\t%1, %0\\t%@ float"
2567 [(set_attr "length" "4,4,4,4,8,8,4,4,4")
2568 (set_attr "type"
2569 "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*,load,store1")])
2570
2571 ;; Exactly the same as above, except that all `f' cases are deleted.
2572 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2573 ;; when -msoft-float.
2574
2575 (define_insn "*movsf_soft_insn"
2576 [(set (match_operand:SF 0 "general_operand" "=r,r,m")
2577 (match_operand:SF 1 "general_operand" "r,mE,r"))]
2578 "TARGET_SOFT_FLOAT
2579 && (GET_CODE (operands[0]) != MEM || register_operand (operands[1], SFmode))"
2580 "@
2581 mov%?\\t%0, %1
2582 ldr%?\\t%0, %1\\t%@ float
2583 str%?\\t%1, %0\\t%@ float"
2584 [(set_attr "length" "4,4,4")
2585 (set_attr "type" "*,load,store1")])
2586
2587 (define_expand "movdf"
2588 [(set (match_operand:DF 0 "general_operand" "")
2589 (match_operand:DF 1 "general_operand" ""))]
2590 ""
2591 "
2592 if (GET_CODE (operands[0]) == MEM)
2593 operands[1] = force_reg (DFmode, operands[1]);
2594 ")
2595
2596 ;; Reloading a df mode value stored in integer regs to memory can require a
2597 ;; scratch reg.
2598 (define_expand "reload_outdf"
2599 [(match_operand:DF 0 "reload_memory_operand" "=o")
2600 (match_operand:DF 1 "s_register_operand" "r")
2601 (match_operand:SI 2 "s_register_operand" "=&r")]
2602 ""
2603 "
2604 {
2605 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
2606
2607 if (code == REG)
2608 operands[2] = XEXP (operands[0], 0);
2609 else if (code == POST_INC || code == PRE_DEC)
2610 {
2611 operands[0] = gen_rtx (SUBREG, DImode, operands[0], 0);
2612 operands[1] = gen_rtx (SUBREG, DImode, operands[1], 0);
2613 emit_insn (gen_movdi (operands[0], operands[1]));
2614 DONE;
2615 }
2616 else if (code == PRE_INC)
2617 {
2618 rtx reg = XEXP (XEXP (operands[0], 0), 0);
2619 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
2620 operands[2] = reg;
2621 }
2622 else if (code == POST_DEC)
2623 operands[2] = XEXP (XEXP (operands[0], 0), 0);
2624 else
2625 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
2626 XEXP (XEXP (operands[0], 0), 1)));
2627
2628 emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (MEM, DFmode, operands[2]),
2629 operands[1]));
2630
2631 if (code == POST_DEC)
2632 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
2633
2634 DONE;
2635 }
2636 ")
2637
2638 (define_insn "*movdf_hard_insn"
2639 [(set (match_operand:DF 0 "general_operand" "=r,Q,r,m,r,f,f,f,m,!f,!r")
2640 (match_operand:DF 1 "general_operand" "Q,r,r,r,mF,fG,H,mF,f,r,f"))]
2641 "TARGET_HARD_FLOAT
2642 && (GET_CODE (operands[0]) != MEM
2643 || register_operand (operands[1], DFmode))"
2644 "*
2645 {
2646 rtx ops[3];
2647
2648 switch (which_alternative)
2649 {
2650 case 0: return \"ldm%?ia\\t%m1, {%0, %R0}\\t%@ double\";
2651 case 1: return \"stm%?ia\\t%m0, {%1, %R1}\\t%@ double\";
2652 case 2: case 3: case 4: return output_move_double (operands);
2653 case 5: return \"mvf%?d\\t%0, %1\";
2654 case 6: return \"mnf%?d\\t%0, #%N1\";
2655 case 7: return \"ldf%?d\\t%0, %1\";
2656 case 8: return \"stf%?d\\t%1, %0\";
2657 case 9: return output_mov_double_fpu_from_arm (operands);
2658 case 10: return output_mov_double_arm_from_fpu (operands);
2659 }
2660 }
2661 "
2662 [(set_attr "length" "4,4,8,8,8,4,4,4,4,8,8")
2663 (set_attr "type"
2664 "load,store2,*,store2,load,ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r")])
2665
2666 ;; Software floating point version. This is essentially the same as movdi.
2667 ;; Do not use `f' as a constraint to prevent reload from ever trying to use
2668 ;; an `f' reg.
2669
2670 (define_insn "*movdf_soft_insn"
2671 [(set (match_operand:DF 0 "soft_df_operand" "=r,r,m")
2672 (match_operand:DF 1 "soft_df_operand" "r,mF,r"))]
2673 "TARGET_SOFT_FLOAT"
2674 "* return output_move_double (operands);"
2675 [(set_attr "length" "8,8,8")
2676 (set_attr "type" "*,load,store2")])
2677
2678 (define_expand "movxf"
2679 [(set (match_operand:XF 0 "general_operand" "")
2680 (match_operand:XF 1 "general_operand" ""))]
2681 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
2682 "")
2683
2684 ;; Even when the XFmode patterns aren't enabled, we enable this after
2685 ;; reloading so that we can push floating point registers in the prologue.
2686
2687 (define_insn "*movxf_hard_insn"
2688 [(set (match_operand:XF 0 "general_operand" "=f,f,f,m,f,r,r")
2689 (match_operand:XF 1 "general_operand" "fG,H,m,f,r,f,r"))]
2690 "TARGET_HARD_FLOAT && (ENABLE_XF_PATTERNS || reload_completed)"
2691 "*
2692 switch (which_alternative)
2693 {
2694 case 0: return \"mvf%?e\\t%0, %1\";
2695 case 1: return \"mnf%?e\\t%0, #%N1\";
2696 case 2: return \"ldf%?e\\t%0, %1\";
2697 case 3: return \"stf%?e\\t%1, %0\";
2698 case 4: return output_mov_long_double_fpu_from_arm (operands);
2699 case 5: return output_mov_long_double_arm_from_fpu (operands);
2700 case 6: return output_mov_long_double_arm_from_arm (operands);
2701 }
2702 "
2703 [(set_attr "length" "4,4,4,4,8,8,12")
2704 (set_attr "type" "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*")])
2705 \f
2706
2707 ;; load- and store-multiple insns
2708 ;; The arm can load/store any set of registers, provided that they are in
2709 ;; ascending order; but that is beyond GCC so stick with what it knows.
2710
2711 (define_expand "load_multiple"
2712 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
2713 (match_operand:SI 1 "" ""))
2714 (use (match_operand:SI 2 "" ""))])]
2715 ""
2716 "
2717 /* Support only fixed point registers */
2718 if (GET_CODE (operands[2]) != CONST_INT
2719 || INTVAL (operands[2]) > 14
2720 || INTVAL (operands[2]) < 2
2721 || GET_CODE (operands[1]) != MEM
2722 || GET_CODE (operands[0]) != REG
2723 || REGNO (operands[0]) > 14
2724 || REGNO (operands[0]) + INTVAL (operands[2]) > 15)
2725 FAIL;
2726
2727 operands[3]
2728 = arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]),
2729 force_reg (SImode, XEXP (operands[1], 0)),
2730 TRUE, FALSE);
2731 ")
2732
2733 ;; Load multiple with write-back
2734
2735 (define_insn "*ldmsi_postinc"
2736 [(match_parallel 0 "load_multiple_operation"
2737 [(set (match_operand:SI 1 "s_register_operand" "+r")
2738 (plus:SI (match_dup 1)
2739 (match_operand:SI 2 "immediate_operand" "n")))
2740 (set (match_operand:SI 3 "s_register_operand" "=r")
2741 (mem:SI (match_dup 1)))])]
2742 "(INTVAL (operands[2]) == 4 * (XVECLEN (operands[0], 0) - 2))"
2743 "*
2744 {
2745 rtx ops[3];
2746 int count = XVECLEN (operands[0], 0);
2747
2748 ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
2749 ops[1] = SET_DEST (XVECEXP (operands[0], 0, 1));
2750 ops[2] = SET_DEST (XVECEXP (operands[0], 0, count - 2));
2751
2752 output_asm_insn (\"ldm%?ia\\t%0!, {%1-%2}\\t%@ load multiple\", ops);
2753 return \"\";
2754 }
2755 "
2756 [(set_attr "type" "load")])
2757
2758 ;; Ordinary load multiple
2759
2760 (define_insn "*ldmsi"
2761 [(match_parallel 0 "load_multiple_operation"
2762 [(set (match_operand:SI 1 "s_register_operand" "=r")
2763 (match_operand:SI 2 "indirect_operand" "Q"))])]
2764 ""
2765 "*
2766 {
2767 rtx ops[3];
2768 int count = XVECLEN (operands[0], 0);
2769
2770 ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
2771 ops[1] = SET_DEST (XVECEXP (operands[0], 0, 0));
2772 ops[2] = SET_DEST (XVECEXP (operands[0], 0, count - 1));
2773
2774 output_asm_insn (\"ldm%?ia\\t%0, {%1-%2}\\t%@ load multiple\", ops);
2775 return \"\";
2776 }
2777 "
2778 [(set_attr "type" "load")])
2779
2780 (define_expand "store_multiple"
2781 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
2782 (match_operand:SI 1 "" ""))
2783 (use (match_operand:SI 2 "" ""))])]
2784 ""
2785 "
2786 /* Support only fixed point registers */
2787 if (GET_CODE (operands[2]) != CONST_INT
2788 || INTVAL (operands[2]) > 14
2789 || INTVAL (operands[2]) < 2
2790 || GET_CODE (operands[1]) != REG
2791 || GET_CODE (operands[0]) != MEM
2792 || REGNO (operands[1]) > 14
2793 || REGNO (operands[1]) + INTVAL (operands[2]) > 15)
2794 FAIL;
2795
2796 operands[3]
2797 = arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]),
2798 force_reg (SImode, XEXP (operands[0], 0)),
2799 TRUE, FALSE);
2800 ")
2801
2802 ;; Store multiple with write-back
2803
2804 (define_insn "*stmsi_postinc"
2805 [(match_parallel 0 "store_multiple_operation"
2806 [(set (match_operand:SI 1 "s_register_operand" "+r")
2807 (plus:SI (match_dup 1)
2808 (match_operand:SI 2 "immediate_operand" "n")))
2809 (set (mem:SI (match_dup 1))
2810 (match_operand:SI 3 "s_register_operand" "r"))])]
2811 "(INTVAL (operands[2]) == 4 * (XVECLEN (operands[0], 0) - 2))"
2812 "*
2813 {
2814 rtx ops[3];
2815 int count = XVECLEN (operands[0], 0);
2816
2817 ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
2818 ops[1] = SET_SRC (XVECEXP (operands[0], 0, 1));
2819 ops[2] = SET_SRC (XVECEXP (operands[0], 0, count - 2));
2820
2821 output_asm_insn (\"stm%?ia\\t%0!, {%1-%2}\\t%@ str multiple\", ops);
2822 return \"\";
2823 }
2824 "
2825 [(set (attr "type")
2826 (cond [(eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 4))
2827 (const_string "store2")
2828 (eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 5))
2829 (const_string "store3")]
2830 (const_string "store4")))])
2831
2832 ;; Ordinary store multiple
2833
2834 (define_insn "*stmsi"
2835 [(match_parallel 0 "store_multiple_operation"
2836 [(set (match_operand:SI 2 "indirect_operand" "=Q")
2837 (match_operand:SI 1 "s_register_operand" "r"))])]
2838 ""
2839 "*
2840 {
2841 rtx ops[3];
2842 int count = XVECLEN (operands[0], 0);
2843
2844 ops[0] = XEXP (SET_DEST (XVECEXP (operands[0], 0, 0)), 0);
2845 ops[1] = SET_SRC (XVECEXP (operands[0], 0, 0));
2846 ops[2] = SET_SRC (XVECEXP (operands[0], 0, count - 1));
2847
2848 output_asm_insn (\"stm%?ia\\t%0, {%1-%2}\\t%@ str multiple\", ops);
2849 return \"\";
2850 }
2851 "
2852 [(set (attr "type")
2853 (cond [(eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 3))
2854 (const_string "store2")
2855 (eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 4))
2856 (const_string "store3")]
2857 (const_string "store4")))])
2858
2859 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
2860 ;; We could let this apply for blocks of less than this, but it clobbers so
2861 ;; many registers that there is then probably a better way.
2862
2863 (define_expand "movstrqi"
2864 [(match_operand:BLK 0 "general_operand" "")
2865 (match_operand:BLK 1 "general_operand" "")
2866 (match_operand:SI 2 "const_int_operand" "")
2867 (match_operand:SI 3 "const_int_operand" "")]
2868 ""
2869 "
2870 if (arm_gen_movstrqi (operands))
2871 DONE;
2872 FAIL;
2873 ")
2874 \f
2875
2876 ;; Comparison and test insns
2877
2878 (define_expand "cmpsi"
2879 [(set (reg:CC 24)
2880 (compare:CC (match_operand:SI 0 "s_register_operand" "")
2881 (match_operand:SI 1 "arm_add_operand" "")))]
2882 ""
2883 "
2884 {
2885 arm_compare_op0 = operands[0];
2886 arm_compare_op1 = operands[1];
2887 arm_compare_fp = 0;
2888 DONE;
2889 }
2890 ")
2891
2892 (define_expand "cmpsf"
2893 [(set (reg:CC 24)
2894 (compare:CC (match_operand:SF 0 "s_register_operand" "")
2895 (match_operand:SF 1 "fpu_rhs_operand" "")))]
2896 "TARGET_HARD_FLOAT"
2897 "
2898 {
2899 arm_compare_op0 = operands[0];
2900 arm_compare_op1 = operands[1];
2901 arm_compare_fp = 1;
2902 DONE;
2903 }
2904 ")
2905
2906 (define_expand "cmpdf"
2907 [(set (reg:CC 24)
2908 (compare:CC (match_operand:DF 0 "s_register_operand" "")
2909 (match_operand:DF 1 "fpu_rhs_operand" "")))]
2910 "TARGET_HARD_FLOAT"
2911 "
2912 {
2913 arm_compare_op0 = operands[0];
2914 arm_compare_op1 = operands[1];
2915 arm_compare_fp = 1;
2916 DONE;
2917 }
2918 ")
2919
2920 (define_expand "cmpxf"
2921 [(set (reg:CC 24)
2922 (compare:CC (match_operand:XF 0 "s_register_operand" "")
2923 (match_operand:XF 1 "fpu_rhs_operand" "")))]
2924 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
2925 "
2926 {
2927 arm_compare_op0 = operands[0];
2928 arm_compare_op1 = operands[1];
2929 arm_compare_fp = 1;
2930 DONE;
2931 }
2932 ")
2933
2934 (define_insn "*cmpsi_insn"
2935 [(set (match_operand 0 "cc_register" "")
2936 (compare (match_operand:SI 1 "s_register_operand" "r,r")
2937 (match_operand:SI 2 "arm_add_operand" "rI,L")))]
2938 ""
2939 "@
2940 cmp%?\\t%1, %2
2941 cmn%?\\t%1, #%n2"
2942 [(set_attr "conds" "set")])
2943
2944 (define_insn "*cmpsi_negsi"
2945 [(set (match_operand 0 "cc_register" "")
2946 (compare (match_operand:SI 1 "s_register_operand" "r")
2947 (neg:SI (match_operand:SI 2 "s_register_operand" "r"))))]
2948 ""
2949 "cmn%?\\t%1, %2"
2950 [(set_attr "conds" "set")])
2951
2952 (define_insn "*cmpsi_shiftsi"
2953 [(set (match_operand 0 "cc_register" "")
2954 (compare (match_operand:SI 1 "s_register_operand" "r")
2955 (match_operator:SI 2 "shift_operator"
2956 [(match_operand:SI 3 "s_register_operand" "r")
2957 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
2958 ""
2959 "cmp%?\\t%1, %3%S2"
2960 [(set_attr "conds" "set")])
2961
2962 (define_insn "*cmpsi_neg_shiftsi"
2963 [(set (match_operand 0 "cc_register" "")
2964 (compare (match_operand:SI 1 "s_register_operand" "r")
2965 (neg:SI (match_operator:SI 2 "shift_operator"
2966 [(match_operand:SI 3 "s_register_operand" "r")
2967 (match_operand:SI 4 "arm_rhs_operand" "rM")]))))]
2968 ""
2969 "cmn%?\\t%1, %3%S2"
2970 [(set_attr "conds" "set")])
2971
2972 (define_insn "*cmpsf_insn"
2973 [(set (reg:CCFP 24)
2974 (compare:CCFP (match_operand:SF 0 "s_register_operand" "f,f")
2975 (match_operand:SF 1 "fpu_add_operand" "fG,H")))]
2976 "TARGET_HARD_FLOAT"
2977 "@
2978 cmf%?\\t%0, %1
2979 cnf%?\\t%0, #%N1"
2980 [(set_attr "conds" "set")
2981 (set_attr "type" "f_2_r")])
2982
2983 (define_insn "*cmpdf_insn"
2984 [(set (reg:CCFP 24)
2985 (compare:CCFP (match_operand:DF 0 "s_register_operand" "f,f")
2986 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
2987 "TARGET_HARD_FLOAT"
2988 "@
2989 cmf%?\\t%0, %1
2990 cnf%?\\t%0, #%N1"
2991 [(set_attr "conds" "set")
2992 (set_attr "type" "f_2_r")])
2993
2994 (define_insn "*cmpesfdf_df"
2995 [(set (reg:CCFP 24)
2996 (compare:CCFP (float_extend:DF
2997 (match_operand:SF 0 "s_register_operand" "f,f"))
2998 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
2999 "TARGET_HARD_FLOAT"
3000 "@
3001 cmf%?\\t%0, %1
3002 cnf%?\\t%0, #%N1"
3003 [(set_attr "conds" "set")
3004 (set_attr "type" "f_2_r")])
3005
3006 (define_insn "*cmpdf_esfdf"
3007 [(set (reg:CCFP 24)
3008 (compare:CCFP (match_operand:DF 0 "s_register_operand" "f")
3009 (float_extend:DF
3010 (match_operand:SF 1 "s_register_operand" "f"))))]
3011 "TARGET_HARD_FLOAT"
3012 "cmf%?\\t%0, %1"
3013 [(set_attr "conds" "set")
3014 (set_attr "type" "f_2_r")])
3015
3016 (define_insn "*cmpxf_insn"
3017 [(set (reg:CCFP 24)
3018 (compare:CCFP (match_operand:XF 0 "s_register_operand" "f,f")
3019 (match_operand:XF 1 "fpu_add_operand" "fG,H")))]
3020 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
3021 "@
3022 cmf%?\\t%0, %1
3023 cnf%?\\t%0, #%N1"
3024 [(set_attr "conds" "set")
3025 (set_attr "type" "f_2_r")])
3026
3027 (define_insn "*cmpsf_trap"
3028 [(set (reg:CCFPE 24)
3029 (compare:CCFPE (match_operand:SF 0 "s_register_operand" "f,f")
3030 (match_operand:SF 1 "fpu_add_operand" "fG,H")))]
3031 "TARGET_HARD_FLOAT"
3032 "@
3033 cmf%?e\\t%0, %1
3034 cnf%?e\\t%0, #%N1"
3035 [(set_attr "conds" "set")
3036 (set_attr "type" "f_2_r")])
3037
3038 (define_insn "*cmpdf_trap"
3039 [(set (reg:CCFPE 24)
3040 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f,f")
3041 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
3042 "TARGET_HARD_FLOAT"
3043 "@
3044 cmf%?e\\t%0, %1
3045 cnf%?e\\t%0, #%N1"
3046 [(set_attr "conds" "set")
3047 (set_attr "type" "f_2_r")])
3048
3049 (define_insn "*cmp_esfdf_df_trap"
3050 [(set (reg:CCFPE 24)
3051 (compare:CCFPE (float_extend:DF
3052 (match_operand:SF 0 "s_register_operand" "f,f"))
3053 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
3054 "TARGET_HARD_FLOAT"
3055 "@
3056 cmf%?e\\t%0, %1
3057 cnf%?e\\t%0, #%N1"
3058 [(set_attr "conds" "set")
3059 (set_attr "type" "f_2_r")])
3060
3061 (define_insn "*cmp_df_esfdf_trap"
3062 [(set (reg:CCFPE 24)
3063 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f")
3064 (float_extend:DF
3065 (match_operand:SF 1 "s_register_operand" "f"))))]
3066 "TARGET_HARD_FLOAT"
3067 "cmf%?e\\t%0, %1"
3068 [(set_attr "conds" "set")
3069 (set_attr "type" "f_2_r")])
3070
3071 (define_insn "*cmpxf_trap"
3072 [(set (reg:CCFPE 24)
3073 (compare:CCFPE (match_operand:XF 0 "s_register_operand" "f,f")
3074 (match_operand:XF 1 "fpu_add_operand" "fG,H")))]
3075 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
3076 "@
3077 cmf%?e\\t%0, %1
3078 cnf%?e\\t%0, #%N1"
3079 [(set_attr "conds" "set")
3080 (set_attr "type" "f_2_r")])
3081
3082 ; This insn allows redundant compares to be removed by cse, nothing should
3083 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
3084 ; is deleted later on. The match_dup will match the mode here, so that
3085 ; mode changes of the condition codes aren't lost by this even though we don't
3086 ; specify what they are.
3087
3088 (define_insn "*delted_compare"
3089 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
3090 ""
3091 "\\t%@ deleted compare"
3092 [(set_attr "conds" "set")
3093 (set_attr "length" "0")])
3094
3095 \f
3096 ;; Conditional branch insns
3097
3098 (define_expand "beq"
3099 [(set (pc)
3100 (if_then_else (eq (match_dup 1) (const_int 0))
3101 (label_ref (match_operand 0 "" ""))
3102 (pc)))]
3103 ""
3104 "
3105 {
3106 operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1,
3107 arm_compare_fp);
3108 }
3109 ")
3110
3111 (define_expand "bne"
3112 [(set (pc)
3113 (if_then_else (ne (match_dup 1) (const_int 0))
3114 (label_ref (match_operand 0 "" ""))
3115 (pc)))]
3116 ""
3117 "
3118 {
3119 operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1,
3120 arm_compare_fp);
3121 }
3122 ")
3123
3124 (define_expand "bgt"
3125 [(set (pc)
3126 (if_then_else (gt (match_dup 1) (const_int 0))
3127 (label_ref (match_operand 0 "" ""))
3128 (pc)))]
3129 ""
3130 "
3131 {
3132 operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1,
3133 arm_compare_fp);
3134 }
3135 ")
3136
3137 (define_expand "ble"
3138 [(set (pc)
3139 (if_then_else (le (match_dup 1) (const_int 0))
3140 (label_ref (match_operand 0 "" ""))
3141 (pc)))]
3142 ""
3143 "
3144 {
3145 operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1,
3146 arm_compare_fp);
3147 }
3148 ")
3149
3150 (define_expand "bge"
3151 [(set (pc)
3152 (if_then_else (ge (match_dup 1) (const_int 0))
3153 (label_ref (match_operand 0 "" ""))
3154 (pc)))]
3155 ""
3156 "
3157 {
3158 operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1,
3159 arm_compare_fp);
3160 }
3161 ")
3162
3163 (define_expand "blt"
3164 [(set (pc)
3165 (if_then_else (lt (match_dup 1) (const_int 0))
3166 (label_ref (match_operand 0 "" ""))
3167 (pc)))]
3168 ""
3169 "
3170 {
3171 operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1,
3172 arm_compare_fp);
3173 }
3174 ")
3175
3176 (define_expand "bgtu"
3177 [(set (pc)
3178 (if_then_else (gtu (match_dup 1) (const_int 0))
3179 (label_ref (match_operand 0 "" ""))
3180 (pc)))]
3181 ""
3182 "
3183 {
3184 operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1,
3185 arm_compare_fp);
3186 }
3187 ")
3188
3189 (define_expand "bleu"
3190 [(set (pc)
3191 (if_then_else (leu (match_dup 1) (const_int 0))
3192 (label_ref (match_operand 0 "" ""))
3193 (pc)))]
3194 ""
3195 "
3196 {
3197 operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1,
3198 arm_compare_fp);
3199 }
3200 ")
3201
3202 (define_expand "bgeu"
3203 [(set (pc)
3204 (if_then_else (geu (match_dup 1) (const_int 0))
3205 (label_ref (match_operand 0 "" ""))
3206 (pc)))]
3207 ""
3208 "
3209 {
3210 operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1,
3211 arm_compare_fp);
3212 }
3213 ")
3214
3215 (define_expand "bltu"
3216 [(set (pc)
3217 (if_then_else (ltu (match_dup 1) (const_int 0))
3218 (label_ref (match_operand 0 "" ""))
3219 (pc)))]
3220 ""
3221 "
3222 {
3223 operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1,
3224 arm_compare_fp);
3225 }
3226 ")
3227
3228 ;; patterns to match conditional branch insns
3229
3230 (define_insn "*condbranch"
3231 [(set (pc)
3232 (if_then_else (match_operator 1 "comparison_operator"
3233 [(reg 24) (const_int 0)])
3234 (label_ref (match_operand 0 "" ""))
3235 (pc)))]
3236 ""
3237 "*
3238 {
3239 extern int arm_ccfsm_state;
3240
3241 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3242 {
3243 arm_ccfsm_state += 2;
3244 return \"\";
3245 }
3246 return \"b%d1\\t%l0\";
3247 }"
3248 [(set_attr "conds" "use")])
3249
3250 (define_insn "*condbranch_reversed"
3251 [(set (pc)
3252 (if_then_else (match_operator 1 "comparison_operator"
3253 [(reg 24) (const_int 0)])
3254 (pc)
3255 (label_ref (match_operand 0 "" ""))))]
3256 "REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
3257 "*
3258 {
3259 extern int arm_ccfsm_state;
3260
3261 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3262 {
3263 arm_ccfsm_state += 2;
3264 return \"\";
3265 }
3266 return \"b%D1\\t%l0\";
3267 }"
3268 [(set_attr "conds" "use")])
3269 \f
3270
3271 ; scc insns
3272
3273 (define_expand "seq"
3274 [(set (match_operand:SI 0 "s_register_operand" "=r")
3275 (eq:SI (match_dup 1) (const_int 0)))]
3276 ""
3277 "
3278 {
3279 operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1,
3280 arm_compare_fp);
3281 }
3282 ")
3283
3284 (define_expand "sne"
3285 [(set (match_operand:SI 0 "s_register_operand" "=r")
3286 (ne:SI (match_dup 1) (const_int 0)))]
3287 ""
3288 "
3289 {
3290 operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1,
3291 arm_compare_fp);
3292 }
3293 ")
3294
3295 (define_expand "sgt"
3296 [(set (match_operand:SI 0 "s_register_operand" "=r")
3297 (gt:SI (match_dup 1) (const_int 0)))]
3298 ""
3299 "
3300 {
3301 operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1,
3302 arm_compare_fp);
3303 }
3304 ")
3305
3306 (define_expand "sle"
3307 [(set (match_operand:SI 0 "s_register_operand" "=r")
3308 (le:SI (match_dup 1) (const_int 0)))]
3309 ""
3310 "
3311 {
3312 operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1,
3313 arm_compare_fp);
3314 }
3315 ")
3316
3317 (define_expand "sge"
3318 [(set (match_operand:SI 0 "s_register_operand" "=r")
3319 (ge:SI (match_dup 1) (const_int 0)))]
3320 ""
3321 "
3322 {
3323 operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1,
3324 arm_compare_fp);
3325 }
3326 ")
3327
3328 (define_expand "slt"
3329 [(set (match_operand:SI 0 "s_register_operand" "=r")
3330 (lt:SI (match_dup 1) (const_int 0)))]
3331 ""
3332 "
3333 {
3334 operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1,
3335 arm_compare_fp);
3336 }
3337 ")
3338
3339 (define_expand "sgtu"
3340 [(set (match_operand:SI 0 "s_register_operand" "=r")
3341 (gtu:SI (match_dup 1) (const_int 0)))]
3342 ""
3343 "
3344 {
3345 operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1,
3346 arm_compare_fp);
3347 }
3348 ")
3349
3350 (define_expand "sleu"
3351 [(set (match_operand:SI 0 "s_register_operand" "=r")
3352 (leu:SI (match_dup 1) (const_int 0)))]
3353 ""
3354 "
3355 {
3356 operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1,
3357 arm_compare_fp);
3358 }
3359 ")
3360
3361 (define_expand "sgeu"
3362 [(set (match_operand:SI 0 "s_register_operand" "=r")
3363 (geu:SI (match_dup 1) (const_int 0)))]
3364 ""
3365 "
3366 {
3367 operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1,
3368 arm_compare_fp);
3369 }
3370 ")
3371
3372 (define_expand "sltu"
3373 [(set (match_operand:SI 0 "s_register_operand" "=r")
3374 (ltu:SI (match_dup 1) (const_int 0)))]
3375 ""
3376 "
3377 {
3378 operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1,
3379 arm_compare_fp);
3380 }
3381 ")
3382
3383 (define_insn "*mov_scc"
3384 [(set (match_operand:SI 0 "s_register_operand" "=r")
3385 (match_operator:SI 1 "comparison_operator" [(reg 24) (const_int 0)]))]
3386 ""
3387 "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
3388 [(set_attr "conds" "use")
3389 (set_attr "length" "8")])
3390
3391 (define_insn "*mov_negscc"
3392 [(set (match_operand:SI 0 "s_register_operand" "=r")
3393 (neg:SI (match_operator:SI 1 "comparison_operator"
3394 [(reg 24) (const_int 0)])))]
3395 ""
3396 "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
3397 [(set_attr "conds" "use")
3398 (set_attr "length" "8")])
3399
3400 (define_insn "*mov_notscc"
3401 [(set (match_operand:SI 0 "s_register_operand" "=r")
3402 (not:SI (match_operator:SI 1 "comparison_operator"
3403 [(reg 24) (const_int 0)])))]
3404 ""
3405 "mov%D1\\t%0, #0\;mvn%d1\\t%0, #1"
3406 [(set_attr "conds" "use")
3407 (set_attr "length" "8")])
3408
3409 \f
3410 ;; Conditional move insns
3411
3412 (define_expand "movsicc"
3413 [(set (match_operand:SI 0 "register_operand" "")
3414 (if_then_else (match_operand 1 "comparison_operator" "")
3415 (match_operand:SI 2 "arm_not_operand" "")
3416 (match_operand:SI 3 "register_operand" "")))]
3417 ""
3418 "
3419 {
3420 enum rtx_code code = GET_CODE (operands[1]);
3421 rtx ccreg = gen_compare_reg (code, arm_compare_op0, arm_compare_op1,
3422 arm_compare_fp);
3423
3424 operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx);
3425 }")
3426
3427 (define_expand "movsfcc"
3428 [(set (match_operand:SF 0 "register_operand" "")
3429 (if_then_else (match_operand 1 "comparison_operator" "")
3430 (match_operand:SF 2 "nonmemory_operand" "")
3431 (match_operand:SF 3 "register_operand" "")))]
3432 ""
3433 "
3434 {
3435 enum rtx_code code = GET_CODE (operands[1]);
3436 rtx ccreg = gen_compare_reg (code, arm_compare_op0, arm_compare_op1,
3437 arm_compare_fp);
3438
3439 operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx);
3440 }")
3441
3442 (define_expand "movdfcc"
3443 [(set (match_operand:DF 0 "register_operand" "")
3444 (if_then_else (match_operand 1 "comparison_operator" "")
3445 (match_operand:DF 2 "nonmemory_operand" "")
3446 (match_operand:DF 3 "register_operand" "")))]
3447 "TARGET_HARD_FLOAT"
3448 "
3449 {
3450 enum rtx_code code = GET_CODE (operands[1]);
3451 rtx ccreg = gen_compare_reg (code, arm_compare_op0, arm_compare_op1,
3452 arm_compare_fp);
3453
3454 operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx);
3455 }")
3456
3457 (define_insn "*movsicc_insn"
3458 [(set (match_operand:SI 0 "register_operand" "=r,r")
3459 (if_then_else (match_operator 1 "comparison_operator"
3460 [(reg 24) (const_int 0)])
3461 (match_operand:SI 2 "arm_not_operand" "rI,K")
3462 (match_operand:SI 3 "register_operand" "0,0")))]
3463 ""
3464 "@
3465 mov%d1\\t%0, %2
3466 mvn%d1\\t%0, #%B2"
3467 [(set_attr "type" "*,*")
3468 (set_attr "conds" "use,use")])
3469
3470 (define_insn "*movsfcc_hard_insn"
3471 [(set (match_operand:SF 0 "register_operand" "=f")
3472 (if_then_else (match_operator 1 "comparison_operator"
3473 [(reg 24) (const_int 0)])
3474 (match_operand:SF 2 "register_operand" "f")
3475 (match_operand:SF 3 "register_operand" "0")))]
3476 "TARGET_HARD_FLOAT"
3477 "mvf%d1s\\t%0, %2"
3478 [(set_attr "type" "ffarith")
3479 (set_attr "conds" "use")])
3480
3481 (define_insn "*movsfcc_soft_insn"
3482 [(set (match_operand:SF 0 "register_operand" "=r")
3483 (if_then_else (match_operator 1 "comparison_operator"
3484 [(reg 24) (const_int 0)])
3485 (match_operand:SF 2 "register_operand" "r")
3486 (match_operand:SF 3 "register_operand" "0")))]
3487 "TARGET_SOFT_FLOAT"
3488 "mov%d1\\t%0, %2"
3489 [(set_attr "type" "*")
3490 (set_attr "conds" "use")])
3491
3492 (define_insn "*movdfcc_insn"
3493 [(set (match_operand:DF 0 "register_operand" "=f")
3494 (if_then_else (match_operator 1 "comparison_operator"
3495 [(reg 24) (const_int 0)])
3496 (match_operand:DF 2 "register_operand" "f")
3497 (match_operand:DF 3 "register_operand" "0")))]
3498 "TARGET_HARD_FLOAT"
3499 "mvf%d1d\\t%0, %2"
3500 [(set_attr "type" "ffarith")
3501 (set_attr "conds" "use")])
3502 \f
3503 ;; Jump and linkage insns
3504
3505 (define_insn "jump"
3506 [(set (pc)
3507 (label_ref (match_operand 0 "" "")))]
3508 ""
3509 "*
3510 {
3511 extern int arm_ccfsm_state;
3512
3513 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3514 {
3515 arm_ccfsm_state += 2;
3516 return \"\";
3517 }
3518 return \"b%?\\t%l0\";
3519 }")
3520
3521 (define_expand "call"
3522 [(parallel [(call (match_operand 0 "memory_operand" "")
3523 (match_operand 1 "general_operand" ""))
3524 (clobber (reg:SI 14))])]
3525 ""
3526 "")
3527
3528 (define_insn "*call_reg"
3529 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
3530 (match_operand 1 "" "g"))
3531 (clobber (reg:SI 14))]
3532 ""
3533 "*
3534 return output_call (operands);
3535 "
3536 ;; length is worst case, normally it is only two
3537 [(set_attr "length" "12")
3538 (set_attr "type" "call")])
3539
3540 (define_insn "*call_mem"
3541 [(call (mem:SI (match_operand 0 "memory_operand" "m"))
3542 (match_operand 1 "general_operand" "g"))
3543 (clobber (reg:SI 14))]
3544 ""
3545 "*
3546 return output_call_mem (operands);
3547 "
3548 [(set_attr "length" "12")
3549 (set_attr "type" "call")])
3550
3551 (define_expand "call_value"
3552 [(parallel [(set (match_operand 0 "" "=rf")
3553 (call (match_operand 1 "memory_operand" "m")
3554 (match_operand 2 "general_operand" "g")))
3555 (clobber (reg:SI 14))])]
3556 ""
3557 "")
3558
3559 (define_insn "*call_value_reg"
3560 [(set (match_operand 0 "" "=rf")
3561 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
3562 (match_operand 2 "general_operand" "g")))
3563 (clobber (reg:SI 14))]
3564 ""
3565 "*
3566 return output_call (&operands[1]);
3567 "
3568 [(set_attr "length" "12")
3569 (set_attr "type" "call")])
3570
3571 (define_insn "*call_value_mem"
3572 [(set (match_operand 0 "" "=rf")
3573 (call (mem:SI (match_operand 1 "memory_operand" "m"))
3574 (match_operand 2 "general_operand" "g")))
3575 (clobber (reg:SI 14))]
3576 "! CONSTANT_ADDRESS_P (XEXP (operands[1], 0))"
3577 "*
3578 return output_call_mem (&operands[1]);
3579 "
3580 [(set_attr "length" "12")
3581 (set_attr "type" "call")])
3582
3583 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
3584 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
3585
3586 (define_insn "*call_symbol"
3587 [(call (mem:SI (match_operand:SI 0 "" "X"))
3588 (match_operand:SI 1 "general_operand" "g"))
3589 (clobber (reg:SI 14))]
3590 "GET_CODE (operands[0]) == SYMBOL_REF"
3591 "bl%?\\t%a0"
3592 [(set_attr "type" "call")])
3593
3594 (define_insn "*call_value_symbol"
3595 [(set (match_operand 0 "s_register_operand" "=rf")
3596 (call (mem:SI (match_operand:SI 1 "" "X"))
3597 (match_operand:SI 2 "general_operand" "g")))
3598 (clobber (reg:SI 14))]
3599 "GET_CODE(operands[1]) == SYMBOL_REF"
3600 "bl%?\\t%a1"
3601 [(set_attr "type" "call")])
3602
3603 ;; Often the return insn will be the same as loading from memory, so set attr
3604 (define_insn "return"
3605 [(return)]
3606 "USE_RETURN_INSN"
3607 "*
3608 {
3609 extern int arm_ccfsm_state;
3610
3611 if (arm_ccfsm_state == 2)
3612 {
3613 arm_ccfsm_state += 2;
3614 return \"\";
3615 }
3616 return output_return_instruction (NULL, TRUE);
3617 }"
3618 [(set_attr "type" "load")])
3619
3620 (define_insn "*cond_return"
3621 [(set (pc)
3622 (if_then_else (match_operator 0 "comparison_operator"
3623 [(reg 24) (const_int 0)])
3624 (return)
3625 (pc)))]
3626 "USE_RETURN_INSN"
3627 "*
3628 {
3629 extern int arm_ccfsm_state;
3630
3631 if (arm_ccfsm_state == 2)
3632 {
3633 arm_ccfsm_state += 2;
3634 return \"\";
3635 }
3636 return output_return_instruction (operands[0], TRUE);
3637 }"
3638 [(set_attr "conds" "use")
3639 (set_attr "type" "load")])
3640
3641 (define_insn "*cond_return_inverted"
3642 [(set (pc)
3643 (if_then_else (match_operator 0 "comparison_operator"
3644 [(reg 24) (const_int 0)])
3645 (pc)
3646 (return)))]
3647 "USE_RETURN_INSN"
3648 "*
3649 {
3650 extern int arm_ccfsm_state;
3651
3652 if (arm_ccfsm_state == 2)
3653 {
3654 arm_ccfsm_state += 2;
3655 return \"\";
3656 }
3657 return output_return_instruction
3658 (gen_rtx (reverse_condition (GET_CODE (operands[0])),
3659 GET_MODE (operands[0]), XEXP (operands[0], 0),
3660 XEXP (operands[0], 1)),
3661 TRUE);
3662 }"
3663 [(set_attr "conds" "use")
3664 (set_attr "type" "load")])
3665
3666 ;; Call subroutine returning any type.
3667
3668 (define_expand "untyped_call"
3669 [(parallel [(call (match_operand 0 "" "")
3670 (const_int 0))
3671 (match_operand 1 "" "")
3672 (match_operand 2 "" "")])]
3673 ""
3674 "
3675 {
3676 int i;
3677
3678 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
3679
3680 for (i = 0; i < XVECLEN (operands[2], 0); i++)
3681 {
3682 rtx set = XVECEXP (operands[2], 0, i);
3683 emit_move_insn (SET_DEST (set), SET_SRC (set));
3684 }
3685
3686 /* The optimizer does not know that the call sets the function value
3687 registers we stored in the result block. We avoid problems by
3688 claiming that all hard registers are used and clobbered at this
3689 point. */
3690 emit_insn (gen_blockage ());
3691
3692 DONE;
3693 }")
3694
3695 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
3696 ;; all of memory. This blocks insns from being moved across this point.
3697
3698 (define_insn "blockage"
3699 [(unspec_volatile [(const_int 0)] 0)]
3700 ""
3701 ""
3702 [(set_attr "length" "0")
3703 (set_attr "type" "block")])
3704
3705 (define_expand "casesi"
3706 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
3707 (match_operand:SI 1 "immediate_operand" "") ; lower bound
3708 (match_operand:SI 2 "immediate_operand" "") ; total range
3709 (match_operand:SI 3 "" "") ; table label
3710 (match_operand:SI 4 "" "")] ; Out of range label
3711 ""
3712 "
3713 {
3714 rtx reg;
3715 if (operands[1] != const0_rtx)
3716 {
3717 reg = gen_reg_rtx (SImode);
3718 emit_insn (gen_addsi3 (reg, operands[0],
3719 GEN_INT (-INTVAL (operands[1]))));
3720 operands[0] = reg;
3721 }
3722
3723 if (! const_ok_for_arm (INTVAL (operands[2])))
3724 operands[2] = force_reg (SImode, operands[2]);
3725
3726 emit_jump_insn (gen_casesi_internal (operands[0], operands[2], operands[3],
3727 operands[4]));
3728 DONE;
3729 }")
3730
3731 (define_insn "casesi_internal"
3732 [(set (pc)
3733 (if_then_else
3734 (leu (match_operand:SI 0 "s_register_operand" "r")
3735 (match_operand:SI 1 "arm_rhs_operand" "rI"))
3736 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
3737 (label_ref (match_operand 2 "" ""))))
3738 (label_ref (match_operand 3 "" ""))))]
3739 ""
3740 "*
3741 if (flag_pic)
3742 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
3743 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
3744 "
3745 [(set_attr "conds" "clob")
3746 (set_attr "length" "12")])
3747
3748 (define_insn "indirect_jump"
3749 [(set (pc)
3750 (match_operand:SI 0 "s_register_operand" "r"))]
3751 ""
3752 "mov%?\\t%|pc, %0\\t%@ indirect jump")
3753
3754 (define_insn "*load_indirect_jump"
3755 [(set (pc)
3756 (match_operand:SI 0 "memory_operand" "m"))]
3757 ""
3758 "ldr%?\\t%|pc, %0\\t%@ indirect jump"
3759 [(set_attr "type" "load")])
3760 \f
3761 ;; Misc insns
3762
3763 (define_insn "nop"
3764 [(const_int 0)]
3765 ""
3766 "mov%?\\tr0, r0\\t%@ nop")
3767 \f
3768 ;; Patterns to allow combination of arithmetic, cond code and shifts
3769
3770 (define_insn "*arith_shiftsi"
3771 [(set (match_operand:SI 0 "s_register_operand" "=r")
3772 (match_operator:SI 1 "shiftable_operator"
3773 [(match_operator:SI 3 "shift_operator"
3774 [(match_operand:SI 4 "s_register_operand" "r")
3775 (match_operand:SI 5 "reg_or_int_operand" "rI")])
3776 (match_operand:SI 2 "s_register_operand" "r")]))]
3777 ""
3778 "%i1%?\\t%0, %2, %4%S3")
3779
3780 (define_insn "*arith_shiftsi_compare0"
3781 [(set (reg:CC_NOOV 24)
3782 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
3783 [(match_operator:SI 3 "shift_operator"
3784 [(match_operand:SI 4 "s_register_operand" "r")
3785 (match_operand:SI 5 "reg_or_int_operand" "rI")])
3786 (match_operand:SI 2 "s_register_operand" "r")])
3787 (const_int 0)))
3788 (set (match_operand:SI 0 "s_register_operand" "=r")
3789 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
3790 (match_dup 2)]))]
3791 ""
3792 "%i1%?s\\t%0, %2, %4%S3"
3793 [(set_attr "conds" "set")])
3794
3795 (define_insn "*arith_shiftsi_compare0_scratch"
3796 [(set (reg:CC_NOOV 24)
3797 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
3798 [(match_operator:SI 3 "shift_operator"
3799 [(match_operand:SI 4 "s_register_operand" "r")
3800 (match_operand:SI 5 "reg_or_int_operand" "rI")])
3801 (match_operand:SI 2 "s_register_operand" "r")])
3802 (const_int 0)))
3803 (clobber (match_scratch:SI 0 "=r"))]
3804 ""
3805 "%i1%?s\\t%0, %2, %4%S3"
3806 [(set_attr "conds" "set")])
3807
3808 (define_insn "*sub_shiftsi"
3809 [(set (match_operand:SI 0 "s_register_operand" "=r")
3810 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
3811 (match_operator:SI 2 "shift_operator"
3812 [(match_operand:SI 3 "s_register_operand" "r")
3813 (match_operand:SI 4 "reg_or_int_operand" "rM")])))]
3814 ""
3815 "sub%?\\t%0, %1, %3%S2")
3816
3817 (define_insn "*sub_shiftsi_compare0"
3818 [(set (reg:CC_NOOV 24)
3819 (compare:CC_NOOV
3820 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
3821 (match_operator:SI 2 "shift_operator"
3822 [(match_operand:SI 3 "s_register_operand" "r")
3823 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
3824 (const_int 0)))
3825 (set (match_operand:SI 0 "s_register_operand" "=r")
3826 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
3827 (match_dup 4)])))]
3828 ""
3829 "sub%?s\\t%0, %1, %3%S2"
3830 [(set_attr "conds" "set")])
3831
3832 (define_insn "*sub_shiftsi_compare0_scratch"
3833 [(set (reg:CC_NOOV 24)
3834 (compare:CC_NOOV
3835 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
3836 (match_operator:SI 2 "shift_operator"
3837 [(match_operand:SI 3 "s_register_operand" "r")
3838 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
3839 (const_int 0)))
3840 (clobber (match_scratch:SI 0 "=r"))]
3841 ""
3842 "sub%?s\\t%0, %1, %3%S2"
3843 [(set_attr "conds" "set")])
3844
3845 ;; These variants of the above insns can occur if the first operand is the
3846 ;; frame pointer and we eliminate that. This is a kludge, but there doesn't
3847 ;; seem to be a way around it. Most of the predicates have to be null
3848 ;; because the format can be generated part way through reload, so
3849 ;; if we don't match it as soon as it becomes available, reload doesn't know
3850 ;; how to reload pseudos that haven't got hard registers; the constraints will
3851 ;; sort everything out.
3852
3853 (define_insn "*reload_mulsi3"
3854 [(set (match_operand:SI 0 "" "=&r")
3855 (plus:SI (plus:SI (match_operator:SI 5 "shift_operator"
3856 [(match_operand:SI 3 "" "r")
3857 (match_operand:SI 4 "" "rM")])
3858 (match_operand:SI 2 "" "r"))
3859 (match_operand:SI 1 "const_int_operand" "n")))]
3860 "reload_in_progress"
3861 "*
3862 output_asm_insn (\"add%?\\t%0, %2, %3%S5\", operands);
3863 operands[2] = operands[1];
3864 operands[1] = operands[0];
3865 return output_add_immediate (operands);
3866 "
3867 ; we have no idea how long the add_immediate is, it could be up to 4.
3868 [(set_attr "length" "20")])
3869
3870 (define_insn "*relaod_mulsi_compare0"
3871 [(set (reg:CC_NOOV 24)
3872 (compare:CC_NOOV (plus:SI
3873 (plus:SI
3874 (match_operator:SI 5 "shift_operator"
3875 [(match_operand:SI 3 "" "r")
3876 (match_operand:SI 4 "" "rM")])
3877 (match_operand:SI 1 "" "r"))
3878 (match_operand:SI 2 "const_int_operand" "n"))
3879 (const_int 0)))
3880 (set (match_operand:SI 0 "" "=&r")
3881 (plus:SI (plus:SI (match_op_dup 5 [(match_dup 3) (match_dup 4)])
3882 (match_dup 1))
3883 (match_dup 2)))]
3884 "reload_in_progress"
3885 "*
3886 output_add_immediate (operands);
3887 return \"add%?s\\t%0, %0, %3%S5\";
3888 "
3889 [(set_attr "conds" "set")
3890 (set_attr "length" "20")])
3891
3892 (define_insn "*reload_mulsi_compare0_scratch"
3893 [(set (reg:CC_NOOV 24)
3894 (compare:CC_NOOV (plus:SI
3895 (plus:SI
3896 (match_operator:SI 5 "shift_operator"
3897 [(match_operand:SI 3 "" "r")
3898 (match_operand:SI 4 "" "rM")])
3899 (match_operand:SI 1 "" "r"))
3900 (match_operand:SI 2 "const_int_operand" "n"))
3901 (const_int 0)))
3902 (clobber (match_scratch:SI 0 "=&r"))]
3903 "reload_in_progress"
3904 "*
3905 output_add_immediate (operands);
3906 return \"add%?s\\t%0, %0, %3%S5\";
3907 "
3908 [(set_attr "conds" "set")
3909 (set_attr "length" "20")])
3910
3911 ;; These are similar, but are needed when the mla pattern contains the
3912 ;; eliminated register as operand 3.
3913
3914 (define_insn "*reload_muladdsi"
3915 [(set (match_operand:SI 0 "" "=&r,&r")
3916 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "" "%0,r")
3917 (match_operand:SI 2 "" "r,r"))
3918 (match_operand:SI 3 "" "r,r"))
3919 (match_operand:SI 4 "const_int_operand" "n,n")))]
3920 "reload_in_progress"
3921 "*
3922 output_asm_insn (\"mla%?\\t%0, %2, %1, %3\", operands);
3923 operands[2] = operands[4];
3924 operands[1] = operands[0];
3925 return output_add_immediate (operands);
3926 "
3927 [(set_attr "length" "20")
3928 (set_attr "type" "mult")])
3929
3930 (define_insn "*reload_muladdsi_compare0"
3931 [(set (reg:CC_NOOV 24)
3932 (compare:CC_NOOV (plus:SI (plus:SI (mult:SI
3933 (match_operand:SI 3 "" "r")
3934 (match_operand:SI 4 "" "r"))
3935 (match_operand:SI 1 "" "r"))
3936 (match_operand:SI 2 "const_int_operand" "n"))
3937 (const_int 0)))
3938 (set (match_operand:SI 0 "" "=&r")
3939 (plus:SI (plus:SI (mult:SI (match_dup 3) (match_dup 4)) (match_dup 1))
3940 (match_dup 2)))]
3941 "reload_in_progress"
3942 "*
3943 output_add_immediate (operands);
3944 output_asm_insn (\"mla%?s\\t%0, %3, %4, %0\", operands);
3945 return \"\";
3946 "
3947 [(set_attr "length" "20")
3948 (set_attr "conds" "set")
3949 (set_attr "type" "mult")])
3950
3951 (define_insn "*reload_muladdsi_compare0_scratch"
3952 [(set (reg:CC_NOOV 24)
3953 (compare:CC_NOOV (plus:SI (plus:SI (mult:SI
3954 (match_operand:SI 3 "" "r")
3955 (match_operand:SI 4 "" "r"))
3956 (match_operand:SI 1 "" "r"))
3957 (match_operand:SI 2 "const_int_operand" "n"))
3958 (const_int 0)))
3959 (clobber (match_scratch:SI 0 "=&r"))]
3960 "reload_in_progress"
3961 "*
3962 output_add_immediate (operands);
3963 return \"mla%?s\\t%0, %3, %4, %0\";
3964 "
3965 [(set_attr "length" "20")
3966 (set_attr "conds" "set")
3967 (set_attr "type" "mult")])
3968
3969 \f
3970
3971 (define_insn "*and_scc"
3972 [(set (match_operand:SI 0 "s_register_operand" "=r")
3973 (and:SI (match_operator 1 "comparison_operator"
3974 [(match_operand 3 "reversible_cc_register" "") (const_int 0)])
3975 (match_operand:SI 2 "s_register_operand" "r")))]
3976 ""
3977 "mov%D1\\t%0, #0\;and%d1\\t%0, %2, #1"
3978 [(set_attr "conds" "use")
3979 (set_attr "length" "8")])
3980
3981 (define_insn "*ior_scc"
3982 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3983 (ior:SI (match_operator 2 "comparison_operator"
3984 [(reg 24) (const_int 0)])
3985 (match_operand:SI 1 "s_register_operand" "0,?r")))]
3986 ""
3987 "@
3988 orr%d2\\t%0, %1, #1
3989 mov%D2\\t%0, %1\;orr%d2\\t%0, %1, #1"
3990 [(set_attr "conds" "use")
3991 (set_attr "length" "4,8")])
3992
3993 (define_insn "*compare_scc"
3994 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3995 (match_operator 1 "comparison_operator"
3996 [(match_operand:SI 2 "s_register_operand" "r,r")
3997 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
3998 (clobber (reg 24))]
3999 ""
4000 "*
4001 if (GET_CODE (operands[1]) == LT && operands[3] == const0_rtx)
4002 return \"mov\\t%0, %2, lsr #31\";
4003
4004 if (GET_CODE (operands[1]) == GE && operands[3] == const0_rtx)
4005 return \"mvn\\t%0, %2\;mov\\t%0, %0, lsr #31\";
4006
4007 if (GET_CODE (operands[1]) == NE)
4008 {
4009 if (which_alternative == 1)
4010 return \"adds\\t%0, %2, #%n3\;movne\\t%0, #1\";
4011 return \"subs\\t%0, %2, %3\;movne\\t%0, #1\";
4012 }
4013 if (which_alternative == 1)
4014 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
4015 else
4016 output_asm_insn (\"cmp\\t%2, %3\", operands);
4017 return \"mov%D1\\t%0, #0\;mov%d1\\t%0, #1\";
4018 "
4019 [(set_attr "conds" "clob")
4020 (set_attr "length" "12")])
4021
4022 (define_insn "*ior_compare_compare"
4023 [(set (match_operand:SI 0 "s_register_operand" "=&r")
4024 (ior:SI (match_operator 1 "comparison_operator"
4025 [(match_operand:SI 2 "s_register_operand" "r")
4026 (match_operand:SI 3 "arm_rhs_operand" "rI")])
4027 (match_operator 4 "comparison_operator"
4028 [(match_operand:SI 5 "s_register_operand" "r")
4029 (match_operand:SI 6 "arm_rhs_operand" "rI")])))
4030 (clobber (reg 24))]
4031 ""
4032 "*
4033 {
4034 int dominant = comparison_dominates_p (GET_CODE (operands[4]),
4035 GET_CODE (operands[1]));
4036
4037 output_asm_insn (dominant ? \"cmp\\t%5, %6\" : \"cmp\\t%2, %3\",
4038 operands);
4039 output_asm_insn (\"mov\\t%0, #0\", operands);
4040 if (GET_CODE (operands[1]) == GET_CODE (operands[4])
4041 || comparison_dominates_p (GET_CODE (operands[1]),
4042 GET_CODE (operands[4]))
4043 || dominant)
4044 output_asm_insn (dominant ? \"cmp%D4\\t%2, %3\" : \"cmp%D1\\t%5,%6\",
4045 operands);
4046 else
4047 output_asm_insn (\"mov%d1\\t%0, #1\;cmp\\t%5, %6\", operands);
4048 return dominant ? \"mov%d1\\t%0, #1\" : \"mov%d4\\t%0, #1\";
4049 }
4050 "
4051 [(set_attr "conds" "clob")
4052 ; worst case length
4053 (set_attr "length" "20")])
4054
4055 (define_split
4056 [(set (pc)
4057 (if_then_else
4058 (match_operator 5 "equality_operator"
4059 [(ior:SI (match_operator 6 "comparison_operator"
4060 [(match_operand:SI 0 "s_register_operand" "")
4061 (match_operand:SI 1 "arm_add_operand" "")])
4062 (match_operator 7 "comparison_operator"
4063 [(match_operand:SI 2 "s_register_operand" "")
4064 (match_operand:SI 3 "arm_add_operand" "")]))
4065 (const_int 0)])
4066 (label_ref (match_operand 4 "" ""))
4067 (pc)))
4068 (clobber (reg 24))]
4069 "(GET_CODE (operands[6]) == GET_CODE (operands[7])
4070 || comparison_dominates_p (GET_CODE (operands[6]), GET_CODE (operands[7]))
4071 || comparison_dominates_p (GET_CODE (operands[7]), GET_CODE (operands[6])))"
4072 [(set (reg:CC 24)
4073 (compare:CC (ior:CC (match_op_dup 6
4074 [(match_dup 0) (match_dup 1)])
4075 (match_op_dup 7
4076 [(match_dup 2) (match_dup 3)]))
4077 (const_int 0)))
4078 (set (pc)
4079 (if_then_else (match_op_dup 5 [(reg:CC 24) (const_int 0)])
4080 (label_ref (match_dup 4))
4081 (pc)))]
4082 "
4083 {
4084 enum rtx_code code = comparison_dominates_p (GET_CODE (operands[6]),
4085 GET_CODE (operands[7]))
4086 ? GET_CODE (operands[7]) : GET_CODE (operands[6]);
4087
4088 if (GET_CODE (operands[5]) == NE)
4089 operands[5] = gen_rtx (code, CCmode,
4090 XEXP (operands[5], 0), XEXP (operands[5], 1));
4091 else
4092 operands[5] = gen_rtx (reverse_condition (code), CCmode,
4093 XEXP (operands[5], 0), XEXP (operands[5], 1));
4094 }
4095 ")
4096
4097 ;; Don't match these patterns if we can use a conditional compare, since they
4098 ;; tell the final prescan branch eliminator code that full branch inlining
4099 ;; can't be done.
4100
4101 (define_insn "*impossible_cond_compare"
4102 [(set (pc)
4103 (if_then_else
4104 (ne (ior:SI (match_operator 5 "comparison_operator"
4105 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
4106 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
4107 (match_operator 6 "comparison_operator"
4108 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
4109 (match_operand:SI 3 "arm_rhs_operand" "rI,rI,L,L")]))
4110 (const_int 0))
4111 (label_ref (match_operand 4 "" ""))
4112 (pc)))
4113 (clobber (reg 24))]
4114 "!(GET_CODE (operands[5]) == GET_CODE (operands[6])
4115 || comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[6]))
4116 || comparison_dominates_p (GET_CODE (operands[6]), GET_CODE (operands[5])))"
4117 "*
4118 {
4119 extern int arm_ccfsm_state;
4120
4121 if (which_alternative & 1)
4122 output_asm_insn (\"cmn\\t%0, #%n1\;b%d5\\t%l4\", operands);
4123 else
4124 output_asm_insn (\"cmp\\t%0, %1\;b%d5\\t%l4\", operands);
4125
4126 if (which_alternative >= 2)
4127 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
4128 else
4129 output_asm_insn (\"cmp\\t%2, %3\", operands);
4130
4131 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
4132 {
4133 arm_ccfsm_state += 2;
4134 return \"\";
4135 }
4136 return \"b%d6\\t%l4\";
4137 }"
4138 [(set_attr "conds" "jump_clob")
4139 (set_attr "length" "16")])
4140
4141 (define_insn "*condition_compare_ior"
4142 [(set (reg:CC 24)
4143 (compare:CC
4144 (ior:CC (match_operator 4 "comparison_operator"
4145 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
4146 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
4147 (match_operator 5 "comparison_operator"
4148 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
4149 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")]))
4150 (const_int 0)))]
4151 "(GET_CODE (operands[4]) == GET_CODE (operands[5])
4152 || comparison_dominates_p (GET_CODE (operands[4]), GET_CODE (operands[5]))
4153 || comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])))"
4154 "*
4155 if (comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])))
4156 {
4157 if (which_alternative >= 2)
4158 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
4159 else
4160 output_asm_insn (\"cmp\\t%2, %3\", operands);
4161
4162 if (which_alternative & 1)
4163 return \"cmn%D5\\t%0, #%n1\";
4164 return \"cmp%D5\\t%0, %1\";
4165 }
4166
4167 if (which_alternative & 1)
4168 output_asm_insn (\"cmn\\t%0, #%n1\", operands);
4169 else
4170 output_asm_insn (\"cmp\\t%0, %1\", operands);
4171
4172 if (which_alternative >= 2)
4173 return \"cmn%D4\\t%2, #%n3\";
4174 return \"cmp%D4\\t%2, %3\";
4175 "
4176 [(set_attr "conds" "set")
4177 (set_attr "length" "8")])
4178
4179 (define_insn "*cond_move"
4180 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
4181 (if_then_else (match_operator 3 "equality_operator"
4182 [(match_operator 4 "comparison_operator"
4183 [(reg 24) (const_int 0)])
4184 (const_int 0)])
4185 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
4186 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
4187 ""
4188 "*
4189 if (GET_CODE (operands[3]) == NE)
4190 {
4191 if (which_alternative != 1)
4192 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
4193 if (which_alternative != 0)
4194 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
4195 return \"\";
4196 }
4197 if (which_alternative != 0)
4198 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
4199 if (which_alternative != 1)
4200 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
4201 return \"\";
4202 "
4203 [(set_attr "conds" "use")
4204 (set_attr "length" "4,4,8")])
4205
4206 (define_insn "*cond_arith"
4207 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4208 (match_operator:SI 5 "shiftable_operator"
4209 [(match_operator:SI 4 "comparison_operator"
4210 [(match_operand:SI 2 "s_register_operand" "r,r")
4211 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
4212 (match_operand:SI 1 "s_register_operand" "0,?r")]))
4213 (clobber (reg 24))]
4214 ""
4215 "*
4216 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
4217 return \"%i5\\t%0, %1, %2, lsr #31\";
4218
4219 output_asm_insn (\"cmp\\t%2, %3\", operands);
4220 if (GET_CODE (operands[5]) == AND)
4221 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
4222 else if (GET_CODE (operands[5]) == MINUS)
4223 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
4224 else if (which_alternative != 0)
4225 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
4226 return \"%i5%d4\\t%0, %1, #1\";
4227 "
4228 [(set_attr "conds" "clob")
4229 (set_attr "length" "12")])
4230
4231 (define_insn "*cond_sub"
4232 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4233 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
4234 (match_operator:SI 4 "comparison_operator"
4235 [(match_operand:SI 2 "s_register_operand" "r,r")
4236 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
4237 (clobber (reg 24))]
4238 ""
4239 "*
4240 output_asm_insn (\"cmp\\t%2, %3\", operands);
4241 if (which_alternative != 0)
4242 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
4243 return \"sub%d4\\t%0, %1, #1\";
4244 "
4245 [(set_attr "conds" "clob")
4246 (set_attr "length" "8,12")])
4247
4248 (define_insn "*and_scc_scc"
4249 [(set (match_operand:SI 0 "s_register_operand" "=&r")
4250 (and:SI (match_operator 1 "comparison_operator"
4251 [(match_operand:SI 2 "s_register_operand" "r")
4252 (match_operand:SI 3 "arm_rhs_operand" "rI")])
4253 (match_operator 4 "comparison_operator"
4254 [(match_operand:SI 5 "s_register_operand" "r")
4255 (match_operand:SI 6 "arm_rhs_operand" "rI")])))
4256 (clobber (reg 24))]
4257 ""
4258 "*
4259 {
4260 int dominant =
4261 comparison_dominates_p (reverse_condition (GET_CODE (operands[1])),
4262 reverse_condition (GET_CODE (operands[4])))
4263 ? 1
4264 : comparison_dominates_p (reverse_condition (GET_CODE (operands[4])),
4265 reverse_condition (GET_CODE (operands[1])))
4266 ? 2 : 0;
4267 output_asm_insn (dominant == 2 ? \"cmp\\t%5, %6\" : \"cmp\\t%2, %3\",
4268 operands);
4269 output_asm_insn (\"mov\\t%0, #1\", operands);
4270 if (GET_CODE (operands[1]) == GET_CODE (operands[4]) || dominant)
4271 {
4272 output_asm_insn (dominant == 2 ? \"cmp%d4\\t%2, %3\"
4273 : \"cmp%d1\\t%5, %6\", operands);
4274 }
4275 else
4276 {
4277 output_asm_insn (\"mov%D1\\t%0, #0\", operands);
4278 output_asm_insn (\"cmp\\t%5, %6\", operands);
4279 }
4280 return dominant == 2 ? \"mov%D1\\t%0, #0\" : \"mov%D4\\t%0, #0\";
4281 }
4282 "
4283 [(set_attr "conds" "clob")
4284 (set_attr "length" "20")])
4285
4286 (define_split
4287 [(set (pc)
4288 (if_then_else (match_operator 1 "equality_operator"
4289 [(and:SI (match_operator 2 "comparison_operator"
4290 [(match_operand:SI 3 "s_register_operand" "")
4291 (match_operand:SI 4 "arm_add_operand" "")])
4292 (match_operator 0 "comparison_operator"
4293 [(match_operand:SI 5 "s_register_operand" "")
4294 (match_operand:SI 6 "arm_add_operand" "")]))
4295 (const_int 0)])
4296 (label_ref (match_operand 7 "" ""))
4297 (pc)))
4298 (clobber (reg 24))]
4299 "(GET_CODE (operands[2]) == GET_CODE (operands[0])
4300 || comparison_dominates_p (reverse_condition (GET_CODE (operands[2])),
4301 reverse_condition (GET_CODE (operands[0])))
4302 || comparison_dominates_p (reverse_condition (GET_CODE (operands[0])),
4303 reverse_condition (GET_CODE (operands[2]))))"
4304 [(set (reg:CC 24)
4305 (compare:CC (ior:CC (match_op_dup 2
4306 [(match_dup 3) (match_dup 4)])
4307 (match_op_dup 0
4308 [(match_dup 5) (match_dup 6)]))
4309 (const_int 0)))
4310 (set (pc)
4311 (if_then_else (match_op_dup 1 [(reg:CC 24) (const_int 0)])
4312 (label_ref (match_dup 7))
4313 (pc)))]
4314 "
4315 {
4316 /* Use DeMorgans law to convert this into an IOR of the inverse conditions
4317 This is safe since we only do it for integer comparisons. */
4318 enum rtx_code code =
4319 comparison_dominates_p (reverse_condition (GET_CODE (operands[2])),
4320 reverse_condition (GET_CODE (operands[0])))
4321 ? GET_CODE (operands[0]) : GET_CODE (operands[2]);
4322
4323 operands[2] = gen_rtx (reverse_condition (GET_CODE (operands[2])),
4324 GET_MODE (operands[2]), operands[3], operands[4]);
4325 operands[0] = gen_rtx (reverse_condition (GET_CODE (operands[0])),
4326 GET_MODE (operands[0]), operands[5], operands[6]);
4327 if (GET_CODE (operands[1]) == NE)
4328 operands[1] = gen_rtx (code, CCmode,
4329 XEXP (operands[1], 0), XEXP (operands[1], 1));
4330 else
4331 operands[1] = gen_rtx (reverse_condition (code), CCmode,
4332 XEXP (operands[1], 0), XEXP (operands[1], 1));
4333 }
4334 ")
4335
4336 ;; Don't match these patterns if we can use a conditional compare, since they
4337 ;; tell the final prescan branch eliminator code that full branch inlining
4338 ;; can't be done.
4339
4340 (define_insn "*impossible_cond_branch_and"
4341 [(set (pc)
4342 (if_then_else
4343 (eq (and:SI (match_operator 1 "comparison_operator"
4344 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
4345 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L")])
4346 (match_operator 4 "comparison_operator"
4347 [(match_operand:SI 5 "s_register_operand" "r,r,r,r")
4348 (match_operand:SI 6 "arm_rhs_operand" "rI,rI,L,L")]))
4349 (const_int 0))
4350 (label_ref (match_operand 0 "" ""))
4351 (pc)))
4352 (clobber (reg 24))]
4353 "!(GET_CODE (operands[1]) == GET_CODE (operands[4])
4354 || comparison_dominates_p (reverse_condition (GET_CODE (operands[1])),
4355 reverse_condition (GET_CODE (operands[4])))
4356 || comparison_dominates_p (reverse_condition (GET_CODE (operands[4])),
4357 reverse_condition (GET_CODE (operands[1]))))"
4358 "*
4359 {
4360 extern int arm_ccfsm_state;
4361
4362 if (which_alternative & 1)
4363 output_asm_insn (\"cmn\\t%2, #%n3\;b%D1\\t%l0\", operands);
4364 else
4365 output_asm_insn (\"cmp\\t%2, %3\;b%D1\\t%l0\", operands);
4366
4367 if (which_alternative >= 2)
4368 output_asm_insn (\"cmn\\t%5, #%n6\", operands);
4369 else
4370 output_asm_insn (\"cmp\\t%5, %6\", operands);
4371
4372 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
4373 {
4374 arm_ccfsm_state += 2;
4375 return \"\";
4376 }
4377 return \"b%D4\\t%l0\";
4378 }"
4379 [(set_attr "conds" "jump_clob")
4380 (set_attr "length" "16")])
4381
4382 (define_insn "*negscc"
4383 [(set (match_operand:SI 0 "s_register_operand" "=r")
4384 (neg:SI (match_operator 3 "comparison_operator"
4385 [(match_operand:SI 1 "s_register_operand" "r")
4386 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
4387 (clobber (reg 24))]
4388 ""
4389 "*
4390 if (GET_CODE (operands[3]) == LT && operands[3] == const0_rtx)
4391 return \"mov\\t%0, %1, asr #31\";
4392
4393 if (GET_CODE (operands[3]) == NE)
4394 return \"subs\\t%0, %1, %2\;mvnne\\t%0, #0\";
4395
4396 if (GET_CODE (operands[3]) == GT)
4397 return \"subs\\t%0, %1, %2\;mvnne\\t%0, %0, asr #31\";
4398
4399 output_asm_insn (\"cmp\\t%1, %2\", operands);
4400 output_asm_insn (\"mov%D3\\t%0, #0\", operands);
4401 return \"mvn%d3\\t%0, #0\";
4402 "
4403 [(set_attr "conds" "clob")
4404 (set_attr "length" "12")])
4405
4406 (define_insn "movcond"
4407 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
4408 (if_then_else:SI
4409 (match_operator 5 "comparison_operator"
4410 [(match_operand:SI 3 "s_register_operand" "r,r,r")
4411 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
4412 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
4413 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
4414 (clobber (reg 24))]
4415 ""
4416 "*
4417 if (GET_CODE (operands[5]) == LT
4418 && (operands[4] == const0_rtx))
4419 {
4420 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
4421 {
4422 if (operands[2] == const0_rtx)
4423 return \"and\\t%0, %1, %3, asr #31\";
4424 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
4425 }
4426 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
4427 {
4428 if (operands[1] == const0_rtx)
4429 return \"bic\\t%0, %2, %3, asr #31\";
4430 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
4431 }
4432 /* The only case that falls through to here is when both ops 1 & 2
4433 are constants */
4434 }
4435
4436 if (GET_CODE (operands[5]) == GE
4437 && (operands[4] == const0_rtx))
4438 {
4439 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
4440 {
4441 if (operands[2] == const0_rtx)
4442 return \"bic\\t%0, %1, %3, asr #31\";
4443 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
4444 }
4445 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
4446 {
4447 if (operands[1] == const0_rtx)
4448 return \"and\\t%0, %2, %3, asr #31\";
4449 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
4450 }
4451 /* The only case that falls through to here is when both ops 1 & 2
4452 are constants */
4453 }
4454 if (GET_CODE (operands[4]) == CONST_INT
4455 && !const_ok_for_arm (INTVAL (operands[4])))
4456 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
4457 else
4458 output_asm_insn (\"cmp\\t%3, %4\", operands);
4459 if (which_alternative != 0)
4460 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
4461 if (which_alternative != 1)
4462 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
4463 return \"\";
4464 "
4465 [(set_attr "conds" "clob")
4466 (set_attr "length" "8,8,12")])
4467
4468 (define_insn "*ifcompare_arith_arith"
4469 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4470 (if_then_else:SI (match_operator 9 "comparison_operator"
4471 [(match_operand:SI 5 "s_register_operand" "r,r")
4472 (match_operand:SI 6 "arm_add_operand" "rI,L")])
4473 (match_operator:SI 8 "shiftable_operator"
4474 [(match_operand:SI 1 "s_register_operand" "r,r")
4475 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")])
4476 (match_operator:SI 7 "shiftable_operator"
4477 [(match_operand:SI 3 "s_register_operand" "r,r")
4478 (match_operand:SI 4 "arm_rhs_operand" "rI,rI")])))
4479 (clobber (reg 24))]
4480 ""
4481 "@
4482 cmp\\t%5, %6\;%I8%d9\\t%0, %1, %2\;%I7%D9\\t%0, %3, %4
4483 cmn\\t%5, #%n6\;%I8%d9\\t%0, %1, %2\;%I7%D9\\t%0, %3, %4"
4484 [(set_attr "conds" "clob")
4485 (set_attr "length" "12")])
4486
4487 (define_insn "*ifcompare_arith_move"
4488 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4489 (if_then_else:SI (match_operator 6 "comparison_operator"
4490 [(match_operand:SI 2 "s_register_operand" "r,r")
4491 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
4492 (match_operator:SI 7 "shiftable_operator"
4493 [(match_operand:SI 4 "s_register_operand" "r,r")
4494 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
4495 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")))
4496 (clobber (reg 24))]
4497 ""
4498 "*
4499 /* If we have an operation where (op x 0) is the identity operation and
4500 the conditional operator is LT or GE and we are comparing against zero and
4501 everything is in registers then we can do this in two instructions */
4502 if (operands[3] == const0_rtx
4503 && GET_CODE (operands[7]) != AND
4504 && GET_CODE (operands[5]) == REG
4505 && GET_CODE (operands[1]) == REG
4506 && REGNO (operands[1]) == REGNO (operands[4])
4507 && REGNO (operands[4]) != REGNO (operands[0]))
4508 {
4509 if (GET_CODE (operands[6]) == LT)
4510 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
4511 else if (GET_CODE (operands[6]) == GE)
4512 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
4513 }
4514 if (GET_CODE (operands[3]) == CONST_INT
4515 && !const_ok_for_arm (INTVAL (operands[3])))
4516 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
4517 else
4518 output_asm_insn (\"cmp\\t%2, %3\", operands);
4519 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
4520 if (which_alternative != 0)
4521 {
4522 if (GET_CODE (operands[1]) == MEM)
4523 return \"ldr%D6\\t%0, %1\";
4524 else
4525 return \"mov%D6\\t%0, %1\";
4526 }
4527 return \"\";
4528 "
4529 [(set_attr "conds" "clob")
4530 (set_attr "length" "8,12")])
4531
4532 (define_insn "*ifcompare_move_arith"
4533 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4534 (if_then_else:SI (match_operator 6 "comparison_operator"
4535 [(match_operand:SI 4 "s_register_operand" "r,r")
4536 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
4537 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")
4538 (match_operator:SI 7 "shiftable_operator"
4539 [(match_operand:SI 2 "s_register_operand" "r,r")
4540 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
4541 (clobber (reg 24))]
4542 ""
4543 "*
4544 /* If we have an operation where (op x 0) is the identity operation and
4545 the conditional operator is LT or GE and we are comparing against zero and
4546 everything is in registers then we can do this in two instructions */
4547 if (operands[5] == const0_rtx
4548 && GET_CODE (operands[7]) != AND
4549 && GET_CODE (operands[3]) == REG
4550 && GET_CODE (operands[1]) == REG
4551 && REGNO (operands[1]) == REGNO (operands[2])
4552 && REGNO (operands[2]) != REGNO (operands[0]))
4553 {
4554 if (GET_CODE (operands[6]) == GE)
4555 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
4556 else if (GET_CODE (operands[6]) == LT)
4557 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
4558 }
4559
4560 if (GET_CODE (operands[5]) == CONST_INT
4561 && !const_ok_for_arm (INTVAL (operands[5])))
4562 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
4563 else
4564 output_asm_insn (\"cmp\\t%4, %5\", operands);
4565
4566 if (which_alternative != 0)
4567 {
4568 if (GET_CODE (operands[1]) == MEM)
4569 output_asm_insn (\"ldr%d6\\t%0, %1\", operands);
4570 else
4571 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
4572 }
4573 return \"%I7%D6\\t%0, %2, %3\";
4574 "
4575 [(set_attr "conds" "clob")
4576 (set_attr "length" "8,12")])
4577
4578 (define_insn "*ifcompare_plus_move"
4579 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4580 (if_then_else:SI (match_operator 6 "comparison_operator"
4581 [(match_operand:SI 4 "s_register_operand" "r,r")
4582 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
4583 (plus:SI
4584 (match_operand:SI 2 "s_register_operand" "r,r")
4585 (match_operand:SI 3 "arm_add_operand" "rL,rL"))
4586 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")))
4587 (clobber (reg 24))]
4588 ""
4589 "*
4590 {
4591 if (GET_CODE (operands[5]) == CONST_INT
4592 && !const_ok_for_arm (INTVAL (operands[5])))
4593 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
4594 else
4595 output_asm_insn (\"cmp\\t%4, %5\", operands);
4596 if (GET_CODE (operands[3]) == CONST_INT
4597 && !const_ok_for_arm (INTVAL (operands[3])))
4598 output_asm_insn (\"sub%d6\\t%0, %2, #%n3\", operands);
4599 else
4600 output_asm_insn (\"add%d6\\t%0, %2, %3\", operands);
4601 if (which_alternative != 0)
4602 {
4603 if (GET_CODE (operands[1]) == MEM)
4604 output_asm_insn (\"ldr%D6\\t%0, %1\", operands);
4605 else
4606 output_asm_insn (\"mov%D6\\t%0, %1\", operands);
4607 }
4608 return \"\";
4609 }
4610 "
4611 [(set_attr "conds" "clob")
4612 (set_attr "length" "8,12")])
4613
4614 (define_insn "*ifcompare_move_plus"
4615 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4616 (if_then_else:SI (match_operator 6 "comparison_operator"
4617 [(match_operand:SI 4 "s_register_operand" "r,r")
4618 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
4619 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")
4620 (plus:SI
4621 (match_operand:SI 2 "s_register_operand" "r,r")
4622 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
4623 (clobber (reg 24))]
4624 ""
4625 "*
4626 {
4627 if (GET_CODE (operands[5]) == CONST_INT
4628 && !const_ok_for_arm (INTVAL (operands[5])))
4629 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
4630 else
4631 output_asm_insn (\"cmp\\t%4, %5\", operands);
4632 if (GET_CODE (operands[3]) == CONST_INT
4633 && !const_ok_for_arm (INTVAL (operands[3])))
4634 output_asm_insn (\"sub%D6\\t%0, %2, #%n3\", operands);
4635 else
4636 output_asm_insn (\"add%D6\\t%0, %2, %3\", operands);
4637 if (which_alternative != 0)
4638 {
4639 if (GET_CODE (operands[6]) == MEM)
4640 output_asm_insn (\"ldr%d6\\t%0, %1\", operands);
4641 else
4642 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
4643 }
4644 return \"\";
4645 }
4646 "
4647 [(set_attr "conds" "clob")
4648 (set_attr "length" "8,12")])
4649
4650 (define_insn "ifcompare_move_not"
4651 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4652 (if_then_else:SI (match_operator 5 "comparison_operator"
4653 [(match_operand:SI 3 "s_register_operand" "r,r")
4654 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
4655 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
4656 (not:SI
4657 (match_operand:SI 2 "s_register_operand" "r,r"))))
4658 (clobber (reg 24))]
4659 ""
4660 "#"
4661 [(set_attr "conds" "clob")
4662 (set_attr "length" "8,12")])
4663
4664 (define_insn "*ifcompare_not_move"
4665 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4666 (if_then_else:SI
4667 (match_operator 5 "comparison_operator"
4668 [(match_operand:SI 3 "s_register_operand" "r,r,r,r")
4669 (match_operand:SI 4 "arm_add_operand" "rI,L,rI,L")])
4670 (not:SI
4671 (match_operand:SI 2 "s_register_operand" "r,r,r,r"))
4672 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))
4673 (clobber (reg 24))]
4674 ""
4675 "@
4676 cmp\\t%3, %4\;mvn%d5\\t%0, %2
4677 cmn\\t%3, #%n4\;mvn%d5\\t%0, %2
4678 cmp\\t%3, %4\;mov%D5\\t%0, %1\;mvn%d5\\t%0, %2
4679 cmn\\t%3, #%n4\;mov%D5\\t%0, %1\;mvn%d5\\t%0, %2"
4680 [(set_attr "conds" "clob")
4681 (set_attr "length" "8,8,12,12")])
4682
4683 (define_insn "*ifcompare_shift_move"
4684 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4685 (if_then_else:SI
4686 (match_operator 6 "comparison_operator"
4687 [(match_operand:SI 4 "s_register_operand" "r,r,r,r")
4688 (match_operand:SI 5 "arm_add_operand" "rI,L,rI,L")])
4689 (match_operator:SI 7 "shift_operator"
4690 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
4691 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM,rM")])
4692 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))
4693 (clobber (reg 24))]
4694 ""
4695 "@
4696 cmp\\t%4, %5\;mov%d6\\t%0, %2%S7
4697 cmn\\t%4, #%n5\;mov%d6\\t%0, %2%S7
4698 cmp\\t%4, %5\;mov%D6\\t%0, %1\;mov%d6\\t%0, %2%S7
4699 cmn\\t%4, #%n5\;mov%D6\\t%0, %1\;mov%d6\\t%0, %2%S7"
4700 [(set_attr "conds" "clob")
4701 (set_attr "length" "8,8,12,12")])
4702
4703 (define_insn "ifcompare_move_shift"
4704 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4705 (if_then_else:SI
4706 (match_operator 6 "comparison_operator"
4707 [(match_operand:SI 4 "s_register_operand" "r,r,r,r")
4708 (match_operand:SI 5 "arm_add_operand" "rI,L,rI,L")])
4709 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
4710 (match_operator:SI 7 "shift_operator"
4711 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
4712 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM,rM")])))
4713 (clobber (reg 24))]
4714 ""
4715 "@
4716 cmp\\t%4, %5\;mov%D6\\t%0, %2%S7
4717 cmn\\t%4, #%n5\;mov%D6\\t%0, %2%S7
4718 cmp\\t%4, %5\;mov%d6\\t%0, %1\;mov%D6\\t%0, %2%S7
4719 cmn\\t%4, #%n5\;mov%d6\\t%0, %1\;mov%D6\\t%0, %2%S7"
4720 [(set_attr "conds" "clob")
4721 (set_attr "length" "8,8,12,12")])
4722
4723 (define_insn "*ifcompare_shift_shift"
4724 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4725 (if_then_else:SI
4726 (match_operator 7 "comparison_operator"
4727 [(match_operand:SI 5 "s_register_operand" "r,r")
4728 (match_operand:SI 6 "arm_add_operand" "rI,L")])
4729 (match_operator:SI 8 "shift_operator"
4730 [(match_operand:SI 1 "s_register_operand" "r,r")
4731 (match_operand:SI 2 "arm_rhs_operand" "rM,rM")])
4732 (match_operator:SI 9 "shift_operator"
4733 [(match_operand:SI 3 "s_register_operand" "r,r")
4734 (match_operand:SI 4 "arm_rhs_operand" "rI,rI")])))
4735 (clobber (reg 24))]
4736 ""
4737 "@
4738 cmp\\t%5, %6\;mov%d7\\t%0, %1%S8\;mov%D7\\t%0, %3%S9
4739 cmn\\t%5, #%n6\;mov%d7\\t%0, %1%S8\;mov%D7\\t%0, %3%S9"
4740 [(set_attr "conds" "clob")
4741 (set_attr "length" "12")])
4742
4743 (define_insn "*ifcompare_not_arith"
4744 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4745 (if_then_else:SI
4746 (match_operator 6 "comparison_operator"
4747 [(match_operand:SI 4 "s_register_operand" "r,r")
4748 (match_operand:SI 5 "arm_add_operand" "rI,L")])
4749 (not:SI (match_operand:SI 1 "s_register_operand" "r,r"))
4750 (match_operator:SI 7 "shiftable_operator"
4751 [(match_operand:SI 2 "s_register_operand" "r,r")
4752 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
4753 (clobber (reg 24))]
4754 ""
4755 "@
4756 cmp\\t%4, %5\;mvn%d6\\t%0, %1\;%I7%D6\\t%0, %2, %3
4757 cmn\\t%4, #%n5\;mvn%d6\\t%0, %1\;%I7%D6\\t%0, %2, %3"
4758 [(set_attr "conds" "clob")
4759 (set_attr "length" "12")])
4760
4761 (define_insn "*if_compare_arith_not"
4762 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4763 (if_then_else:SI
4764 (match_operator 6 "comparison_operator"
4765 [(match_operand:SI 4 "s_register_operand" "r,r")
4766 (match_operand:SI 5 "arm_add_operand" "rI,L")])
4767 (match_operator:SI 7 "shiftable_operator"
4768 [(match_operand:SI 2 "s_register_operand" "r,r")
4769 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
4770 (not:SI (match_operand:SI 1 "s_register_operand" "r,r"))))
4771 (clobber (reg 24))]
4772 ""
4773 "@
4774 cmp\\t%4, %5\;mvn%D6\\t%0, %1\;%I7%d6\\t%0, %2, %3
4775 cmn\\t%4, #%n5\;mvn%D6\\t%0, %1\;%I7%d6\\t%0, %2, %3"
4776 [(set_attr "conds" "clob")
4777 (set_attr "length" "12")])
4778
4779 (define_insn "*ifcompare_neg_move"
4780 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4781 (if_then_else:SI
4782 (match_operator 5 "comparison_operator"
4783 [(match_operand:SI 3 "s_register_operand" "r,r,r,r")
4784 (match_operand:SI 4 "arm_add_operand" "rI,L,rI,L")])
4785 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r"))
4786 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))
4787 (clobber (reg:CC 24))]
4788 ""
4789 "@
4790 cmp\\t%3, %4\;rsb%d5\\t%0, %2, #0
4791 cmn\\t%3, #%n4\;rsb%d5\\t%0, %2, #0
4792 cmp\\t%3, %4\;mov%D5\\t%0, %1\;rsb%d5\\t%0, %2, #0
4793 cmn\\t%3, #%n4\;mov%D5\\t%0, %1\;rsb%d5\\t%0, %2, #0"
4794 [(set_attr "conds" "clob")
4795 (set_attr "length" "8,8,12,12")])
4796
4797 (define_insn "*ifcompare_move_neg"
4798 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4799 (if_then_else:SI
4800 (match_operator 5 "comparison_operator"
4801 [(match_operand:SI 3 "s_register_operand" "r,r,r,r")
4802 (match_operand:SI 4 "arm_add_operand" "rI,L,rI,L")])
4803 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
4804 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r"))))
4805 (clobber (reg:CC 24))]
4806 ""
4807 "@
4808 cmp\\t%3, %4\;rsb%D5\\t%0, %2, #0
4809 cmn\\t%3, #%n4\;rsb%D5\\t%0, %2, #0
4810 cmp\\t%3, %4\;mov%d5\\t%0, %1\;rsb%D5\\t%0, %2, #0
4811 cmn\\t%3, #%n4\;mov%d5\\t%0, %1\;rsb%D5\\t%0, %2, #0"
4812 [(set_attr "conds" "clob")
4813 (set_attr "length" "8,8,12,12")])
4814
4815 (define_insn "*arith_adjacentmem"
4816 [(set (match_operand:SI 0 "s_register_operand" "=r")
4817 (match_operator:SI 1 "shiftable_operator"
4818 [(match_operand:SI 2 "memory_operand" "m")
4819 (match_operand:SI 3 "memory_operand" "m")]))
4820 (clobber (match_scratch:SI 4 "=r"))]
4821 "adjacent_mem_locations (operands[2], operands[3])"
4822 "*
4823 {
4824 rtx ldm[3];
4825 rtx arith[4];
4826 int val1 = 0, val2 = 0;
4827
4828 if (REGNO (operands[0]) > REGNO (operands[4]))
4829 {
4830 ldm[1] = operands[4];
4831 ldm[2] = operands[0];
4832 }
4833 else
4834 {
4835 ldm[1] = operands[0];
4836 ldm[2] = operands[4];
4837 }
4838 if (GET_CODE (XEXP (operands[2], 0)) != REG)
4839 val1 = INTVAL (XEXP (XEXP (operands[2], 0), 1));
4840 if (GET_CODE (XEXP (operands[3], 0)) != REG)
4841 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
4842 arith[0] = operands[0];
4843 arith[3] = operands[1];
4844 if (val1 < val2)
4845 {
4846 arith[1] = ldm[1];
4847 arith[2] = ldm[2];
4848 }
4849 else
4850 {
4851 arith[1] = ldm[2];
4852 arith[2] = ldm[1];
4853 }
4854 if (val1 && val2)
4855 {
4856 rtx ops[3];
4857 ldm[0] = ops[0] = operands[4];
4858 ops[1] = XEXP (XEXP (operands[2], 0), 0);
4859 ops[2] = XEXP (XEXP (operands[2], 0), 1);
4860 output_add_immediate (ops);
4861 if (val1 < val2)
4862 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
4863 else
4864 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
4865 }
4866 else if (val1)
4867 {
4868 ldm[0] = XEXP (operands[3], 0);
4869 if (val1 < val2)
4870 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
4871 else
4872 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
4873 }
4874 else
4875 {
4876 ldm[0] = XEXP (operands[2], 0);
4877 if (val1 < val2)
4878 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
4879 else
4880 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
4881 }
4882 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
4883 return \"\";
4884 }
4885 "
4886 [(set_attr "length" "12")
4887 (set_attr "type" "load")])
4888
4889 ;; the arm can support extended pre-inc instructions
4890
4891 ;; In all these cases, we use operands 0 and 1 for the register being
4892 ;; incremented because those are the operands that local-alloc will
4893 ;; tie and these are the pair most likely to be tieable (and the ones
4894 ;; that will benefit the most).
4895
4896 ;; We reject the frame pointer if it occurs anywhere in these patterns since
4897 ;; elimination will cause too many headaches.
4898
4899 (define_insn "*strqi_preinc"
4900 [(set (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4901 (match_operand:SI 2 "index_operand" "rJ")))
4902 (match_operand:QI 3 "s_register_operand" "r"))
4903 (set (match_operand:SI 0 "s_register_operand" "=r")
4904 (plus:SI (match_dup 1) (match_dup 2)))]
4905 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4906 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4907 && (GET_CODE (operands[2]) != REG
4908 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4909 "str%?b\\t%3, [%0, %2]!"
4910 [(set_attr "type" "store1")])
4911
4912 (define_insn "*strqi_predec"
4913 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4914 (match_operand:SI 2 "s_register_operand" "r")))
4915 (match_operand:QI 3 "s_register_operand" "r"))
4916 (set (match_operand:SI 0 "s_register_operand" "=r")
4917 (minus:SI (match_dup 1) (match_dup 2)))]
4918 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4919 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4920 && (GET_CODE (operands[2]) != REG
4921 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4922 "str%?b\\t%3, [%0, -%2]!"
4923 [(set_attr "type" "store1")])
4924
4925 (define_insn "*loadqi_preinc"
4926 [(set (match_operand:QI 3 "s_register_operand" "=r")
4927 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4928 (match_operand:SI 2 "index_operand" "rJ"))))
4929 (set (match_operand:SI 0 "s_register_operand" "=r")
4930 (plus:SI (match_dup 1) (match_dup 2)))]
4931 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4932 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4933 && (GET_CODE (operands[2]) != REG
4934 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4935 "ldr%?b\\t%3, [%0, %2]!"
4936 [(set_attr "type" "load")])
4937
4938 (define_insn "*loadqi_predec"
4939 [(set (match_operand:QI 3 "s_register_operand" "=r")
4940 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4941 (match_operand:SI 2 "s_register_operand" "r"))))
4942 (set (match_operand:SI 0 "s_register_operand" "=r")
4943 (minus:SI (match_dup 1) (match_dup 2)))]
4944 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4945 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4946 && (GET_CODE (operands[2]) != REG
4947 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4948 "ldr%?b\\t%3, [%0, -%2]!"
4949 [(set_attr "type" "load")])
4950
4951 (define_insn "*loadqisi_preinc"
4952 [(set (match_operand:SI 3 "s_register_operand" "=r")
4953 (zero_extend:SI
4954 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4955 (match_operand:SI 2 "index_operand" "rJ")))))
4956 (set (match_operand:SI 0 "s_register_operand" "=r")
4957 (plus:SI (match_dup 1) (match_dup 2)))]
4958 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4959 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4960 && (GET_CODE (operands[2]) != REG
4961 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4962 "ldr%?b\\t%3, [%0, %2]!\\t%@ z_extendqisi"
4963 [(set_attr "type" "load")])
4964
4965 (define_insn "*loadqisi_predec"
4966 [(set (match_operand:SI 3 "s_register_operand" "=r")
4967 (zero_extend:SI
4968 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4969 (match_operand:SI 2 "s_register_operand" "r")))))
4970 (set (match_operand:SI 0 "s_register_operand" "=r")
4971 (minus:SI (match_dup 1) (match_dup 2)))]
4972 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4973 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4974 && (GET_CODE (operands[2]) != REG
4975 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4976 "ldr%?b\\t%3, [%0, -%2]!\\t%@ z_extendqisi"
4977 [(set_attr "type" "load")])
4978
4979 (define_insn "*strsi_preinc"
4980 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4981 (match_operand:SI 2 "index_operand" "rJ")))
4982 (match_operand:SI 3 "s_register_operand" "r"))
4983 (set (match_operand:SI 0 "s_register_operand" "=r")
4984 (plus:SI (match_dup 1) (match_dup 2)))]
4985 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4986 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4987 && (GET_CODE (operands[2]) != REG
4988 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4989 "str%?\\t%3, [%0, %2]!"
4990 [(set_attr "type" "store1")])
4991
4992 (define_insn "*strqi_predec"
4993 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4994 (match_operand:SI 2 "s_register_operand" "r")))
4995 (match_operand:SI 3 "s_register_operand" "r"))
4996 (set (match_operand:SI 0 "s_register_operand" "=r")
4997 (minus:SI (match_dup 1) (match_dup 2)))]
4998 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4999 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5000 && (GET_CODE (operands[2]) != REG
5001 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5002 "str%?\\t%3, [%0, -%2]!"
5003 [(set_attr "type" "store1")])
5004
5005 (define_insn "*loadsi_preinc"
5006 [(set (match_operand:SI 3 "s_register_operand" "=r")
5007 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
5008 (match_operand:SI 2 "index_operand" "rJ"))))
5009 (set (match_operand:SI 0 "s_register_operand" "=r")
5010 (plus:SI (match_dup 1) (match_dup 2)))]
5011 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5012 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5013 && (GET_CODE (operands[2]) != REG
5014 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5015 "ldr%?\\t%3, [%0, %2]!"
5016 [(set_attr "type" "load")])
5017
5018 (define_insn "*loadsi_predec"
5019 [(set (match_operand:SI 3 "s_register_operand" "=r")
5020 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5021 (match_operand:SI 2 "s_register_operand" "r"))))
5022 (set (match_operand:SI 0 "s_register_operand" "=r")
5023 (minus:SI (match_dup 1) (match_dup 2)))]
5024 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5025 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5026 && (GET_CODE (operands[2]) != REG
5027 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5028 "ldr%?\\t%3, [%0, -%2]!"
5029 [(set_attr "type" "load")])
5030
5031 (define_insn "*loadhi_preinc"
5032 [(set (match_operand:HI 3 "s_register_operand" "=r")
5033 (mem:HI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
5034 (match_operand:SI 2 "index_operand" "rJ"))))
5035 (set (match_operand:SI 0 "s_register_operand" "=r")
5036 (plus:SI (match_dup 1) (match_dup 2)))]
5037 "(! BYTES_BIG_ENDIAN)
5038 && ! TARGET_SHORT_BY_BYTES
5039 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
5040 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5041 && (GET_CODE (operands[2]) != REG
5042 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5043 "ldr%?\\t%3, [%0, %2]!\\t%@ loadhi"
5044 [(set_attr "type" "load")])
5045
5046 (define_insn "*loadhi_predec"
5047 [(set (match_operand:HI 3 "s_register_operand" "=r")
5048 (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5049 (match_operand:SI 2 "s_register_operand" "r"))))
5050 (set (match_operand:SI 0 "s_register_operand" "=r")
5051 (minus:SI (match_dup 1) (match_dup 2)))]
5052 "(!BYTES_BIG_ENDIAN)
5053 && ! TARGET_SHORT_BY_BYTES
5054 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
5055 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5056 && (GET_CODE (operands[2]) != REG
5057 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5058 "ldr%?\\t%3, [%0, -%2]!\\t%@ loadhi"
5059 [(set_attr "type" "load")])
5060
5061 (define_insn "*strqi_shiftpreinc"
5062 [(set (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
5063 [(match_operand:SI 3 "s_register_operand" "r")
5064 (match_operand:SI 4 "const_shift_operand" "n")])
5065 (match_operand:SI 1 "s_register_operand" "0")))
5066 (match_operand:QI 5 "s_register_operand" "r"))
5067 (set (match_operand:SI 0 "s_register_operand" "=r")
5068 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
5069 (match_dup 1)))]
5070 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5071 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5072 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5073 "str%?b\\t%5, [%0, %3%S2]!"
5074 [(set_attr "type" "store1")])
5075
5076 (define_insn "*strqi_shiftpredec"
5077 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5078 (match_operator:SI 2 "shift_operator"
5079 [(match_operand:SI 3 "s_register_operand" "r")
5080 (match_operand:SI 4 "const_shift_operand" "n")])))
5081 (match_operand:QI 5 "s_register_operand" "r"))
5082 (set (match_operand:SI 0 "s_register_operand" "=r")
5083 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
5084 (match_dup 4)])))]
5085 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5086 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5087 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5088 "str%?b\\t%5, [%0, -%3%S2]!"
5089 [(set_attr "type" "store1")])
5090
5091 (define_insn "*loadqi_shiftpreinc"
5092 [(set (match_operand:QI 5 "s_register_operand" "=r")
5093 (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
5094 [(match_operand:SI 3 "s_register_operand" "r")
5095 (match_operand:SI 4 "const_shift_operand" "n")])
5096 (match_operand:SI 1 "s_register_operand" "0"))))
5097 (set (match_operand:SI 0 "s_register_operand" "=r")
5098 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
5099 (match_dup 1)))]
5100 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5101 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5102 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5103 "ldr%?b\\t%5, [%0, %3%S2]!"
5104 [(set_attr "type" "load")])
5105
5106 (define_insn "*loadqi_shiftpredec"
5107 [(set (match_operand:QI 5 "s_register_operand" "=r")
5108 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5109 (match_operator:SI 2 "shift_operator"
5110 [(match_operand:SI 3 "s_register_operand" "r")
5111 (match_operand:SI 4 "const_shift_operand" "n")]))))
5112 (set (match_operand:SI 0 "s_register_operand" "=r")
5113 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
5114 (match_dup 4)])))]
5115 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5116 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5117 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5118 "ldr%?b\\t%5, [%0, -%3%S2]!"
5119 [(set_attr "type" "load")])
5120
5121 (define_insn "*strsi_shiftpreinc"
5122 [(set (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
5123 [(match_operand:SI 3 "s_register_operand" "r")
5124 (match_operand:SI 4 "const_shift_operand" "n")])
5125 (match_operand:SI 1 "s_register_operand" "0")))
5126 (match_operand:SI 5 "s_register_operand" "r"))
5127 (set (match_operand:SI 0 "s_register_operand" "=r")
5128 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
5129 (match_dup 1)))]
5130 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5131 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5132 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5133 "str%?\\t%5, [%0, %3%S2]!"
5134 [(set_attr "type" "store1")])
5135
5136 (define_insn "*strsi_shiftpredec"
5137 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5138 (match_operator:SI 2 "shift_operator"
5139 [(match_operand:SI 3 "s_register_operand" "r")
5140 (match_operand:SI 4 "const_shift_operand" "n")])))
5141 (match_operand:SI 5 "s_register_operand" "r"))
5142 (set (match_operand:SI 0 "s_register_operand" "=r")
5143 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
5144 (match_dup 4)])))]
5145 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5146 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5147 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5148 "str%?\\t%5, [%0, -%3%S2]!"
5149 [(set_attr "type" "store1")])
5150
5151 (define_insn "*loadqi_shiftpreinc"
5152 [(set (match_operand:SI 5 "s_register_operand" "=r")
5153 (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
5154 [(match_operand:SI 3 "s_register_operand" "r")
5155 (match_operand:SI 4 "const_shift_operand" "n")])
5156 (match_operand:SI 1 "s_register_operand" "0"))))
5157 (set (match_operand:SI 0 "s_register_operand" "=r")
5158 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
5159 (match_dup 1)))]
5160 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5161 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5162 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5163 "ldr%?\\t%5, [%0, %3%S2]!"
5164 [(set_attr "type" "load")])
5165
5166 (define_insn "*loadqi_shiftpredec"
5167 [(set (match_operand:SI 5 "s_register_operand" "=r")
5168 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5169 (match_operator:SI 2 "shift_operator"
5170 [(match_operand:SI 3 "s_register_operand" "r")
5171 (match_operand:SI 4 "const_shift_operand" "n")]))))
5172 (set (match_operand:SI 0 "s_register_operand" "=r")
5173 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
5174 (match_dup 4)])))]
5175 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5176 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5177 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5178 "ldr%?\\t%5, [%0, -%3%S2]!"
5179 [(set_attr "type" "load")])
5180
5181 (define_insn "*loadhi_shiftpreinc"
5182 [(set (match_operand:HI 5 "s_register_operand" "=r")
5183 (mem:HI (plus:SI (match_operator:SI 2 "shift_operator"
5184 [(match_operand:SI 3 "s_register_operand" "r")
5185 (match_operand:SI 4 "const_shift_operand" "n")])
5186 (match_operand:SI 1 "s_register_operand" "0"))))
5187 (set (match_operand:SI 0 "s_register_operand" "=r")
5188 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
5189 (match_dup 1)))]
5190 "(! BYTES_BIG_ENDIAN)
5191 && ! TARGET_SHORT_BY_BYTES
5192 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
5193 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5194 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5195 "ldr%?\\t%5, [%0, %3%S2]!\\t%@ loadhi"
5196 [(set_attr "type" "load")])
5197
5198 (define_insn "*loadhi_shiftpredec"
5199 [(set (match_operand:HI 5 "s_register_operand" "=r")
5200 (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5201 (match_operator:SI 2 "shift_operator"
5202 [(match_operand:SI 3 "s_register_operand" "r")
5203 (match_operand:SI 4 "const_shift_operand" "n")]))))
5204 (set (match_operand:SI 0 "s_register_operand" "=r")
5205 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
5206 (match_dup 4)])))]
5207 "(! BYTES_BIG_ENDIAN)
5208 && ! TARGET_SHORT_BY_BYTES
5209 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
5210 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5211 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5212 "ldr%?\\t%5, [%0, -%3%S2]!\\t%@ loadhi"
5213 [(set_attr "type" "load")])
5214
5215 ; It can also support extended post-inc expressions, but combine doesn't
5216 ; try these....
5217 ; It doesn't seem worth adding peepholes for anything but the most common
5218 ; cases since, unlike combine, the increment must immediately follow the load
5219 ; for this pattern to match.
5220 ; When loading we must watch to see that the base register isn't trampled by
5221 ; the load. In such cases this isn't a post-inc expression.
5222
5223 (define_peephole
5224 [(set (mem:QI (match_operand:SI 0 "s_register_operand" "+r"))
5225 (match_operand:QI 2 "s_register_operand" "r"))
5226 (set (match_dup 0)
5227 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
5228 ""
5229 "str%?b\\t%2, [%0], %1")
5230
5231 (define_peephole
5232 [(set (match_operand:QI 0 "s_register_operand" "=r")
5233 (mem:QI (match_operand:SI 1 "s_register_operand" "+r")))
5234 (set (match_dup 1)
5235 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
5236 "REGNO(operands[0]) != REGNO(operands[1])
5237 && (GET_CODE (operands[2]) != REG
5238 || REGNO(operands[0]) != REGNO (operands[2]))"
5239 "ldr%?b\\t%0, [%1], %2")
5240
5241 (define_peephole
5242 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "+r"))
5243 (match_operand:SI 2 "s_register_operand" "r"))
5244 (set (match_dup 0)
5245 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
5246 ""
5247 "str%?\\t%2, [%0], %1")
5248
5249 (define_peephole
5250 [(set (match_operand:HI 0 "s_register_operand" "=r")
5251 (mem:HI (match_operand:SI 1 "s_register_operand" "+r")))
5252 (set (match_dup 1)
5253 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
5254 "(! BYTES_BIG_ENDIAN)
5255 && ! TARGET_SHORT_BY_BYTES
5256 && REGNO(operands[0]) != REGNO(operands[1])
5257 && (GET_CODE (operands[2]) != REG
5258 || REGNO(operands[0]) != REGNO (operands[2]))"
5259 "ldr%?\\t%0, [%1], %2\\t%@ loadhi")
5260
5261 (define_peephole
5262 [(set (match_operand:SI 0 "s_register_operand" "=r")
5263 (mem:SI (match_operand:SI 1 "s_register_operand" "+r")))
5264 (set (match_dup 1)
5265 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
5266 "REGNO(operands[0]) != REGNO(operands[1])
5267 && (GET_CODE (operands[2]) != REG
5268 || REGNO(operands[0]) != REGNO (operands[2]))"
5269 "ldr%?\\t%0, [%1], %2")
5270
5271 (define_peephole
5272 [(set (mem:QI (plus:SI (match_operand:SI 0 "s_register_operand" "+r")
5273 (match_operand:SI 1 "index_operand" "rJ")))
5274 (match_operand:QI 2 "s_register_operand" "r"))
5275 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
5276 ""
5277 "str%?b\\t%2, [%0, %1]!")
5278
5279 (define_peephole
5280 [(set (mem:QI (plus:SI (match_operator:SI 4 "shift_operator"
5281 [(match_operand:SI 0 "s_register_operand" "r")
5282 (match_operand:SI 1 "const_int_operand" "n")])
5283 (match_operand:SI 2 "s_register_operand" "+r")))
5284 (match_operand:QI 3 "s_register_operand" "r"))
5285 (set (match_dup 2) (plus:SI (match_op_dup 4 [(match_dup 0) (match_dup 1)])
5286 (match_dup 2)))]
5287 ""
5288 "str%?b\\t%3, [%2, %0%S4]!")
5289
5290 ; This pattern is never tried by combine, so do it as a peephole
5291
5292 (define_peephole
5293 [(set (match_operand:SI 0 "s_register_operand" "=r")
5294 (match_operand:SI 1 "s_register_operand" "r"))
5295 (set (match_operand 2 "cc_register" "")
5296 (compare (match_dup 1) (const_int 0)))]
5297 ""
5298 "sub%?s\\t%0, %1, #0"
5299 [(set_attr "conds" "set")])
5300
5301 ; Peepholes to spot possible load- and store-multiples, if the ordering is
5302 ; reversed, check that the memory references aren't volatile.
5303
5304 (define_peephole
5305 [(set (match_operand:SI 0 "s_register_operand" "=r")
5306 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5307 (const_int 12))))
5308 (set (match_operand:SI 2 "s_register_operand" "=r")
5309 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
5310 (set (match_operand:SI 3 "s_register_operand" "=r")
5311 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
5312 (set (match_operand:SI 4 "s_register_operand" "=r")
5313 (mem:SI (match_dup 1)))]
5314 "REGNO (operands[0]) > REGNO (operands[2])
5315 && REGNO (operands[2]) > REGNO (operands[3])
5316 && REGNO (operands[3]) > REGNO (operands[4])
5317 && !(REGNO (operands[1]) == REGNO (operands[0])
5318 || REGNO (operands[1]) == REGNO (operands[2])
5319 || REGNO (operands[1]) == REGNO (operands[3])
5320 || REGNO (operands[1]) == REGNO (operands[4]))
5321 && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn)))
5322 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))
5323 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn
5324 (prev_nonnote_insn (insn)))))
5325 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn
5326 (prev_nonnote_insn
5327 (prev_nonnote_insn (insn))))))"
5328 "ldm%?ia\\t%1, {%4, %3, %2, %0}\\t%@ phole ldm")
5329
5330 (define_peephole
5331 [(set (match_operand:SI 0 "s_register_operand" "=r")
5332 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5333 (const_int 8))))
5334 (set (match_operand:SI 2 "s_register_operand" "=r")
5335 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
5336 (set (match_operand:SI 3 "s_register_operand" "=r")
5337 (mem:SI (match_dup 1)))]
5338 "REGNO (operands[0]) > REGNO (operands[2])
5339 && REGNO (operands[2]) > REGNO (operands[3])
5340 && !(REGNO (operands[1]) == REGNO (operands[0])
5341 || REGNO (operands[1]) == REGNO (operands[2])
5342 || REGNO (operands[1]) == REGNO (operands[3]))
5343 && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn)))
5344 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))
5345 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn
5346 (prev_nonnote_insn (insn)))))"
5347 "ldm%?ia\\t%1, {%3, %2, %0}\\t%@ phole ldm")
5348
5349 (define_peephole
5350 [(set (match_operand:SI 0 "s_register_operand" "=r")
5351 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5352 (const_int 4))))
5353 (set (match_operand:SI 2 "s_register_operand" "=r")
5354 (mem:SI (match_dup 1)))]
5355 "REGNO (operands[0]) > REGNO (operands[2])
5356 && !(REGNO (operands[1]) == REGNO (operands[0])
5357 || REGNO (operands[1]) == REGNO (operands[2]))
5358 && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn)))
5359 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))"
5360 "ldm%?ia\\t%1, {%2, %0}\\t%@ phole ldm")
5361
5362 (define_peephole
5363 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5364 (const_int 12)))
5365 (match_operand:SI 0 "s_register_operand" "r"))
5366 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
5367 (match_operand:SI 2 "s_register_operand" "r"))
5368 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5369 (match_operand:SI 3 "s_register_operand" "r"))
5370 (set (mem:SI (match_dup 1))
5371 (match_operand:SI 4 "s_register_operand" "r"))]
5372 "REGNO (operands[0]) > REGNO (operands[2])
5373 && REGNO (operands[2]) > REGNO (operands[3])
5374 && REGNO (operands[3]) > REGNO (operands[4])
5375 && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn)))
5376 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))
5377 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn
5378 (prev_nonnote_insn (insn)))))
5379 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn
5380 (prev_nonnote_insn
5381 (prev_nonnote_insn (insn))))))"
5382 "stm%?ia\\t%1, {%4, %3, %2, %0}\\t%@ phole stm")
5383
5384 (define_peephole
5385 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5386 (const_int 8)))
5387 (match_operand:SI 0 "s_register_operand" "r"))
5388 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5389 (match_operand:SI 2 "s_register_operand" "r"))
5390 (set (mem:SI (match_dup 1))
5391 (match_operand:SI 3 "s_register_operand" "r"))]
5392 "REGNO (operands[0]) > REGNO (operands[2])
5393 && REGNO (operands[2]) > REGNO (operands[3])
5394 && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn)))
5395 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))
5396 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn
5397 (prev_nonnote_insn (insn)))))"
5398 "stm%?ia\\t%1, {%3, %2, %0}\\t%@ phole stm")
5399
5400 (define_peephole
5401 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5402 (const_int 4)))
5403 (match_operand:SI 0 "s_register_operand" "r"))
5404 (set (mem:SI (match_dup 1))
5405 (match_operand:SI 2 "s_register_operand" "r"))]
5406 "REGNO (operands[0]) > REGNO (operands[2])
5407 && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn)))
5408 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))"
5409 "stm%?ia\\t%1, {%2, %0}\\t%@ phole stm")
5410
5411 ;; A call followed by return can be replaced by restoring the regs and
5412 ;; jumping to the subroutine, provided we aren't passing the address of
5413 ;; any of our local variables. If we call alloca then this is unsafe
5414 ;; since restoring the frame frees the memory, which is not what we want.
5415 ;; Sometimes the return might have been targeted by the final prescan:
5416 ;; if so then emit a proper return insn as well.
5417 ;; Unfortunately, if the frame pointer is required, we don't know if the
5418 ;; current function has any implicit stack pointer adjustments that will
5419 ;; be restored by the return: we can't therefore do a tail call.
5420 ;; Another unfortunate that we can't handle is if current_function_args_size
5421 ;; is non-zero: in this case elimination of the argument pointer assumed
5422 ;; that lr was pushed onto the stack, so eliminating upsets the offset
5423 ;; calculations.
5424
5425 (define_peephole
5426 [(parallel [(call (mem:SI (match_operand:SI 0 "" "X"))
5427 (match_operand:SI 1 "general_operand" "g"))
5428 (clobber (reg:SI 14))])
5429 (return)]
5430 "(GET_CODE (operands[0]) == SYMBOL_REF && USE_RETURN_INSN
5431 && !get_frame_size () && !current_function_calls_alloca
5432 && !frame_pointer_needed && !current_function_args_size)"
5433 "*
5434 {
5435 extern rtx arm_target_insn;
5436 extern int arm_ccfsm_state, arm_current_cc;
5437
5438 if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
5439 {
5440 arm_current_cc ^= 1;
5441 output_return_instruction (NULL, TRUE);
5442 arm_ccfsm_state = 0;
5443 arm_target_insn = NULL;
5444 }
5445
5446 output_return_instruction (NULL, FALSE);
5447 return \"b%?\\t%a0\";
5448 }"
5449 [(set_attr "type" "call")
5450 (set_attr "length" "8")])
5451
5452 (define_peephole
5453 [(parallel [(set (match_operand 0 "s_register_operand" "=rf")
5454 (call (mem:SI (match_operand:SI 1 "" "X"))
5455 (match_operand:SI 2 "general_operand" "g")))
5456 (clobber (reg:SI 14))])
5457 (return)]
5458 "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN
5459 && !get_frame_size () && !current_function_calls_alloca
5460 && !frame_pointer_needed && !current_function_args_size)"
5461 "*
5462 {
5463 extern rtx arm_target_insn;
5464 extern int arm_ccfsm_state, arm_current_cc;
5465
5466 if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
5467 {
5468 arm_current_cc ^= 1;
5469 output_return_instruction (NULL, TRUE);
5470 arm_ccfsm_state = 0;
5471 arm_target_insn = NULL;
5472 }
5473
5474 output_return_instruction (NULL, FALSE);
5475 return \"b%?\\t%a1\";
5476 }"
5477 [(set_attr "type" "call")
5478 (set_attr "length" "8")])
5479
5480 ;; As above but when this function is not void, we must be returning the
5481 ;; result of the called subroutine.
5482
5483 (define_peephole
5484 [(parallel [(set (match_operand 0 "s_register_operand" "=rf")
5485 (call (mem:SI (match_operand:SI 1 "" "X"))
5486 (match_operand:SI 2 "general_operand" "g")))
5487 (clobber (reg:SI 14))])
5488 (use (match_dup 0))
5489 (return)]
5490 "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN
5491 && !get_frame_size () && !current_function_calls_alloca
5492 && !frame_pointer_needed && !current_function_args_size)"
5493 "*
5494 {
5495 extern rtx arm_target_insn;
5496 extern int arm_ccfsm_state, arm_current_cc;
5497
5498 if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
5499 {
5500 arm_current_cc ^= 1;
5501 output_return_instruction (NULL, TRUE);
5502 arm_ccfsm_state = 0;
5503 arm_target_insn = NULL;
5504 }
5505
5506 output_return_instruction (NULL, FALSE);
5507 return \"b%?\\t%a1\";
5508 }"
5509 [(set_attr "type" "call")
5510 (set_attr "length" "8")])
5511
5512 ;; If calling a subroutine and then jumping back to somewhere else, but not
5513 ;; too far away, then we can set the link register with the branch address
5514 ;; and jump direct to the subroutine. On return from the subroutine
5515 ;; execution continues at the branch; this avoids a prefetch stall.
5516 ;; We use the length attribute (via short_branch ()) to establish whether or
5517 ;; not this is possible, this is the same as the sparc does.
5518
5519 (define_peephole
5520 [(parallel[(call (mem:SI (match_operand:SI 0 "" "X"))
5521 (match_operand:SI 1 "general_operand" "g"))
5522 (clobber (reg:SI 14))])
5523 (set (pc)
5524 (label_ref (match_operand 2 "" "")))]
5525 "0 && GET_CODE (operands[0]) == SYMBOL_REF
5526 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
5527 && arm_insn_not_targeted (insn)"
5528 "*
5529 {
5530 int backward = arm_backwards_branch (INSN_UID (insn),
5531 INSN_UID (operands[2]));
5532
5533 #if 0
5534 /* Putting this in means that TARGET_6 code will ONLY run on an arm6 or
5535 * above, leaving it out means that the code will still run on an arm 2 or 3
5536 */
5537 if (TARGET_6)
5538 {
5539 if (backward)
5540 output_asm_insn (\"sub%?\\t%|lr, %|pc, #(8 + . -%l2)\", operands);
5541 else
5542 output_asm_insn (\"add%?\\t%|lr, %|pc, #(%l2 - . -8)\", operands);
5543 }
5544 else
5545 #endif
5546 {
5547 output_asm_insn (\"mov%?\\t%|lr, %|pc\\t%@ protect cc\", operands);
5548 if (backward)
5549 output_asm_insn (\"sub%?\\t%|lr, %|lr, #(4 + . -%l2)\", operands);
5550 else
5551 output_asm_insn (\"add%?\\t%|lr, %|lr, #(%l2 - . -4)\", operands);
5552 }
5553 return \"b%?\\t%a0\";
5554 }"
5555 [(set_attr "type" "call")
5556 (set (attr "length")
5557 (if_then_else (eq_attr "prog_mode" "prog32")
5558 (const_int 8)
5559 (const_int 12)))])
5560
5561 (define_peephole
5562 [(parallel[(set (match_operand:SI 0 "s_register_operand" "=r")
5563 (call (mem:SI (match_operand:SI 1 "" "X"))
5564 (match_operand:SI 2 "general_operand" "g")))
5565 (clobber (reg:SI 14))])
5566 (set (pc)
5567 (label_ref (match_operand 3 "" "")))]
5568 "0 && GET_CODE (operands[0]) == SYMBOL_REF
5569 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
5570 && arm_insn_not_targeted (insn)"
5571 "*
5572 {
5573 int backward = arm_backwards_branch (INSN_UID (insn),
5574 INSN_UID (operands[3]));
5575
5576 #if 0
5577 /* Putting this in means that TARGET_6 code will ONLY run on an arm6 or
5578 * above, leaving it out means that the code will still run on an arm 2 or 3
5579 */
5580 if (TARGET_6)
5581 {
5582 if (backward)
5583 output_asm_insn (\"sub%?\\t%|lr, %|pc, #(8 + . -%l3)\", operands);
5584 else
5585 output_asm_insn (\"add%?\\t%|lr, %|pc, #(%l3 - . -8)\", operands);
5586 }
5587 else
5588 #endif
5589 {
5590 output_asm_insn (\"mov%?\\t%|lr, %|pc\\t%@ protect cc\", operands);
5591 if (backward)
5592 output_asm_insn (\"sub%?\\t%|lr, %|lr, #(4 + . -%l3)\", operands);
5593 else
5594 output_asm_insn (\"add%?\\t%|lr, %|lr, #(%l3 - . -4)\", operands);
5595 }
5596 return \"b%?\\t%a1\";
5597 }"
5598 [(set_attr "type" "call")
5599 (set (attr "length")
5600 (if_then_else (eq_attr "prog_mode" "prog32")
5601 (const_int 8)
5602 (const_int 12)))])
5603
5604 (define_split
5605 [(set (pc)
5606 (if_then_else (match_operator 0 "comparison_operator"
5607 [(match_operator:SI 1 "shift_operator"
5608 [(match_operand:SI 2 "s_register_operand" "r")
5609 (match_operand:SI 3 "reg_or_int_operand" "rM")])
5610 (match_operand:SI 4 "s_register_operand" "r")])
5611 (label_ref (match_operand 5 "" ""))
5612 (pc)))
5613 (clobber (reg 24))]
5614 ""
5615 [(set (reg:CC 24)
5616 (compare:CC (match_dup 4)
5617 (match_op_dup 1 [(match_dup 2) (match_dup 3)])))
5618 (set (pc)
5619 (if_then_else (match_op_dup 0 [(reg 24) (const_int 0)])
5620 (label_ref (match_dup 5))
5621 (pc)))]
5622 "
5623 operands[0] = gen_rtx (swap_condition (GET_CODE (operands[0])), VOIDmode,
5624 operands[1], operands[2]);
5625 ")
5626
5627 (define_split
5628 [(set (match_operand:SI 0 "s_register_operand" "")
5629 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
5630 (const_int 0))
5631 (neg:SI (match_operator:SI 2 "comparison_operator"
5632 [(match_operand:SI 3 "s_register_operand" "")
5633 (match_operand:SI 4 "arm_rhs_operand" "")]))))
5634 (clobber (match_operand:SI 5 "s_register_operand" ""))]
5635 ""
5636 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
5637 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
5638 (match_dup 5)))]
5639 "")
5640
5641 ;; This pattern can be used because cc_noov mode implies that the following
5642 ;; branch will be an equality (EQ or NE), so the sign extension is not
5643 ;; needed. Combine doesn't eliminate these because by the time it sees the
5644 ;; branch it no-longer knows that the data came from memory.
5645
5646 (define_insn "*loadqi_compare"
5647 [(set (reg:CC_NOOV 24)
5648 (compare:CC_NOOV
5649 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "m") 0)
5650 (const_int 24))
5651 (match_operand 1 "immediate_operand" "I")))
5652 (clobber (match_scratch:SI 2 "=r"))]
5653 "((unsigned long) INTVAL (operands[1]))
5654 == (((unsigned long) INTVAL (operands[1])) >> 24) << 24"
5655 "*
5656 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
5657 output_asm_insn (\"ldr%?b\\t%2, %0\", operands);
5658 output_asm_insn (\"cmp%?\\t%2, %1\", operands);
5659 return \"\";
5660 "
5661 [(set_attr "conds" "set")
5662 (set_attr "length" "8")
5663 (set_attr "type" "load")])
5664
5665 (define_expand "prologue"
5666 [(clobber (const_int 0))]
5667 ""
5668 "
5669 arm_expand_prologue ();
5670 DONE;
5671 ")
5672
5673 ;; This split is only used during output to reduce the number of patterns
5674 ;; that need assembler instructions adding to them. We allowed the setting
5675 ;; of the conditions to be implicit during rtl generation so that
5676 ;; the conditional compare patterns would work. However this conflicts to
5677 ;; some extend with the conditional data operations, so we have to split them
5678 ;; up again here.
5679
5680 (define_split
5681 [(set (match_operand:SI 0 "s_register_operand" "")
5682 (if_then_else:SI (match_operator 1 "comparison_operator"
5683 [(match_operand 2 "" "") (match_operand 3 "" "")])
5684 (match_operand 4 "" "")
5685 (match_operand 5 "" "")))
5686 (clobber (reg 24))]
5687 "reload_completed"
5688 [(set (match_dup 6) (match_dup 7))
5689 (set (match_dup 0)
5690 (if_then_else:SI (match_op_dup 1 [(match_dup 6) (const_int 0)])
5691 (match_dup 4)
5692 (match_dup 5)))]
5693 "
5694 {
5695 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), operands[2],
5696 operands[3]);
5697
5698 operands[6] = gen_rtx (REG, mode, 24);
5699 operands[7] = gen_rtx (COMPARE, mode, operands[2], operands[3]);
5700 }
5701 ")
5702
5703
5704 (define_insn "*cond_move_not"
5705 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5706 (if_then_else:SI (match_operator 4 "comparison_operator"
5707 [(match_operand 3 "reversible_cc_register" "")
5708 (const_int 0)])
5709 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
5710 (not:SI
5711 (match_operand:SI 2 "s_register_operand" "r,r"))))]
5712 ""
5713 "@
5714 mvn%D4\\t%0, %2
5715 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
5716 [(set_attr "conds" "use")
5717 (set_attr "length" "4,8")])
5718
5719 ;; The next two patterns occur when an AND operation is followed by a
5720 ;; scc insn sequence
5721
5722 (define_insn "*sign_extract_onebit"
5723 [(set (match_operand:SI 0 "s_register_operand" "=r")
5724 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
5725 (const_int 1)
5726 (match_operand:SI 2 "immediate_operand" "n")))]
5727 ""
5728 "*
5729 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
5730 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
5731 return \"mvnne\\t%0, #0\";
5732 "
5733 [(set_attr "conds" "clob")
5734 (set_attr "length" "8")])
5735
5736 (define_insn "*not_signextract_onebit"
5737 [(set (match_operand:SI 0 "s_register_operand" "=r")
5738 (not:SI
5739 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
5740 (const_int 1)
5741 (match_operand:SI 2 "immediate_operand" "n"))))]
5742 ""
5743 "*
5744 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
5745 output_asm_insn (\"tst\\t%1, %2\", operands);
5746 output_asm_insn (\"mvneq\\t%0, #0\", operands);
5747 return \"movne\\t%0, #0\";
5748 "
5749 [(set_attr "conds" "clob")
5750 (set_attr "length" "12")])
5751
5752 ;; Push multiple registers to the stack. The first register is in the
5753 ;; unspec part of the insn; subsequent registers are in parallel (use ...)
5754 ;; expressions.
5755 (define_insn "*push_multi"
5756 [(match_parallel 2 "multi_register_push"
5757 [(set (match_operand:BLK 0 "memory_operand" "=m")
5758 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "r")] 2))])]
5759 ""
5760 "*
5761 {
5762 char pattern[100];
5763 int i;
5764 extern int lr_save_eliminated;
5765
5766 if (lr_save_eliminated)
5767 {
5768 if (XVECLEN (operands[2], 0) > 1)
5769 abort ();
5770 return \"\";
5771 }
5772 strcpy (pattern, \"stmfd\\t%m0!, {%1\");
5773 for (i = 1; i < XVECLEN (operands[2], 0); i++)
5774 {
5775 strcat (pattern, \", %|\");
5776 strcat (pattern, reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i),
5777 0))]);
5778 }
5779 strcat (pattern, \"}\");
5780 output_asm_insn (pattern, operands);
5781 return \"\";
5782 }"
5783 [(set_attr "type" "store4")])
5784
5785 ;; Special patterns for dealing with the constant pool
5786
5787 (define_insn "consttable_4"
5788 [(unspec_volatile [(match_operand 0 "" "")] 2)]
5789 ""
5790 "*
5791 {
5792 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
5793 {
5794 case MODE_FLOAT:
5795 {
5796 union real_extract u;
5797 bcopy ((char *) &CONST_DOUBLE_LOW (operands[0]), (char *) &u, sizeof u);
5798 assemble_real (u.d, GET_MODE (operands[0]));
5799 break;
5800 }
5801 default:
5802 assemble_integer (operands[0], 4, 1);
5803 break;
5804 }
5805 return \"\";
5806 }"
5807 [(set_attr "length" "4")])
5808
5809 (define_insn "consttable_8"
5810 [(unspec_volatile [(match_operand 0 "" "")] 3)]
5811 ""
5812 "*
5813 {
5814 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
5815 {
5816 case MODE_FLOAT:
5817 {
5818 union real_extract u;
5819 bcopy ((char *) &CONST_DOUBLE_LOW (operands[0]), (char *) &u, sizeof u);
5820 assemble_real (u.d, GET_MODE (operands[0]));
5821 break;
5822 }
5823 default:
5824 assemble_integer (operands[0], 8, 1);
5825 break;
5826 }
5827 return \"\";
5828 }"
5829 [(set_attr "length" "8")])
5830
5831 (define_insn "consttable_end"
5832 [(unspec_volatile [(const_int 0)] 4)]
5833 ""
5834 "*
5835 text_section ();
5836 return \"\";
5837 ")
5838
5839 (define_insn "align_4"
5840 [(unspec_volatile [(const_int 0)] 5)]
5841 ""
5842 "*
5843 readonly_data_section ();
5844 assemble_align (32);
5845 return \"\";
5846 ")
This page took 0.300791 seconds and 5 git commands to generate.