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