(peepholes for call followed by branch): Disable.
[official-gcc.git] / gcc / config / arm / arm.md
blob44952d08a87b2eaeccbc2dff8ef654acc7613343
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   if (GET_CODE (XEXP (operands[0], 0)) == REG)
2497     operands[2] = XEXP (operands[0], 0);
2498   else
2499     emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
2500                            XEXP (XEXP (operands[0], 0), 1)));
2501   emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (MEM, DFmode, operands[2]),
2502                       operands[1]));
2503   DONE;
2506 (define_insn ""
2507   [(set (match_operand:DF 0 "general_operand" "=r,Q#m,r,f,f,f,f,m,!f,!r,r")
2508         (match_operand:DF 1 "general_operand" 
2509                 "Q,r,?o,?f,!G,!H,m,f,r,f,??r"))]
2510   "GET_CODE (operands[0]) != MEM || register_operand (operands[1], DFmode)"
2511   "*
2513   rtx ops[3];
2515   switch (which_alternative)
2516     {
2517     case 0:
2518       return \"ldm%?ia\\t%m1, {%0, %R0}\\t%@ double\";
2520     case 1:
2521       return \"stm%?ia\\t%m0, {%1, %R1}\\t%@ double\";
2523     case 2:
2524       ops[0] = operands[0];
2525       ops[1] = XEXP (XEXP (operands[1], 0), 0);
2526       ops[2] = XEXP (XEXP (operands[1], 0), 1);
2527       if (!INTVAL (ops[2]) || const_ok_for_arm (INTVAL (ops[2])))
2528         output_asm_insn (\"add%?\\t%0, %1, %2\", ops);
2529       else
2530         output_asm_insn (\"sub%?\\t%0, %1, #%n2\", ops);
2531       return \"ldm%?ia\\t%0, {%0, %R0}\\t%@ double\";
2533     case 3:
2534     case 4:
2535       return \"mvf%?d\\t%0, %1\";
2537     case 5: return \"mnf%?d\\t%0, #%N1\";
2538     case 6: return \"ldf%?d\\t%0, %1\";
2539     case 7: return \"stf%?d\\t%1, %0\";
2540     case 8: return output_mov_double_fpu_from_arm (operands);
2541     case 9: return output_mov_double_arm_from_fpu (operands);
2542     case 10: return output_move_double (operands);
2543     }
2546 [(set_attr "length" "4,4,8,4,4,4,4,4,8,8,8")
2547  (set_attr "type" 
2548 "load,store2,load,ffarith,ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*")])
2550 (define_expand "movxf"
2551   [(set (match_operand:XF 0 "general_operand" "")
2552         (match_operand:XF 1 "general_operand" ""))]
2553   "ENABLE_XF_PATTERNS"
2554   "")
2556 ;; Even when the XFmode patterns aren't enabled, we enable this after
2557 ;; reloading so that we can push floating point registers in the prologue.
2559 (define_insn ""
2560   [(set (match_operand:XF 0 "general_operand" "=f,f,f,m,f,r,r")
2561         (match_operand:XF 1 "general_operand" "fG,H,m,f,r,f,r"))]
2562   "ENABLE_XF_PATTERNS || reload_completed"
2563   "*
2564   switch (which_alternative)
2565     {
2566     case 0: return \"mvf%?e\\t%0, %1\";
2567     case 1: return \"mnf%?e\\t%0, #%N1\";
2568     case 2: return \"ldf%?e\\t%0, %1\";
2569     case 3: return \"stf%?e\\t%1, %0\";
2570     case 4: return output_mov_long_double_fpu_from_arm (operands);
2571     case 5: return output_mov_long_double_arm_from_fpu (operands);
2572     case 6: return output_mov_long_double_arm_from_arm (operands);
2573     }
2575 [(set_attr "length" "4,4,4,4,8,8,12")
2576  (set_attr "type" "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*")])
2579 ;; load- and store-multiple insns
2580 ;; The arm can load/store any set of registers, provided that they are in
2581 ;; ascending order; but that is beyond GCC so stick with what it knows.
2583 (define_expand "load_multiple"
2584   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
2585                           (match_operand:SI 1 "" ""))
2586                      (use (match_operand:SI 2 "" ""))])]
2587   ""
2588   "
2589   /* Support only fixed point registers */
2590   if (GET_CODE (operands[2]) != CONST_INT
2591       || INTVAL (operands[2]) > 14
2592       || INTVAL (operands[2]) < 2
2593       || GET_CODE (operands[1]) != MEM
2594       || GET_CODE (operands[0]) != REG
2595       || REGNO (operands[0]) > 14
2596       || REGNO (operands[0]) + INTVAL (operands[2]) > 15)
2597     FAIL;
2599   operands[3]
2600             = arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]),
2601                                      force_reg (SImode, XEXP (operands[1], 0)),
2602                                      TRUE, FALSE);
2605 ;; Load multiple with write-back
2607 (define_insn ""
2608   [(match_parallel 0 "load_multiple_operation"
2609                    [(set (match_operand:SI 1 "s_register_operand" "+r")
2610                          (plus:SI (match_dup 1)
2611                                   (match_operand:SI 2 "immediate_operand" "n")))
2612                     (set (match_operand:SI 3 "s_register_operand" "=r")
2613                          (mem:SI (match_dup 1)))])]
2614   "(INTVAL (operands[2])  == 4 * (XVECLEN (operands[0], 0) - 2))"
2615   "*
2617   rtx ops[3];
2618   int count = XVECLEN (operands[0], 0);
2620   ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
2621   ops[1] = SET_DEST (XVECEXP (operands[0], 0, 1));
2622   ops[2] = SET_DEST (XVECEXP (operands[0], 0, count - 2));
2624   output_asm_insn (\"ldm%?ia\\t%0!, {%1-%2}\\t%@ load multiple\", ops);
2625   return \"\";
2628 [(set_attr "type" "load")])
2630 ;; Ordinary load multiple
2632 (define_insn ""
2633   [(match_parallel 0 "load_multiple_operation"
2634                    [(set (match_operand:SI 1 "s_register_operand" "=r")
2635                          (match_operand:SI 2 "indirect_operand" "Q"))])]
2636   ""
2637   "*
2639   rtx ops[3];
2640   int count = XVECLEN (operands[0], 0);
2642   ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
2643   ops[1] = SET_DEST (XVECEXP (operands[0], 0, 0));
2644   ops[2] = SET_DEST (XVECEXP (operands[0], 0, count - 1));
2646   output_asm_insn (\"ldm%?ia\\t%0, {%1-%2}\\t%@ load multiple\", ops);
2647   return \"\";
2650 [(set_attr "type" "load")])
2652 (define_expand "store_multiple"
2653   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
2654                           (match_operand:SI 1 "" ""))
2655                      (use (match_operand:SI 2 "" ""))])]
2656   ""
2657   "
2658   /* Support only fixed point registers */
2659   if (GET_CODE (operands[2]) != CONST_INT
2660       || INTVAL (operands[2]) > 14
2661       || INTVAL (operands[2]) < 2
2662       || GET_CODE (operands[1]) != REG
2663       || GET_CODE (operands[0]) != MEM
2664       || REGNO (operands[1]) > 14
2665       || REGNO (operands[1]) + INTVAL (operands[2]) > 15)
2666     FAIL;
2668   operands[3]
2669            = arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]),
2670                                      force_reg (SImode, XEXP (operands[0], 0)),
2671                                      TRUE, FALSE);
2674 ;; Store multiple with write-back
2676 (define_insn ""
2677   [(match_parallel 0 "store_multiple_operation"
2678                    [(set (match_operand:SI 1 "s_register_operand" "+r")
2679                          (plus:SI (match_dup 1)
2680                                   (match_operand:SI 2 "immediate_operand" "n")))
2681                     (set (mem:SI (match_dup 1))
2682                          (match_operand:SI 3 "s_register_operand" "r"))])]
2683   "(INTVAL (operands[2]) == 4 * (XVECLEN (operands[0], 0) - 2))"
2684   "*
2686   rtx ops[3];
2687   int count = XVECLEN (operands[0], 0);
2689   ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
2690   ops[1] = SET_SRC (XVECEXP (operands[0], 0, 1));
2691   ops[2] = SET_SRC (XVECEXP (operands[0], 0, count - 2));
2693   output_asm_insn (\"stm%?ia\\t%0!, {%1-%2}\\t%@ str multiple\", ops);
2694   return \"\";
2697 [(set (attr "type")
2698       (cond [(eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 4))
2699                 (const_string "store2")
2700              (eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 5))
2701                 (const_string "store3")]
2702           (const_string "store4")))])
2704 ;; Ordinary store multiple
2706 (define_insn ""
2707   [(match_parallel 0 "store_multiple_operation"
2708                    [(set (match_operand:SI 2 "indirect_operand" "=Q")
2709                          (match_operand:SI 1 "s_register_operand" "r"))])]
2710   ""
2711   "*
2713   rtx ops[3];
2714   int count = XVECLEN (operands[0], 0);
2716   ops[0] = XEXP (SET_DEST (XVECEXP (operands[0], 0, 0)), 0);
2717   ops[1] = SET_SRC (XVECEXP (operands[0], 0, 0));
2718   ops[2] = SET_SRC (XVECEXP (operands[0], 0, count - 1));
2720   output_asm_insn (\"stm%?ia\\t%0, {%1-%2}\\t%@ str multiple\", ops);
2721   return \"\";
2724 [(set (attr "type")
2725       (cond [(eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 3))
2726                 (const_string "store2")
2727              (eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 4))
2728                 (const_string "store3")]
2729           (const_string "store4")))])
2731 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
2732 ;; We could let this apply for blocks of less than this, but it clobbers so
2733 ;; many registers that there is then probably a better way.
2735 (define_expand "movstrqi"
2736   [(match_operand:BLK 0 "general_operand" "")
2737    (match_operand:BLK 1 "general_operand" "")
2738    (match_operand:SI 2 "const_int_operand" "")
2739    (match_operand:SI 3 "const_int_operand" "")]
2740   ""
2741   "
2742   if (arm_gen_movstrqi (operands))
2743     DONE;
2744   FAIL;
2748 ;; Comparison and test insns
2750 (define_expand "cmpsi"
2751   [(set (reg:CC 24)
2752         (compare:CC (match_operand:SI 0 "s_register_operand" "")
2753                     (match_operand:SI 1 "arm_add_operand" "")))]
2754   ""
2755   "
2757   arm_compare_op0 = operands[0];
2758   arm_compare_op1 = operands[1];
2759   arm_compare_fp = 0;
2760   DONE;
2764 (define_expand "cmpsf"
2765   [(set (reg:CC 24)
2766         (compare:CC (match_operand:SF 0 "s_register_operand" "")
2767                     (match_operand:SF 1 "fpu_rhs_operand" "")))]
2768   ""
2769   "
2771   arm_compare_op0 = operands[0];
2772   arm_compare_op1 = operands[1];
2773   arm_compare_fp = 1;
2774   DONE;
2778 (define_expand "cmpdf"
2779   [(set (reg:CC 24)
2780         (compare:CC (match_operand:DF 0 "s_register_operand" "")
2781                     (match_operand:DF 1 "fpu_rhs_operand" "")))]
2782   ""
2783   "
2785   arm_compare_op0 = operands[0];
2786   arm_compare_op1 = operands[1];
2787   arm_compare_fp = 1;
2788   DONE;
2792 (define_expand "cmpxf"
2793   [(set (reg:CC 24)
2794         (compare:CC (match_operand:XF 0 "s_register_operand" "")
2795                     (match_operand:XF 1 "fpu_rhs_operand" "")))]
2796   "ENABLE_XF_PATTERNS"
2797   "
2799   arm_compare_op0 = operands[0];
2800   arm_compare_op1 = operands[1];
2801   arm_compare_fp = 1;
2802   DONE;
2806 (define_insn ""
2807   [(set (match_operand 0 "cc_register" "")
2808         (compare (match_operand:SI 1 "s_register_operand" "r,r")
2809                  (match_operand:SI 2 "arm_add_operand" "rI,L")))]
2810   ""
2811   "@
2812    cmp%?\\t%1, %2
2813    cmn%?\\t%1, #%n2"
2814 [(set_attr "conds" "set")])
2816 (define_insn ""
2817   [(set (match_operand 0 "cc_register" "")
2818         (compare (match_operand:SI 1 "s_register_operand" "r")
2819                  (neg:SI (match_operand:SI 2 "s_register_operand" "r"))))]
2820   ""
2821   "cmn%?\\t%1, %2"
2822 [(set_attr "conds" "set")])
2824 (define_insn ""
2825   [(set (match_operand 0 "cc_register" "")
2826         (compare (match_operand:SI 1 "s_register_operand" "r")
2827                  (match_operator:SI 2 "shift_operator"
2828                   [(match_operand:SI 3 "s_register_operand" "r")
2829                    (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
2830   ""
2831   "cmp%?\\t%1, %3%S2"
2832 [(set_attr "conds" "set")])
2834 (define_insn ""
2835   [(set (match_operand 0 "cc_register" "")
2836         (compare (match_operand:SI 1 "s_register_operand" "r")
2837                  (neg:SI (match_operator:SI 2 "shift_operator"
2838                           [(match_operand:SI 3 "s_register_operand" "r")
2839                            (match_operand:SI 4 "arm_rhs_operand" "rM")]))))]
2840   ""
2841   "cmn%?\\t%1, %3%S2"
2842 [(set_attr "conds" "set")])
2844 (define_insn ""
2845   [(set (reg:CCFP 24)
2846         (compare:CCFP (match_operand:SF 0 "s_register_operand" "f,f")
2847                       (match_operand:SF 1 "fpu_add_operand" "fG,H")))]
2848   ""
2849   "@
2850    cmf%?\\t%0, %1
2851    cnf%?\\t%0, #%N1"
2852 [(set_attr "conds" "set")
2853  (set_attr "type" "f_2_r")])
2855 (define_insn ""
2856   [(set (reg:CCFP 24)
2857         (compare:CCFP (match_operand:DF 0 "s_register_operand" "f,f")
2858                       (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
2859   ""
2860   "@
2861    cmf%?\\t%0, %1
2862    cnf%?\\t%0, #%N1"
2863 [(set_attr "conds" "set")
2864  (set_attr "type" "f_2_r")])
2866 (define_insn ""
2867   [(set (reg:CCFP 24)
2868         (compare:CCFP (float_extend:DF
2869                        (match_operand:SF 0 "s_register_operand" "f,f"))
2870                       (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
2871   ""
2872   "@
2873    cmf%?\\t%0, %1
2874    cnf%?\\t%0, #%N1"
2875 [(set_attr "conds" "set")
2876  (set_attr "type" "f_2_r")])
2878 (define_insn ""
2879   [(set (reg:CCFP 24)
2880         (compare:CCFP (match_operand:DF 0 "s_register_operand" "f")
2881                       (float_extend:DF
2882                        (match_operand:SF 1 "s_register_operand" "f"))))]
2883   ""
2884   "cmf%?\\t%0, %1"
2885 [(set_attr "conds" "set")
2886  (set_attr "type" "f_2_r")])
2888 (define_insn ""
2889   [(set (reg:CCFP 24)
2890         (compare:CCFP (match_operand:XF 0 "s_register_operand" "f,f")
2891                       (match_operand:XF 1 "fpu_add_operand" "fG,H")))]
2892   "ENABLE_XF_PATTERNS"
2893   "@
2894    cmf%?\\t%0, %1
2895    cnf%?\\t%0, #%N1"
2896 [(set_attr "conds" "set")
2897  (set_attr "type" "f_2_r")])
2899 (define_insn ""
2900   [(set (reg:CCFPE 24)
2901         (compare:CCFPE (match_operand:SF 0 "s_register_operand" "f,f")
2902                        (match_operand:SF 1 "fpu_add_operand" "fG,H")))]
2903   ""
2904   "@
2905    cmf%?e\\t%0, %1
2906    cnf%?e\\t%0, #%N1"
2907 [(set_attr "conds" "set")
2908  (set_attr "type" "f_2_r")])
2910 (define_insn ""
2911   [(set (reg:CCFPE 24)
2912         (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f,f")
2913                        (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
2914   ""
2915   "@
2916    cmf%?e\\t%0, %1
2917    cnf%?e\\t%0, #%N1"
2918 [(set_attr "conds" "set")
2919  (set_attr "type" "f_2_r")])
2921 (define_insn ""
2922   [(set (reg:CCFPE 24)
2923         (compare:CCFPE (float_extend:DF
2924                         (match_operand:SF 0 "s_register_operand" "f,f"))
2925                        (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
2926   ""
2927   "@
2928    cmf%?e\\t%0, %1
2929    cnf%?e\\t%0, #%N1"
2930 [(set_attr "conds" "set")
2931  (set_attr "type" "f_2_r")])
2933 (define_insn ""
2934   [(set (reg:CCFPE 24)
2935         (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f")
2936                        (float_extend:DF
2937                         (match_operand:SF 1 "s_register_operand" "f"))))]
2938   ""
2939   "cmf%?e\\t%0, %1"
2940 [(set_attr "conds" "set")
2941  (set_attr "type" "f_2_r")])
2943 (define_insn ""
2944   [(set (reg:CCFPE 24)
2945         (compare:CCFPE (match_operand:XF 0 "s_register_operand" "f,f")
2946                        (match_operand:XF 1 "fpu_add_operand" "fG,H")))]
2947   "ENABLE_XF_PATTERNS"
2948   "@
2949    cmf%?e\\t%0, %1
2950    cnf%?e\\t%0, #%N1"
2951 [(set_attr "conds" "set")
2952  (set_attr "type" "f_2_r")])
2954 ; This insn allows redundant compares to be removed by cse, nothing should
2955 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
2956 ; is deleted later on. The match_dup will match the mode here, so that
2957 ; mode changes of the condition codes aren't lost by this even though we don't
2958 ; specify what they are.
2960 (define_insn ""
2961   [(set (match_operand 0 "cc_register" "") (match_dup 0))]
2962   ""
2963   "\\t%@ deleted compare"
2964 [(set_attr "conds" "set")
2965  (set_attr "length" "0")])
2968 ;; Conditional branch insns
2970 (define_expand "beq"
2971   [(set (pc)
2972         (if_then_else (eq (match_dup 1) (const_int 0))
2973                       (label_ref (match_operand 0 "" ""))
2974                       (pc)))]
2975   ""
2976   "
2978   operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1,
2979                                  arm_compare_fp);
2983 (define_expand "bne"
2984   [(set (pc)
2985         (if_then_else (ne (match_dup 1) (const_int 0))
2986                       (label_ref (match_operand 0 "" ""))
2987                       (pc)))]
2988   ""
2989   "
2991   operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1,
2992                                  arm_compare_fp);
2996 (define_expand "bgt"
2997   [(set (pc)
2998         (if_then_else (gt (match_dup 1) (const_int 0))
2999                       (label_ref (match_operand 0 "" ""))
3000                       (pc)))]
3001   ""
3002   "
3004   operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1,
3005                                  arm_compare_fp);
3009 (define_expand "ble"
3010   [(set (pc)
3011         (if_then_else (le (match_dup 1) (const_int 0))
3012                       (label_ref (match_operand 0 "" ""))
3013                       (pc)))]
3014   ""
3015   "
3017   operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1,
3018                                  arm_compare_fp);
3022 (define_expand "bge"
3023   [(set (pc)
3024         (if_then_else (ge (match_dup 1) (const_int 0))
3025                       (label_ref (match_operand 0 "" ""))
3026                       (pc)))]
3027   ""
3028   "
3030   operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1,
3031                                  arm_compare_fp);
3035 (define_expand "blt"
3036   [(set (pc)
3037         (if_then_else (lt (match_dup 1) (const_int 0))
3038                       (label_ref (match_operand 0 "" ""))
3039                       (pc)))]
3040   ""
3041   "
3043   operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1,
3044                                  arm_compare_fp);
3048 (define_expand "bgtu"
3049   [(set (pc)
3050         (if_then_else (gtu (match_dup 1) (const_int 0))
3051                       (label_ref (match_operand 0 "" ""))
3052                       (pc)))]
3053   ""
3054   "
3056   operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1,
3057                                  arm_compare_fp);
3061 (define_expand "bleu"
3062   [(set (pc)
3063         (if_then_else (leu (match_dup 1) (const_int 0))
3064                       (label_ref (match_operand 0 "" ""))
3065                       (pc)))]
3066   ""
3067   "
3069   operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1,
3070                                  arm_compare_fp);
3074 (define_expand "bgeu"
3075   [(set (pc)
3076         (if_then_else (geu (match_dup 1) (const_int 0))
3077                       (label_ref (match_operand 0 "" ""))
3078                       (pc)))]
3079   ""
3080   "
3082   operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1,
3083                                  arm_compare_fp);
3087 (define_expand "bltu"
3088   [(set (pc)
3089         (if_then_else (ltu (match_dup 1) (const_int 0))
3090                       (label_ref (match_operand 0 "" ""))
3091                       (pc)))]
3092   ""
3093   "
3095   operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1,
3096                                  arm_compare_fp);
3100 ;; patterns to match conditional branch insns
3102 (define_insn ""
3103   [(set (pc)
3104         (if_then_else (match_operator 1 "comparison_operator"
3105                                         [(reg 24) (const_int 0)])
3106                       (label_ref (match_operand 0 "" ""))
3107                       (pc)))]
3108   ""
3109   "*
3111   extern int arm_ccfsm_state;
3113   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3114   {
3115     arm_ccfsm_state += 2;
3116     return \"\";
3117   }
3118   return \"b%d1\\t%l0\";
3120 [(set_attr "conds" "use")])
3122 (define_insn ""
3123   [(set (pc)
3124         (if_then_else (match_operator 1 "comparison_operator"
3125                                         [(reg 24) (const_int 0)])
3126                       (pc)
3127                       (label_ref (match_operand 0 "" ""))))]
3128   "REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
3129   "*
3131   extern int arm_ccfsm_state;
3133   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3134   {
3135     arm_ccfsm_state += 2;
3136     return \"\";
3137   }
3138   return \"b%D1\\t%l0\";
3140 [(set_attr "conds" "use")])
3143 ; scc insns
3145 (define_expand "seq"
3146   [(set (match_operand:SI 0 "s_register_operand" "=r")
3147         (eq:SI (match_dup 1) (const_int 0)))]
3148   ""
3149   "
3151   operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1,
3152                                  arm_compare_fp);
3156 (define_expand "sne"
3157   [(set (match_operand:SI 0 "s_register_operand" "=r")
3158         (ne:SI (match_dup 1) (const_int 0)))]
3159   ""
3160   "
3162   operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1,
3163                                  arm_compare_fp);
3167 (define_expand "sgt"
3168   [(set (match_operand:SI 0 "s_register_operand" "=r")
3169         (gt:SI (match_dup 1) (const_int 0)))]
3170   ""
3171   "
3173   operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1,
3174                                  arm_compare_fp);
3178 (define_expand "sle"
3179   [(set (match_operand:SI 0 "s_register_operand" "=r")
3180         (le:SI (match_dup 1) (const_int 0)))]
3181   ""
3182   "
3184   operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1,
3185                                  arm_compare_fp);
3189 (define_expand "sge"
3190   [(set (match_operand:SI 0 "s_register_operand" "=r")
3191         (ge:SI (match_dup 1) (const_int 0)))]
3192   ""
3193   "
3195   operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1,
3196                                  arm_compare_fp);
3200 (define_expand "slt"
3201   [(set (match_operand:SI 0 "s_register_operand" "=r")
3202         (lt:SI (match_dup 1) (const_int 0)))]
3203   ""
3204   "
3206   operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1,
3207                                  arm_compare_fp);
3211 (define_expand "sgtu"
3212   [(set (match_operand:SI 0 "s_register_operand" "=r")
3213         (gtu:SI (match_dup 1) (const_int 0)))]
3214   ""
3215   "
3217   operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1,
3218                                  arm_compare_fp);
3222 (define_expand "sleu"
3223   [(set (match_operand:SI 0 "s_register_operand" "=r")
3224         (leu:SI (match_dup 1) (const_int 0)))]
3225   ""
3226   "
3228   operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1,
3229                                  arm_compare_fp);
3233 (define_expand "sgeu"
3234   [(set (match_operand:SI 0 "s_register_operand" "=r")
3235         (geu:SI (match_dup 1) (const_int 0)))]
3236   ""
3237   "
3239   operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1,
3240                                  arm_compare_fp);
3244 (define_expand "sltu"
3245   [(set (match_operand:SI 0 "s_register_operand" "=r")
3246         (ltu:SI (match_dup 1) (const_int 0)))]
3247   ""
3248   "
3250   operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1,
3251                                  arm_compare_fp);
3255 (define_insn ""
3256   [(set (match_operand:SI 0 "s_register_operand" "=r")
3257         (match_operator:SI 1 "comparison_operator" [(reg 24) (const_int 0)]))]
3258   ""
3259   "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
3260 [(set_attr "conds" "use")
3261  (set_attr "length" "8")])
3263 (define_insn ""
3264   [(set (match_operand:SI 0 "s_register_operand" "=r")
3265         (neg:SI (match_operator:SI 1 "comparison_operator"
3266                  [(reg 24) (const_int 0)])))]
3267   ""
3268   "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
3269 [(set_attr "conds" "use")
3270  (set_attr "length" "8")])
3272 (define_insn ""
3273   [(set (match_operand:SI 0 "s_register_operand" "=r")
3274         (not:SI (match_operator:SI 1 "comparison_operator"
3275                  [(reg 24) (const_int 0)])))]
3276   ""
3277   "mov%D1\\t%0, #0\;mvn%d1\\t%0, #1"
3278 [(set_attr "conds" "use")
3279  (set_attr "length" "8")])
3282 ;; Jump and linkage insns
3284 (define_insn "jump"
3285   [(set (pc)
3286         (label_ref (match_operand 0 "" "")))]
3287   ""
3288   "*
3290   extern int arm_ccfsm_state;
3292   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3293   {
3294     arm_ccfsm_state += 2;
3295     return \"\";
3296   }
3297   return \"b%?\\t%l0\";
3300 (define_expand "call"
3301   [(parallel [(call (match_operand 0 "memory_operand" "")
3302                     (match_operand 1 "general_operand" ""))
3303               (clobber (reg:SI 14))])]
3304   ""
3305   "")
3307 (define_insn ""
3308   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
3309          (match_operand 1 "" "g"))
3310    (clobber (reg:SI 14))]
3311   ""
3312   "*
3313   return output_call (operands);
3315 [(set (attr "conds")
3316       (if_then_else (eq_attr "cpu" "arm6")
3317                     (const_string "clob")
3318                     (const_string "nocond")))
3319 ;; length is worst case, normally it is only two
3320  (set_attr "length" "12")
3321  (set_attr "type" "call")])
3323 (define_insn ""
3324   [(call (mem:SI (match_operand 0 "memory_operand" "m"))
3325          (match_operand 1 "general_operand" "g"))
3326    (clobber (reg:SI 14))]
3327   ""
3328   "*
3329   return output_call_mem (operands);
3331 [(set (attr "conds")
3332       (if_then_else (eq_attr "cpu" "arm6")
3333                     (const_string "clob")
3334                     (const_string "nocond")))
3335  (set_attr "length" "12")
3336  (set_attr "type" "call")])
3338 (define_expand "call_value"
3339   [(parallel [(set (match_operand 0 "" "=rf")
3340                    (call (match_operand 1 "memory_operand" "m")
3341                          (match_operand 2 "general_operand" "g")))
3342               (clobber (reg:SI 14))])]
3343   ""
3344   "")
3346 (define_insn ""
3347   [(set (match_operand 0 "" "=rf")
3348         (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
3349               (match_operand 2 "general_operand" "g")))
3350    (clobber (reg:SI 14))]
3351   ""
3352   "*
3353   return output_call (&operands[1]);
3355 [(set (attr "conds")
3356       (if_then_else (eq_attr "cpu" "arm6")
3357                     (const_string "clob")
3358                     (const_string "nocond")))
3359  (set_attr "length" "12")
3360  (set_attr "type" "call")])
3362 (define_insn ""
3363   [(set (match_operand 0 "" "=rf")
3364         (call (mem:SI (match_operand 1 "memory_operand" "m"))
3365         (match_operand 2 "general_operand" "g")))
3366    (clobber (reg:SI 14))]
3367   "! CONSTANT_ADDRESS_P (XEXP (operands[1], 0))"
3368   "*
3369   return output_call_mem (&operands[1]);
3371 [(set (attr "conds")
3372       (if_then_else (eq_attr "cpu" "arm6")
3373                     (const_string "clob")
3374                     (const_string "nocond")))
3375  (set_attr "length" "12")
3376  (set_attr "type" "call")])
3378 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
3379 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
3381 (define_insn ""
3382   [(call (mem:SI (match_operand:SI 0 "" "i"))
3383          (match_operand:SI 1 "general_operand" "g"))
3384    (clobber (reg:SI 14))]
3385   "GET_CODE (operands[0]) == SYMBOL_REF"
3386   "bl%?\\t%a0"
3387 [(set (attr "conds")
3388       (if_then_else (eq_attr "cpu" "arm6")
3389                     (const_string "clob")
3390                     (const_string "nocond")))
3391  (set_attr "type" "call")])
3393 (define_insn ""
3394   [(set (match_operand 0 "s_register_operand" "=rf")
3395         (call (mem:SI (match_operand:SI 1 "" "i"))
3396         (match_operand:SI 2 "general_operand" "g")))
3397    (clobber (reg:SI 14))]
3398   "GET_CODE(operands[1]) == SYMBOL_REF"
3399   "bl%?\\t%a1"
3400 [(set (attr "conds")
3401       (if_then_else (eq_attr "cpu" "arm6")
3402                     (const_string "clob")
3403                     (const_string "nocond")))
3404  (set_attr "type" "call")])
3406 ;; Often the return insn will be the same as loading from memory, so set attr
3407 (define_insn "return"
3408   [(return)]
3409   "USE_RETURN_INSN"
3410   "*
3412   extern int arm_ccfsm_state;
3414   if (arm_ccfsm_state == 2)
3415   {
3416     arm_ccfsm_state += 2;
3417     return \"\";
3418   }
3419   return output_return_instruction (NULL, TRUE);
3421 [(set_attr "type" "load")])
3423 (define_insn ""
3424   [(set (pc)
3425         (if_then_else (match_operator 0 "comparison_operator"
3426                        [(reg 24) (const_int 0)])
3427                       (return)
3428                       (pc)))]
3429   "USE_RETURN_INSN"
3430   "*
3432   extern int arm_ccfsm_state;
3434   if (arm_ccfsm_state == 2)
3435   {
3436     arm_ccfsm_state += 2;
3437     return \"\";
3438   }
3439   return output_return_instruction (operands[0], TRUE);
3441 [(set_attr "conds" "use")
3442  (set_attr "type" "load")])
3444 (define_insn ""
3445   [(set (pc)
3446         (if_then_else (match_operator 0 "comparison_operator"
3447                        [(reg 24) (const_int 0)])
3448                       (pc)
3449                       (return)))]
3450   "USE_RETURN_INSN"
3451   "*
3453   extern int arm_ccfsm_state;
3455   if (arm_ccfsm_state == 2)
3456   {
3457     arm_ccfsm_state += 2;
3458     return \"\";
3459   }
3460   return output_return_instruction 
3461         (gen_rtx (reverse_condition (GET_CODE (operands[0])),
3462                   GET_MODE (operands[0]), XEXP (operands[0], 0),
3463                   XEXP (operands[0], 1)),
3464          TRUE);
3466 [(set_attr "conds" "use")
3467  (set_attr "type" "load")])
3469 ;; Call subroutine returning any type.
3471 (define_expand "untyped_call"
3472   [(parallel [(call (match_operand 0 "" "")
3473                     (const_int 0))
3474               (match_operand 1 "" "")
3475               (match_operand 2 "" "")])]
3476   ""
3477   "
3479   int i;
3481   emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
3483   for (i = 0; i < XVECLEN (operands[2], 0); i++)
3484     {
3485       rtx set = XVECEXP (operands[2], 0, i);
3486       emit_move_insn (SET_DEST (set), SET_SRC (set));
3487     }
3489   /* The optimizer does not know that the call sets the function value
3490      registers we stored in the result block.  We avoid problems by
3491      claiming that all hard registers are used and clobbered at this
3492      point.  */
3493   emit_insn (gen_blockage ());
3495   DONE;
3498 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
3499 ;; all of memory.  This blocks insns from being moved across this point.
3501 (define_insn "blockage"
3502   [(unspec_volatile [(const_int 0)] 0)]
3503   ""
3504   ""
3505 [(set_attr "length" "0")
3506  (set_attr "type" "block")])
3508 (define_insn "tablejump"
3509   [(set (pc)
3510         (match_operand:SI 0 "s_register_operand" "r"))
3511    (use (label_ref (match_operand 1 "" "")))]
3512   ""
3513   "mov%?\\t%|pc, %0\\t%@ table jump, label %l1")
3515 (define_insn ""
3516   [(set (pc)
3517         (match_operand:SI 0 "memory_operand" "m"))
3518    (use (label_ref (match_operand 1 "" "")))]
3519   ""
3520   "ldr%?\\t%|pc, %0\\t%@ table jump, label %l1"
3521 [(set_attr "type" "load")])
3523 (define_insn "indirect_jump"
3524   [(set (pc)
3525         (match_operand:SI 0 "s_register_operand" "r"))]
3526   ""
3527   "mov%?\\t%|pc, %0\\t%@ indirect jump")
3529 (define_insn ""
3530   [(set (pc)
3531         (match_operand:SI 0 "memory_operand" "m"))]
3532   ""
3533   "ldr%?\\t%|pc, %0\\t%@ indirect jump"
3534 [(set_attr "type" "load")])
3536 ;; Misc insns
3538 (define_insn "nop"
3539   [(const_int 0)]
3540   ""
3541   "mov%?\\tr0, r0\\t%@ nop")
3543 ;; Patterns to allow combination of arithmetic, cond code and shifts
3545 (define_insn ""
3546   [(set (match_operand:SI 0 "s_register_operand" "=r")
3547         (match_operator:SI 1 "shiftable_operator"
3548           [(match_operator:SI 3 "shift_operator"
3549              [(match_operand:SI 4 "s_register_operand" "r")
3550               (match_operand:SI 5 "reg_or_int_operand" "rI")])
3551            (match_operand:SI 2 "s_register_operand" "r")]))]
3552   ""
3553   "%i1%?\\t%0, %2, %4%S3")
3555 (define_insn ""
3556   [(set (reg:CC_NOOV 24)
3557         (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
3558                           [(match_operator:SI 3 "shift_operator"
3559                             [(match_operand:SI 4 "s_register_operand" "r")
3560                              (match_operand:SI 5 "reg_or_int_operand" "rI")])
3561                            (match_operand:SI 2 "s_register_operand" "r")])
3562                          (const_int 0)))
3563    (set (match_operand:SI 0 "s_register_operand" "=r")
3564         (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
3565                          (match_dup 2)]))]
3566   ""
3567   "%i1%?s\\t%0, %2, %4%S3"
3568 [(set_attr "conds" "set")])
3570 (define_insn ""
3571   [(set (reg:CC_NOOV 24)
3572         (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
3573                           [(match_operator:SI 3 "shift_operator"
3574                             [(match_operand:SI 4 "s_register_operand" "r")
3575                              (match_operand:SI 5 "reg_or_int_operand" "rI")])
3576                            (match_operand:SI 2 "s_register_operand" "r")])
3577                          (const_int 0)))
3578    (clobber (match_scratch:SI 0 "=r"))]
3579   ""
3580   "%i1%?s\\t%0, %2, %4%S3"
3581 [(set_attr "conds" "set")])
3583 (define_insn ""
3584   [(set (match_operand:SI 0 "s_register_operand" "=r")
3585         (minus:SI (match_operand:SI 1 "s_register_operand" "r")
3586                   (match_operator:SI 2 "shift_operator"
3587                    [(match_operand:SI 3 "s_register_operand" "r")
3588                     (match_operand:SI 4 "reg_or_int_operand" "rM")])))]
3589   ""
3590   "sub%?\\t%0, %1, %3%S2")
3592 (define_insn ""
3593   [(set (reg:CC_NOOV 24)
3594         (compare:CC_NOOV
3595          (minus:SI (match_operand:SI 1 "s_register_operand" "r")
3596                    (match_operator:SI 2 "shift_operator"
3597                     [(match_operand:SI 3 "s_register_operand" "r")
3598                      (match_operand:SI 4 "reg_or_int_operand" "rM")]))
3599          (const_int 0)))
3600    (set (match_operand:SI 0 "s_register_operand" "=r")
3601         (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
3602                                                  (match_dup 4)])))]
3603   ""
3604   "sub%?s\\t%0, %1, %3%S2"
3605 [(set_attr "conds" "set")])
3607 (define_insn ""
3608   [(set (reg:CC_NOOV 24)
3609         (compare:CC_NOOV
3610          (minus:SI (match_operand:SI 1 "s_register_operand" "r")
3611                    (match_operator:SI 2 "shift_operator"
3612                     [(match_operand:SI 3 "s_register_operand" "r")
3613                      (match_operand:SI 4 "reg_or_int_operand" "rM")]))
3614          (const_int 0)))
3615    (clobber (match_scratch:SI 0 "=r"))]
3616   ""
3617   "sub%?s\\t%0, %1, %3%S2"
3618 [(set_attr "conds" "set")])
3620 ;; These variants of the above insns can occur if the first operand is the
3621 ;; frame pointer and we eliminate that.  This is a kludge, but there doesn't
3622 ;; seem to be a way around it.  Most of the predicates have to be null
3623 ;; because the format can be generated part way through reload, so
3624 ;; if we don't match it as soon as it becomes available, reload doesn't know
3625 ;; how to reload pseudos that haven't got hard registers; the constraints will
3626 ;; sort everything out.
3628 (define_insn ""
3629   [(set (match_operand:SI 0 "" "=&r")
3630         (plus:SI (plus:SI (match_operator:SI 5 "shift_operator"
3631                            [(match_operand:SI 3 "" "r")
3632                             (match_operand:SI 4 "" "rM")])
3633                           (match_operand:SI 2 "" "r"))
3634                  (match_operand:SI 1 "const_int_operand" "n")))]
3635   "reload_in_progress"
3636   "*
3637   output_asm_insn (\"add%?\\t%0, %2, %3%S5\", operands);
3638   operands[2] = operands[1];
3639   operands[1] = operands[0];
3640   return output_add_immediate (operands);
3642 ; we have no idea how long the add_immediate is, it could be up to 4.
3643 [(set_attr "length" "20")])
3645 (define_insn ""
3646   [(set (reg:CC_NOOV 24)
3647         (compare:CC_NOOV (plus:SI
3648                           (plus:SI 
3649                            (match_operator:SI 5 "shift_operator"
3650                             [(match_operand:SI 3 "" "r")
3651                              (match_operand:SI 4 "" "rM")])
3652                            (match_operand:SI 1 "" "r"))
3653                           (match_operand:SI 2 "const_int_operand" "n"))
3654                          (const_int 0)))
3655    (set (match_operand:SI 0 "" "=&r")
3656         (plus:SI (plus:SI (match_op_dup 5 [(match_dup 3) (match_dup 4)])
3657                           (match_dup 1))
3658                  (match_dup 2)))]
3659   "reload_in_progress"
3660   "*
3661   output_add_immediate (operands);
3662   return \"add%?s\\t%0, %0, %3%S5\";
3664 [(set_attr "conds" "set")
3665  (set_attr "length" "20")])
3667 (define_insn ""
3668   [(set (reg:CC_NOOV 24)
3669         (compare:CC_NOOV (plus:SI
3670                           (plus:SI 
3671                            (match_operator:SI 5 "shift_operator"
3672                             [(match_operand:SI 3 "" "r")
3673                              (match_operand:SI 4 "" "rM")])
3674                            (match_operand:SI 1 "" "r"))
3675                           (match_operand:SI 2 "const_int_operand" "n"))
3676                          (const_int 0)))
3677    (clobber (match_scratch:SI 0 "=&r"))]
3678   "reload_in_progress"
3679   "*
3680   output_add_immediate (operands);
3681   return \"add%?s\\t%0, %0, %3%S5\";
3683 [(set_attr "conds" "set")
3684  (set_attr "length" "20")])
3686 ;; These are similar, but are needed when the mla pattern contains the
3687 ;; eliminated register as operand 3.
3689 (define_insn ""
3690   [(set (match_operand:SI 0 "" "=&r,&r")
3691         (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "" "%0,r")
3692                                    (match_operand:SI 2 "" "r,r"))
3693                           (match_operand:SI 3 "" "r,r"))
3694                  (match_operand:SI 4 "const_int_operand" "n,n")))]
3695   "reload_in_progress"
3696   "*
3697   output_asm_insn (\"mla%?\\t%0, %2, %1, %3\", operands);
3698   operands[2] = operands[4];
3699   operands[1] = operands[0];
3700   return output_add_immediate (operands);
3702 [(set_attr "length" "20")])
3704 (define_insn ""
3705   [(set (reg:CC_NOOV 24)
3706         (compare:CC_NOOV (plus:SI (plus:SI (mult:SI
3707                                             (match_operand:SI 3 "" "r")
3708                                             (match_operand:SI 4 "" "r"))
3709                                            (match_operand:SI 1 "" "r"))
3710                                   (match_operand:SI 2 "const_int_operand" "n"))
3711                          (const_int 0)))
3712    (set (match_operand:SI 0 "" "=&r")
3713         (plus:SI (plus:SI (mult:SI (match_dup 3) (match_dup 4)) (match_dup 1))
3714                  (match_dup 2)))]
3715   "reload_in_progress"
3716   "*
3717   output_add_immediate (operands);
3718   output_asm_insn (\"mla%?s\\t%0, %3, %4, %0\", operands);
3719   return \"\";
3721 [(set_attr "length" "20")
3722  (set_attr "conds" "set")])
3724 (define_insn ""
3725   [(set (reg:CC_NOOV 24)
3726         (compare:CC_NOOV (plus:SI (plus:SI (mult:SI
3727                                             (match_operand:SI 3 "" "r")
3728                                             (match_operand:SI 4 "" "r"))
3729                                            (match_operand:SI 1 "" "r"))
3730                                   (match_operand:SI 2 "const_int_operand" "n"))
3731                          (const_int 0)))
3732    (clobber (match_scratch:SI 0 "=&r"))]
3733   "reload_in_progress"
3734   "*
3735   output_add_immediate (operands);
3736   return \"mla%?s\\t%0, %3, %4, %0\";
3738 [(set_attr "length" "20")
3739  (set_attr "conds" "set")])
3744 (define_insn ""
3745   [(set (match_operand:SI 0 "s_register_operand" "=r")
3746         (and:SI (match_operator 1 "comparison_operator"
3747                  [(match_operand 3 "reversible_cc_register" "") (const_int 0)])
3748                 (match_operand:SI 2 "s_register_operand" "r")))]
3749   ""
3750   "mov%D1\\t%0, #0\;and%d1\\t%0, %2, #1"
3751 [(set_attr "conds" "use")
3752  (set_attr "length" "8")])
3754 (define_insn ""
3755   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3756         (ior:SI (match_operator 2 "comparison_operator"
3757                  [(reg 24) (const_int 0)])
3758                 (match_operand:SI 1 "s_register_operand" "0,?r")))]
3759   ""
3760   "@
3761    orr%d2\\t%0, %1, #1
3762    mov%D2\\t%0, %1\;orr%d2\\t%0, %1, #1"
3763 [(set_attr "conds" "use")
3764  (set_attr "length" "4,8")])
3766 (define_insn ""
3767   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3768         (match_operator 1 "comparison_operator"
3769          [(match_operand:SI 2 "s_register_operand" "r,r")
3770           (match_operand:SI 3 "arm_add_operand" "rI,L")]))
3771    (clobber (reg 24))]
3772   ""
3773   "*
3774   if (GET_CODE (operands[1]) == LT && operands[3] == const0_rtx)
3775     return \"mov\\t%0, %2, lsr #31\";
3777   if (GET_CODE (operands[1]) == GE && operands[3] == const0_rtx)
3778     return \"mvn\\t%0, %2\;mov\\t%0, %0, lsr #31\";
3780   if (GET_CODE (operands[1]) == NE)
3781     {
3782       if (which_alternative == 1)
3783         return \"adds\\t%0, %2, #%n3\;movne\\t%0, #1\";
3784       return \"subs\\t%0, %2, %3\;movne\\t%0, #1\";
3785     }
3786   if (which_alternative == 1)
3787     output_asm_insn (\"cmn\\t%2, #%n3\", operands);
3788   else
3789     output_asm_insn (\"cmp\\t%2, %3\", operands);
3790   return \"mov%D1\\t%0, #0\;mov%d1\\t%0, #1\";
3792 [(set_attr "conds" "clob")
3793  (set_attr "length" "12")])
3795 (define_insn ""
3796   [(set (match_operand:SI 0 "s_register_operand" "=&r")
3797         (ior:SI (match_operator 1 "comparison_operator"
3798                  [(match_operand:SI 2 "s_register_operand" "r")
3799                   (match_operand:SI 3 "arm_rhs_operand" "rI")])
3800                 (match_operator 4 "comparison_operator"
3801                  [(match_operand:SI 5 "s_register_operand" "r")
3802                   (match_operand:SI 6 "arm_rhs_operand" "rI")])))
3803    (clobber (reg 24))]
3804   ""
3805   "*
3807   int dominant = comparison_dominates_p (GET_CODE (operands[4]),
3808                                          GET_CODE (operands[1]));
3810   output_asm_insn (dominant ? \"cmp\\t%5, %6\" : \"cmp\\t%2, %3\",
3811                    operands);
3812   output_asm_insn (\"mov\\t%0, #0\", operands);
3813   if (GET_CODE (operands[1]) == GET_CODE (operands[4])
3814       || comparison_dominates_p (GET_CODE (operands[1]),
3815                                  GET_CODE (operands[4]))
3816       || dominant)
3817     output_asm_insn (dominant ? \"cmp%D4\\t%2, %3\" : \"cmp%D1\\t%5,%6\",
3818                      operands);
3819   else
3820     output_asm_insn (\"mov%d1\\t%0, #1\;cmp\\t%5, %6\", operands);
3821   return dominant ? \"mov%d1\\t%0, #1\" : \"mov%d4\\t%0, #1\";
3824 [(set_attr "conds" "clob")
3825 ; worst case length
3826  (set_attr "length" "20")])
3828 (define_split
3829   [(set (pc)
3830         (if_then_else
3831          (match_operator 5 "equality_operator"
3832           [(ior:SI (match_operator 6 "comparison_operator"
3833                     [(match_operand:SI 0 "s_register_operand" "")
3834                      (match_operand:SI 1 "arm_add_operand" "")])
3835                    (match_operator 7 "comparison_operator"
3836                     [(match_operand:SI 2 "s_register_operand" "")
3837                      (match_operand:SI 3 "arm_add_operand" "")]))
3838           (const_int 0)])
3839          (label_ref (match_operand 4 "" ""))
3840          (pc)))
3841    (clobber (reg 24))]
3842   "(GET_CODE (operands[6]) == GET_CODE (operands[7])
3843     || comparison_dominates_p (GET_CODE (operands[6]), GET_CODE (operands[7]))
3844     || comparison_dominates_p (GET_CODE (operands[7]), GET_CODE (operands[6])))"
3845   [(set (reg:CC 24)
3846         (compare:CC (ior:CC (match_op_dup 6
3847                              [(match_dup 0) (match_dup 1)])
3848                             (match_op_dup 7
3849                              [(match_dup 2) (match_dup 3)]))
3850                     (const_int 0)))
3851    (set (pc)
3852         (if_then_else (match_op_dup 5 [(reg:CC 24) (const_int 0)])
3853                       (label_ref (match_dup 4))
3854                       (pc)))]
3855   "
3857   enum rtx_code code = comparison_dominates_p (GET_CODE (operands[6]),
3858                                                GET_CODE (operands[7]))
3859                        ? GET_CODE (operands[7]) : GET_CODE (operands[6]);
3861   if (GET_CODE (operands[5]) == NE)
3862     operands[5] = gen_rtx (code, CCmode,
3863                            XEXP (operands[5], 0), XEXP (operands[5], 1));
3864   else
3865     operands[5] = gen_rtx (reverse_condition (code), CCmode,
3866                            XEXP (operands[5], 0), XEXP (operands[5], 1));
3870 ;; Don't match these patterns if we can use a conditional compare, since they
3871 ;; tell the final prescan branch elimator code that full branch inlining
3872 ;; can't be done.
3874 (define_insn ""
3875   [(set (pc)
3876         (if_then_else
3877          (ne (ior:SI (match_operator 5 "comparison_operator"
3878                       [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
3879                        (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
3880                      (match_operator 6 "comparison_operator"
3881                       [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
3882                        (match_operand:SI 3 "arm_rhs_operand" "rI,rI,L,L")]))
3883              (const_int 0))
3884          (label_ref (match_operand 4 "" ""))
3885          (pc)))
3886    (clobber (reg 24))]
3887   "!(GET_CODE (operands[5]) == GET_CODE (operands[6])
3888      || comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[6]))
3889      || comparison_dominates_p (GET_CODE (operands[6]), GET_CODE (operands[5])))"
3890   "*
3892   extern int arm_ccfsm_state;
3894   if (which_alternative & 1)
3895     output_asm_insn (\"cmn\\t%0, #%n1\;b%d5\\t%l4\", operands);
3896   else
3897     output_asm_insn (\"cmp\\t%0, %1\;b%d5\\t%l4\", operands);
3899   if (which_alternative >= 2)
3900     output_asm_insn (\"cmn\\t%2, #%n3\", operands);
3901   else
3902     output_asm_insn (\"cmp\\t%2, %3\", operands);
3904   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3905   {
3906     arm_ccfsm_state += 2;
3907     return \"\";
3908   }
3909   return \"b%d6\\t%l4\";
3911 [(set_attr "conds" "jump_clob")
3912  (set_attr "length" "16")])
3914 (define_insn ""
3915   [(set (reg:CC 24)
3916         (compare:CC
3917          (ior:CC (match_operator 4 "comparison_operator"
3918                   [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
3919                    (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
3920                  (match_operator 5 "comparison_operator"
3921                   [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
3922                    (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")]))
3923          (const_int 0)))]
3924   "(GET_CODE (operands[4]) == GET_CODE (operands[5])
3925     || comparison_dominates_p (GET_CODE (operands[4]), GET_CODE (operands[5]))
3926     || comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])))"
3927   "*
3928   if (comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])))
3929     {
3930       if (which_alternative >= 2)
3931         output_asm_insn (\"cmn\\t%2, #%n3\", operands);
3932       else
3933         output_asm_insn (\"cmp\\t%2, %3\", operands);
3935       if (which_alternative & 1)
3936         return \"cmn%D5\\t%0, #%n1\";
3937       return \"cmp%D5\\t%0, %1\";
3938     }
3940   if (which_alternative & 1)
3941     output_asm_insn (\"cmn\\t%0, #%n1\", operands);
3942   else
3943     output_asm_insn (\"cmp\\t%0, %1\", operands);
3945   if (which_alternative >= 2)
3946     return \"cmn%D4\\t%2, #%n3\";
3947   return \"cmp%D4\\t%2, %3\";
3949 [(set_attr "conds" "set")
3950  (set_attr "length" "8")])
3952 (define_insn ""
3953   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3954         (if_then_else (match_operator 3 "equality_operator"
3955                        [(match_operator 4 "comparison_operator"
3956                          [(reg 24) (const_int 0)])
3957                         (const_int 0)])
3958                       (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
3959                       (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
3960   ""
3961   "*
3962   if (GET_CODE (operands[3]) == NE)
3963     {
3964       if (which_alternative != 1)
3965         output_asm_insn (\"mov%D4\\t%0, %2\", operands);
3966       if (which_alternative != 0)
3967         output_asm_insn (\"mov%d4\\t%0, %1\", operands);
3968       return \"\";
3969     }
3970   if (which_alternative != 0)
3971     output_asm_insn (\"mov%D4\\t%0, %1\", operands);
3972   if (which_alternative != 1)
3973     output_asm_insn (\"mov%d4\\t%0, %2\", operands);
3974   return \"\";
3976 [(set_attr "conds" "use")
3977  (set_attr "length" "4,4,8")])
3979 (define_insn ""
3980   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3981         (match_operator:SI 5 "shiftable_operator" 
3982          [(match_operator:SI 4 "comparison_operator"
3983            [(match_operand:SI 2 "s_register_operand" "r,r")
3984             (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3985           (match_operand:SI 1 "s_register_operand" "0,?r")]))
3986    (clobber (reg 24))]
3987   ""
3988   "*
3989   if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
3990     return \"%i5\\t%0, %1, %2, lsr #31\";
3992   output_asm_insn (\"cmp\\t%2, %3\", operands);
3993   if (GET_CODE (operands[5]) == AND)
3994     output_asm_insn (\"mov%D4\\t%0, #0\", operands);
3995   else if (which_alternative != 0)
3996     output_asm_insn (\"mov%D4\\t%0, %1\", operands);
3997   return \"%i5%d4\\t%0, %1, #1\";
3999 [(set_attr "conds" "clob")
4000  (set_attr "length" "12")])
4002 (define_insn ""
4003   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4004         (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
4005                   (match_operator:SI 4 "comparison_operator"
4006                    [(match_operand:SI 2 "s_register_operand" "r,r")
4007                     (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
4008    (clobber (reg 24))]
4009   ""
4010   "*
4011   output_asm_insn (\"cmp\\t%2, %3\", operands);
4012   if (which_alternative != 0)
4013     output_asm_insn (\"mov%D4\\t%0, %1\", operands);
4014   return \"sub%d4\\t%0, %1, #1\";
4016 [(set_attr "conds" "clob")
4017  (set_attr "length" "8,12")])
4019 (define_insn ""
4020   [(set (match_operand:SI 0 "s_register_operand" "=&r")
4021         (and:SI (match_operator 1 "comparison_operator"
4022                  [(match_operand:SI 2 "s_register_operand" "r")
4023                   (match_operand:SI 3 "arm_rhs_operand" "rI")])
4024                 (match_operator 4 "comparison_operator"
4025                  [(match_operand:SI 5 "s_register_operand" "r")
4026                   (match_operand:SI 6 "arm_rhs_operand" "rI")])))
4027    (clobber (reg 24))]
4028   ""
4029   "*
4031   int dominant =
4032         comparison_dominates_p (reverse_condition (GET_CODE (operands[1])),
4033                                 reverse_condition (GET_CODE (operands[4])))
4034         ? 1 
4035         : comparison_dominates_p (reverse_condition (GET_CODE (operands[4])),
4036                                   reverse_condition (GET_CODE (operands[1])))
4037         ? 2 : 0;
4038   output_asm_insn (dominant == 2 ? \"cmp\\t%5, %6\" : \"cmp\\t%2, %3\",
4039                        operands);
4040   output_asm_insn (\"mov\\t%0, #1\", operands);
4041   if (GET_CODE (operands[1]) == GET_CODE (operands[4]) || dominant)
4042     {
4043       output_asm_insn (dominant == 2 ? \"cmp%d4\\t%2, %3\"
4044                            : \"cmp%d1\\t%5, %6\", operands);
4045     }
4046   else
4047     {
4048       output_asm_insn (\"mov%D1\\t%0, #0\", operands);
4049       output_asm_insn (\"cmp\\t%5, %6\", operands);
4050     }
4051   return dominant == 2 ? \"mov%D1\\t%0, #0\" : \"mov%D4\\t%0, #0\";
4054 [(set_attr "conds" "clob")
4055  (set_attr "length" "20")])
4057 (define_split
4058   [(set (pc)
4059         (if_then_else (match_operator 1 "equality_operator"
4060                        [(and:SI (match_operator 2 "comparison_operator"
4061                                  [(match_operand:SI 3 "s_register_operand" "")
4062                                   (match_operand:SI 4 "arm_add_operand" "")])
4063                                 (match_operator 0 "comparison_operator"
4064                                  [(match_operand:SI 5 "s_register_operand" "")
4065                                   (match_operand:SI 6 "arm_add_operand" "")]))
4066                         (const_int 0)])
4067                       (label_ref (match_operand 7 "" ""))
4068                       (pc)))
4069    (clobber (reg 24))]
4070   "(GET_CODE (operands[2]) == GET_CODE (operands[0])
4071     || comparison_dominates_p (reverse_condition (GET_CODE (operands[2])),
4072                                reverse_condition (GET_CODE (operands[0])))
4073     || comparison_dominates_p (reverse_condition (GET_CODE (operands[0])),
4074                                reverse_condition (GET_CODE (operands[2]))))"
4075   [(set (reg:CC 24)
4076         (compare:CC (ior:CC (match_op_dup 2
4077                              [(match_dup 3) (match_dup 4)])
4078                             (match_op_dup 0
4079                              [(match_dup 5) (match_dup 6)]))
4080                     (const_int 0)))
4081    (set (pc)
4082         (if_then_else (match_op_dup 1 [(reg:CC 24) (const_int 0)])
4083                       (label_ref (match_dup 7))
4084                       (pc)))]
4085   "
4087   /* Use DeMorgans law to convert this into an IOR of the inverse conditions 
4088      This is safe since we only do it for integer comparisons. */
4089   enum rtx_code code = 
4090         comparison_dominates_p (reverse_condition (GET_CODE (operands[2])),
4091                                 reverse_condition (GET_CODE (operands[0])))
4092         ? GET_CODE (operands[0]) : GET_CODE (operands[2]);
4094   operands[2] = gen_rtx (reverse_condition (GET_CODE (operands[2])),
4095                          GET_MODE (operands[2]), operands[3], operands[4]);
4096   operands[0] = gen_rtx (reverse_condition (GET_CODE (operands[0])),
4097                          GET_MODE (operands[0]), operands[5], operands[6]);
4098   if (GET_CODE (operands[1]) == NE)
4099     operands[1] = gen_rtx (code, CCmode,
4100                            XEXP (operands[1], 0), XEXP (operands[1], 1));
4101   else
4102     operands[1] = gen_rtx (reverse_condition (code), CCmode,
4103                            XEXP (operands[1], 0), XEXP (operands[1], 1));
4107 ;; Don't match these patterns if we can use a conditional compare, since they
4108 ;; tell the final prescan branch elimator code that full branch inlining
4109 ;; can't be done.
4111 (define_insn ""
4112   [(set (pc)
4113         (if_then_else
4114          (eq (and:SI (match_operator 1 "comparison_operator"
4115                       [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
4116                        (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L")])
4117                      (match_operator 4 "comparison_operator"
4118                       [(match_operand:SI 5 "s_register_operand" "r,r,r,r")
4119                        (match_operand:SI 6 "arm_rhs_operand" "rI,rI,L,L")]))
4120              (const_int 0))
4121          (label_ref (match_operand 0 "" ""))
4122          (pc)))
4123    (clobber (reg 24))]
4124   "!(GET_CODE (operands[1]) == GET_CODE (operands[4])
4125      || comparison_dominates_p (reverse_condition (GET_CODE (operands[1])),
4126                                 reverse_condition (GET_CODE (operands[4])))
4127      || comparison_dominates_p (reverse_condition (GET_CODE (operands[4])),
4128                                 reverse_condition (GET_CODE (operands[1]))))"
4129   "*
4131   extern int arm_ccfsm_state;
4133   if (which_alternative & 1)
4134     output_asm_insn (\"cmn\\t%2, #%n3\;b%D1\\t%l0\", operands);
4135   else
4136     output_asm_insn (\"cmp\\t%2, %3\;b%D1\\t%l0\", operands);
4138   if (which_alternative >= 2)
4139     output_asm_insn (\"cmn\\t%5, #%n6\", operands);
4140   else
4141     output_asm_insn (\"cmp\\t%5, %6\", operands);
4143   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
4144   {
4145     arm_ccfsm_state += 2;
4146     return \"\";
4147   }
4148   return \"b%D4\\t%l0\";
4150 [(set_attr "conds" "jump_clob")
4151  (set_attr "length" "16")])
4153 (define_insn ""
4154   [(set (match_operand:SI 0 "s_register_operand" "=r")
4155         (neg:SI (match_operator 3 "comparison_operator"
4156                  [(match_operand:SI 1 "s_register_operand" "r")
4157                   (match_operand:SI 2 "arm_rhs_operand" "rI")])))
4158    (clobber (reg 24))]
4159   ""
4160   "*
4161   if (GET_CODE (operands[3]) == LT && operands[3] == const0_rtx)
4162     return \"mov\\t%0, %1, asr #31\";
4164   if (GET_CODE (operands[3]) == NE)
4165     return \"subs\\t%0, %1, %2\;mvnne\\t%0, #0\";
4167   if (GET_CODE (operands[3]) == GT)
4168     return \"subs\\t%0, %1, %2\;mvnne\\t%0, %0, asr #31\";
4170   output_asm_insn (\"cmp\\t%1, %2\", operands);
4171   output_asm_insn (\"mov%D3\\t%0, #0\", operands);
4172   return \"mvn%d3\\t%0, #0\";
4174 [(set_attr "conds" "clob")
4175  (set_attr "length" "12")])
4177 (define_insn "movcond"
4178   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
4179         (if_then_else:SI
4180          (match_operator 5 "comparison_operator"
4181           [(match_operand:SI 3 "s_register_operand" "r,r,r")
4182            (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
4183          (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
4184          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
4185    (clobber (reg 24))]
4186   ""
4187   "*
4188   if (GET_CODE (operands[5]) == LT
4189       && (operands[4] == const0_rtx))
4190     {
4191       if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
4192         {
4193           if (operands[2] == const0_rtx)
4194             return \"and\\t%0, %1, %3, asr #31\";
4195           return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
4196         }
4197       else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
4198         {
4199           if (operands[1] == const0_rtx)
4200             return \"bic\\t%0, %2, %3, asr #31\";
4201           return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
4202         }
4203       /* The only case that falls through to here is when both ops 1 & 2
4204          are constants */
4205     }
4207   if (GET_CODE (operands[5]) == GE
4208       && (operands[4] == const0_rtx))
4209     {
4210       if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
4211         {
4212           if (operands[2] == const0_rtx)
4213             return \"bic\\t%0, %1, %3, asr #31\";
4214           return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
4215         }
4216       else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
4217         {
4218           if (operands[1] == const0_rtx)
4219             return \"and\\t%0, %2, %3, asr #31\";
4220           return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
4221         }
4222       /* The only case that falls through to here is when both ops 1 & 2
4223          are constants */
4224     }
4225   if (GET_CODE (operands[4]) == CONST_INT
4226       && !const_ok_for_arm (INTVAL (operands[4])))
4227     output_asm_insn (\"cmn\\t%3, #%n4\", operands);
4228   else
4229     output_asm_insn (\"cmp\\t%3, %4\", operands);
4230   if (which_alternative != 0)
4231     output_asm_insn (\"mov%d5\\t%0, %1\", operands);
4232   if (which_alternative != 1)
4233     output_asm_insn (\"mov%D5\\t%0, %2\", operands);
4234   return \"\";
4236 [(set_attr "conds" "clob")
4237  (set_attr "length" "8,8,12")])
4239 (define_insn ""
4240   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4241         (if_then_else:SI (match_operator 9 "comparison_operator"
4242                           [(match_operand:SI 5 "s_register_operand" "r,r")
4243                            (match_operand:SI 6 "arm_add_operand" "rI,L")])
4244                          (match_operator:SI 8 "shiftable_operator"
4245                           [(match_operand:SI 1 "s_register_operand" "r,r")
4246                            (match_operand:SI 2 "arm_rhs_operand" "rI,rI")])
4247                          (match_operator:SI 7 "shiftable_operator"
4248                           [(match_operand:SI 3 "s_register_operand" "r,r")
4249                            (match_operand:SI 4 "arm_rhs_operand" "rI,rI")])))
4250    (clobber (reg 24))]
4251   ""
4252   "@
4253    cmp\\t%5, %6\;%I8%d9\\t%0, %1, %2\;%I7%D9\\t%0, %3, %4
4254    cmn\\t%5, #%n6\;%I8%d9\\t%0, %1, %2\;%I7%D9\\t%0, %3, %4"
4255 [(set_attr "conds" "clob")
4256  (set_attr "length" "12")])
4258 (define_insn ""
4259   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4260         (if_then_else:SI (match_operator 6 "comparison_operator"
4261                           [(match_operand:SI 2 "s_register_operand" "r,r")
4262                            (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
4263                          (match_operator:SI 7 "shiftable_operator"
4264                           [(match_operand:SI 4 "s_register_operand" "r,r")
4265                            (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
4266                          (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")))
4267    (clobber (reg 24))]
4268   ""
4269   "*
4270   /* If we have an operation where (op x 0) is the identity operation and
4271      the condtional operator is LT or GE and we are comparing against zero and
4272      everything is in registers then we can do this in two instructions */
4273   if (operands[3] == const0_rtx
4274       && GET_CODE (operands[7]) != AND
4275       && GET_CODE (operands[5]) == REG
4276       && GET_CODE (operands[1]) == REG 
4277       && REGNO (operands[1]) == REGNO (operands[4])
4278       && REGNO (operands[4]) != REGNO (operands[0]))
4279     {
4280       if (GET_CODE (operands[6]) == LT)
4281         return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
4282       else if (GET_CODE (operands[6]) == GE)
4283         return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
4284     }
4285   if (GET_CODE (operands[3]) == CONST_INT
4286       && !const_ok_for_arm (INTVAL (operands[3])))
4287     output_asm_insn (\"cmn\\t%2, #%n3\", operands);
4288   else
4289     output_asm_insn (\"cmp\\t%2, %3\", operands);
4290   output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
4291   if (which_alternative != 0)
4292     {
4293       if (GET_CODE (operands[1]) == MEM)
4294         return \"ldr%D6\\t%0, %1\";
4295       else
4296         return \"mov%D6\\t%0, %1\";
4297     }
4298   return \"\";
4300 [(set_attr "conds" "clob")
4301  (set_attr "length" "8,12")])
4303 (define_insn ""
4304   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4305         (if_then_else:SI (match_operator 6 "comparison_operator"
4306                           [(match_operand:SI 4 "s_register_operand" "r,r")
4307                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
4308                          (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")
4309                          (match_operator:SI 7 "shiftable_operator"
4310                           [(match_operand:SI 2 "s_register_operand" "r,r")
4311                            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
4312    (clobber (reg 24))]
4313   ""
4314   "*
4315   /* If we have an operation where (op x 0) is the identity operation and
4316      the condtional operator is LT or GE and we are comparing against zero and
4317      everything is in registers then we can do this in two instructions */
4318   if (operands[5] == const0_rtx
4319       && GET_CODE (operands[7]) != AND
4320       && GET_CODE (operands[3]) == REG
4321       && GET_CODE (operands[1]) == REG 
4322       && REGNO (operands[1]) == REGNO (operands[2])
4323       && REGNO (operands[2]) != REGNO (operands[0]))
4324     {
4325       if (GET_CODE (operands[6]) == GE)
4326         return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
4327       else if (GET_CODE (operands[6]) == LT)
4328         return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
4329     }
4331   if (GET_CODE (operands[5]) == CONST_INT
4332       && !const_ok_for_arm (INTVAL (operands[5])))
4333     output_asm_insn (\"cmn\\t%4, #%n5\", operands);
4334   else
4335     output_asm_insn (\"cmp\\t%4, %5\", operands);
4337   if (which_alternative != 0)
4338     {
4339       if (GET_CODE (operands[1]) == MEM)
4340         output_asm_insn (\"ldr%d6\\t%0, %1\", operands);
4341       else
4342         output_asm_insn (\"mov%d6\\t%0, %1\", operands);
4343     }
4344   return \"%I7%D6\\t%0, %2, %3\";
4346 [(set_attr "conds" "clob")
4347  (set_attr "length" "8,12")])
4349 (define_insn ""
4350   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4351         (if_then_else:SI (match_operator 6 "comparison_operator"
4352                           [(match_operand:SI 4 "s_register_operand" "r,r")
4353                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
4354                          (plus:SI
4355                           (match_operand:SI 2 "s_register_operand" "r,r")
4356                           (match_operand:SI 3 "arm_add_operand" "rL,rL"))
4357                          (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")))
4358    (clobber (reg 24))]
4359   ""
4360   "*
4362   if (GET_CODE (operands[5]) == CONST_INT
4363       && !const_ok_for_arm (INTVAL (operands[5])))
4364     output_asm_insn (\"cmn\\t%4, #%n5\", operands);
4365   else
4366     output_asm_insn (\"cmp\\t%4, %5\", operands);
4367   if (GET_CODE (operands[3]) == CONST_INT
4368       && !const_ok_for_arm (INTVAL (operands[3])))
4369     output_asm_insn (\"sub%d6\\t%0, %2, #%n3\", operands);
4370   else
4371     output_asm_insn (\"add%d6\\t%0, %2, %3\", operands);
4372   if (which_alternative != 0)
4373     {
4374       if (GET_CODE (operands[1]) == MEM)
4375         output_asm_insn (\"ldr%D6\\t%0, %1\", operands);
4376       else
4377         output_asm_insn (\"mov%D6\\t%0, %1\", operands);
4378     }
4379   return \"\";
4382 [(set_attr "conds" "clob")
4383  (set_attr "length" "8,12")])
4385 (define_insn ""
4386   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4387         (if_then_else:SI (match_operator 6 "comparison_operator"
4388                           [(match_operand:SI 4 "s_register_operand" "r,r")
4389                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
4390                          (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")
4391                          (plus:SI
4392                           (match_operand:SI 2 "s_register_operand" "r,r")
4393                           (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
4394    (clobber (reg 24))]
4395   ""
4396   "*
4398   if (GET_CODE (operands[5]) == CONST_INT
4399       && !const_ok_for_arm (INTVAL (operands[5])))
4400     output_asm_insn (\"cmn\\t%4, #%n5\", operands);
4401   else
4402     output_asm_insn (\"cmp\\t%4, %5\", operands);
4403   if (GET_CODE (operands[3]) == CONST_INT
4404       && !const_ok_for_arm (INTVAL (operands[3])))
4405     output_asm_insn (\"sub%D6\\t%0, %2, #%n3\", operands);
4406   else
4407     output_asm_insn (\"add%D6\\t%0, %2, %3\", operands);
4408   if (which_alternative != 0)
4409     {
4410       if (GET_CODE (operands[6]) == MEM)
4411         output_asm_insn (\"ldr%d6\\t%0, %1\", operands);
4412       else
4413         output_asm_insn (\"mov%d6\\t%0, %1\", operands);
4414     }
4415   return \"\";
4418 [(set_attr "conds" "clob")
4419  (set_attr "length" "8,12")])
4421 (define_insn ""
4422   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4423         (if_then_else:SI (match_operator 5 "comparison_operator"
4424                           [(match_operand:SI 3 "s_register_operand" "r,r")
4425                            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
4426                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
4427                          (not:SI
4428                           (match_operand:SI 2 "s_register_operand" "r,r"))))
4429    (clobber (reg 24))]
4430   ""
4431   "#"
4432 [(set_attr "conds" "clob")
4433  (set_attr "length" "8,12")])
4435 (define_insn ""
4436   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4437         (if_then_else:SI 
4438          (match_operator 5 "comparison_operator"
4439           [(match_operand:SI 3 "s_register_operand" "r,r,r,r")
4440            (match_operand:SI 4 "arm_add_operand" "rI,L,rI,L")])
4441          (not:SI
4442           (match_operand:SI 2 "s_register_operand" "r,r,r,r"))
4443          (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))
4444    (clobber (reg 24))]
4445   ""
4446   "@
4447    cmp\\t%3, %4\;mvn%d5\\t%0, %2
4448    cmn\\t%3, #%n4\;mvn%d5\\t%0, %2
4449    cmp\\t%3, %4\;mov%D5\\t%0, %1\;mvn%d5\\t%0, %2
4450    cmn\\t%3, #%n4\;mov%D5\\t%0, %1\;mvn%d5\\t%0, %2"
4451 [(set_attr "conds" "clob")
4452  (set_attr "length" "8,8,12,12")])
4454 (define_insn ""
4455   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4456         (if_then_else:SI
4457          (match_operator 6 "comparison_operator"
4458           [(match_operand:SI 4 "s_register_operand" "r,r,r,r")
4459            (match_operand:SI 5 "arm_add_operand" "rI,L,rI,L")])
4460          (match_operator:SI 7 "shift_operator"
4461           [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
4462            (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM,rM")])
4463          (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))
4464    (clobber (reg 24))]
4465   ""
4466   "@
4467    cmp\\t%4, %5\;mov%d6\\t%0, %2%S7
4468    cmn\\t%4, #%n5\;mov%d6\\t%0, %2%S7
4469    cmp\\t%4, %5\;mov%D6\\t%0, %1\;mov%d6\\t%0, %2%S7
4470    cmn\\t%4, #%n5\;mov%D6\\t%0, %1\;mov%d6\\t%0, %2%S7"
4471 [(set_attr "conds" "clob")
4472  (set_attr "length" "8,8,12,12")])
4474 (define_insn ""
4475   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4476         (if_then_else:SI
4477          (match_operator 6 "comparison_operator"
4478           [(match_operand:SI 4 "s_register_operand" "r,r,r,r")
4479            (match_operand:SI 5 "arm_add_operand" "rI,L,rI,L")])
4480          (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
4481          (match_operator:SI 7 "shift_operator"
4482           [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
4483            (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM,rM")])))
4484    (clobber (reg 24))]
4485   ""
4486   "@
4487    cmp\\t%4, %5\;mov%D6\\t%0, %2%S7
4488    cmn\\t%4, #%n5\;mov%D6\\t%0, %2%S7
4489    cmp\\t%4, %5\;mov%d6\\t%0, %1\;mov%D6\\t%0, %2%S7
4490    cmn\\t%4, #%n5\;mov%d6\\t%0, %1\;mov%D6\\t%0, %2%S7"
4491 [(set_attr "conds" "clob")
4492  (set_attr "length" "8,8,12,12")])
4494 (define_insn ""
4495   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4496         (if_then_else:SI
4497          (match_operator 7 "comparison_operator"
4498           [(match_operand:SI 5 "s_register_operand" "r,r")
4499            (match_operand:SI 6 "arm_add_operand" "rI,L")])
4500          (match_operator:SI 8 "shift_operator"
4501           [(match_operand:SI 1 "s_register_operand" "r,r")
4502            (match_operand:SI 2 "arm_rhs_operand" "rM,rM")])
4503          (match_operator:SI 9 "shift_operator"
4504           [(match_operand:SI 3 "s_register_operand" "r,r")
4505            (match_operand:SI 4 "arm_rhs_operand" "rI,rI")])))
4506    (clobber (reg 24))]
4507   ""
4508   "@
4509    cmp\\t%5, %6\;mov%d7\\t%0, %1%S8\;mov%D7\\t%0, %3%S9
4510    cmn\\t%5, #%n6\;mov%d7\\t%0, %1%S8\;mov%D7\\t%0, %3%S9"
4511 [(set_attr "conds" "clob")
4512  (set_attr "length" "12")])
4514 (define_insn ""
4515   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4516         (if_then_else:SI
4517          (match_operator 6 "comparison_operator"
4518           [(match_operand:SI 4 "s_register_operand" "r,r")
4519            (match_operand:SI 5 "arm_add_operand" "rI,L")])
4520          (not:SI (match_operand:SI 1 "s_register_operand" "r,r"))
4521          (match_operator:SI 7 "shiftable_operator"
4522           [(match_operand:SI 2 "s_register_operand" "r,r")
4523            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
4524    (clobber (reg 24))]
4525   ""
4526   "@
4527    cmp\\t%4, %5\;mvn%d6\\t%0, %1\;%I7%D6\\t%0, %2, %3
4528    cmn\\t%4, #%n5\;mvn%d6\\t%0, %1\;%I7%D6\\t%0, %2, %3"
4529 [(set_attr "conds" "clob")
4530  (set_attr "length" "12")])
4532 (define_insn ""
4533   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4534         (if_then_else:SI
4535          (match_operator 6 "comparison_operator"
4536           [(match_operand:SI 4 "s_register_operand" "r,r")
4537            (match_operand:SI 5 "arm_add_operand" "rI,L")])
4538          (match_operator:SI 7 "shiftable_operator"
4539           [(match_operand:SI 2 "s_register_operand" "r,r")
4540            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
4541          (not:SI (match_operand:SI 1 "s_register_operand" "r,r"))))
4542    (clobber (reg 24))]
4543   ""
4544   "@
4545    cmp\\t%4, %5\;mvn%D6\\t%0, %1\;%I7%d6\\t%0, %2, %3
4546    cmn\\t%4, #%n5\;mvn%D6\\t%0, %1\;%I7%d6\\t%0, %2, %3"
4547 [(set_attr "conds" "clob")
4548  (set_attr "length" "12")])
4550 (define_insn ""
4551   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4552         (if_then_else:SI
4553          (match_operator 5 "comparison_operator"
4554           [(match_operand:SI 3 "s_register_operand" "r,r,r,r")
4555            (match_operand:SI 4 "arm_add_operand" "rI,L,rI,L")])
4556          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r"))
4557          (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))
4558    (clobber (reg:CC 24))]
4559   ""
4560   "@
4561    cmp\\t%3, %4\;rsb%d5\\t%0, %2, #0
4562    cmn\\t%3, #%n4\;rsb%d5\\t%0, %2, #0
4563    cmp\\t%3, %4\;mov%D5\\t%0, %1\;rsb%d5\\t%0, %2, #0
4564    cmn\\t%3, #%n4\;mov%D5\\t%0, %1\;rsb%d5\\t%0, %2, #0"
4565 [(set_attr "conds" "clob")
4566  (set_attr "length" "8,8,12,12")])
4568 (define_insn ""
4569   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4570         (if_then_else:SI
4571          (match_operator 5 "comparison_operator"
4572           [(match_operand:SI 3 "s_register_operand" "r,r,r,r")
4573            (match_operand:SI 4 "arm_add_operand" "rI,L,rI,L")])
4574          (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
4575          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r"))))
4576    (clobber (reg:CC 24))]
4577   ""
4578   "@
4579    cmp\\t%3, %4\;rsb%D5\\t%0, %2, #0
4580    cmn\\t%3, #%n4\;rsb%D5\\t%0, %2, #0
4581    cmp\\t%3, %4\;mov%d5\\t%0, %1\;rsb%D5\\t%0, %2, #0
4582    cmn\\t%3, #%n4\;mov%d5\\t%0, %1\;rsb%D5\\t%0, %2, #0"
4583 [(set_attr "conds" "clob")
4584  (set_attr "length" "8,8,12,12")])
4586 (define_insn ""
4587   [(set (match_operand:SI 0 "s_register_operand" "=r")
4588         (match_operator:SI 1 "shiftable_operator"
4589          [(match_operand:SI 2 "memory_operand" "m")
4590           (match_operand:SI 3 "memory_operand" "m")]))
4591    (clobber (match_scratch:SI 4 "=r"))]
4592   "adjacent_mem_locations (operands[2], operands[3])"
4593   "*
4595   rtx ldm[3];
4596   rtx arith[4];
4597   int val1 = 0, val2 = 0;
4599   if (REGNO (operands[0]) > REGNO (operands[4]))
4600     {
4601       ldm[1] = operands[4];
4602       ldm[2] = operands[0];
4603     }
4604   else
4605     {
4606       ldm[1] = operands[0];
4607       ldm[2] = operands[4];
4608     }
4609   if (GET_CODE (XEXP (operands[2], 0)) != REG)
4610     val1 = INTVAL (XEXP (XEXP (operands[2], 0), 1));
4611   if (GET_CODE (XEXP (operands[3], 0)) != REG)
4612     val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
4613   arith[0] = operands[0];
4614   arith[3] = operands[1];
4615   if (val1 < val2)
4616     {
4617       arith[1] = ldm[1];
4618       arith[2] = ldm[2];
4619     }
4620   else
4621     {
4622       arith[1] = ldm[2];
4623       arith[2] = ldm[1];
4624     }
4625   if (val1 && val2)
4626     {
4627       rtx ops[3];
4628       ldm[0] = ops[0] = operands[4];
4629       ops[1] = XEXP (XEXP (operands[2], 0), 0);
4630       ops[2] = XEXP (XEXP (operands[2], 0), 1);
4631       output_add_immediate (ops);
4632       if (val1 < val2)
4633         output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
4634       else
4635         output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
4636     }
4637   else if (val1)
4638     {
4639       ldm[0] = XEXP (operands[3], 0);
4640       if (val1 < val2)
4641         output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
4642       else
4643         output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
4644     }
4645   else
4646     {
4647       ldm[0] = XEXP (operands[2], 0);
4648       if (val1 < val2)
4649         output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
4650       else
4651         output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
4652     }
4653   output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
4654   return \"\";
4657 [(set_attr "length" "12")
4658  (set_attr "type" "load")])
4660 ;; the arm can support extended pre-inc instructions
4662 ;; In all these cases, we use operands 0 and 1 for the register being
4663 ;; incremented because those are the operands that local-alloc will
4664 ;; tie and these are the pair most likely to be tieable (and the ones
4665 ;; that will benefit the most).
4667 ;; We reject the frame pointer if it occurs anywhere in these patterns since
4668 ;; elimination will cause too many headaches.
4670 (define_insn ""
4671   [(set (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4672                          (match_operand:SI 2 "index_operand" "rJ")))
4673         (match_operand:QI 3 "s_register_operand" "r"))
4674    (set (match_operand:SI 0 "s_register_operand" "=r")
4675         (plus:SI (match_dup 1) (match_dup 2)))]
4676   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4677    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4678    && (GET_CODE (operands[2]) != REG
4679        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4680   "str%?b\\t%3, [%0, %2]!"
4681 [(set_attr "type" "store1")])
4683 (define_insn ""
4684   [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4685                           (match_operand:SI 2 "s_register_operand" "r")))
4686         (match_operand:QI 3 "s_register_operand" "r"))
4687    (set (match_operand:SI 0 "s_register_operand" "=r")
4688         (minus:SI (match_dup 1) (match_dup 2)))]
4689   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4690    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4691    && (GET_CODE (operands[2]) != REG
4692        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4693   "str%?b\\t%3, [%0, -%2]!"
4694 [(set_attr "type" "store1")])
4696 (define_insn ""
4697   [(set (match_operand:QI 3 "s_register_operand" "=r")
4698         (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4699                          (match_operand:SI 2 "index_operand" "rJ"))))
4700    (set (match_operand:SI 0 "s_register_operand" "=r")
4701         (plus:SI (match_dup 1) (match_dup 2)))]
4702   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4703    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4704    && (GET_CODE (operands[2]) != REG
4705        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4706   "ldr%?b\\t%3, [%0, %2]!"
4707 [(set_attr "type" "load")])
4709 (define_insn ""
4710   [(set (match_operand:QI 3 "s_register_operand" "=r")
4711         (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4712                           (match_operand:SI 2 "s_register_operand" "r"))))
4713    (set (match_operand:SI 0 "s_register_operand" "=r")
4714         (minus:SI (match_dup 1) (match_dup 2)))]
4715   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4716    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4717    && (GET_CODE (operands[2]) != REG
4718        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4719   "ldr%?b\\t%3, [%0, -%2]!"
4720 [(set_attr "type" "load")])
4722 (define_insn ""
4723   [(set (match_operand:SI 3 "s_register_operand" "=r")
4724         (zero_extend:SI
4725          (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4726                           (match_operand:SI 2 "index_operand" "rJ")))))
4727    (set (match_operand:SI 0 "s_register_operand" "=r")
4728         (plus:SI (match_dup 1) (match_dup 2)))]
4729   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4730    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4731    && (GET_CODE (operands[2]) != REG
4732        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4733   "ldr%?b\\t%3, [%0, %2]!\\t%@ z_extendqisi"
4734 [(set_attr "type" "load")])
4736 (define_insn ""
4737   [(set (match_operand:SI 3 "s_register_operand" "=r")
4738         (zero_extend:SI
4739          (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4740                            (match_operand:SI 2 "s_register_operand" "r")))))
4741    (set (match_operand:SI 0 "s_register_operand" "=r")
4742         (minus:SI (match_dup 1) (match_dup 2)))]
4743   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4744    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4745    && (GET_CODE (operands[2]) != REG
4746        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4747   "ldr%?b\\t%3, [%0, -%2]!\\t%@ z_extendqisi"
4748 [(set_attr "type" "load")])
4750 (define_insn ""
4751   [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4752                          (match_operand:SI 2 "index_operand" "rJ")))
4753         (match_operand:SI 3 "s_register_operand" "r"))
4754    (set (match_operand:SI 0 "s_register_operand" "=r")
4755         (plus:SI (match_dup 1) (match_dup 2)))]
4756   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4757    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4758    && (GET_CODE (operands[2]) != REG
4759        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4760   "str%?\\t%3, [%0, %2]!"
4761 [(set_attr "type" "store1")])
4763 (define_insn ""
4764   [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4765                           (match_operand:SI 2 "s_register_operand" "r")))
4766         (match_operand:SI 3 "s_register_operand" "r"))
4767    (set (match_operand:SI 0 "s_register_operand" "=r")
4768         (minus:SI (match_dup 1) (match_dup 2)))]
4769   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4770    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4771    && (GET_CODE (operands[2]) != REG
4772        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4773   "str%?\\t%3, [%0, -%2]!"
4774 [(set_attr "type" "store1")])
4776 (define_insn ""
4777   [(set (match_operand:SI 3 "s_register_operand" "=r")
4778         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4779                          (match_operand:SI 2 "index_operand" "rJ"))))
4780    (set (match_operand:SI 0 "s_register_operand" "=r")
4781         (plus:SI (match_dup 1) (match_dup 2)))]
4782   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4783    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4784    && (GET_CODE (operands[2]) != REG
4785        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4786   "ldr%?\\t%3, [%0, %2]!"
4787 [(set_attr "type" "load")])
4789 (define_insn ""
4790   [(set (match_operand:SI 3 "s_register_operand" "=r")
4791         (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4792                           (match_operand:SI 2 "s_register_operand" "r"))))
4793    (set (match_operand:SI 0 "s_register_operand" "=r")
4794         (minus:SI (match_dup 1) (match_dup 2)))]
4795   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4796    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4797    && (GET_CODE (operands[2]) != REG
4798        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4799   "ldr%?\\t%3, [%0, -%2]!"
4800 [(set_attr "type" "load")])
4802 (define_insn ""
4803   [(set (match_operand:HI 3 "s_register_operand" "=r")
4804         (mem:HI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4805                          (match_operand:SI 2 "index_operand" "rJ"))))
4806    (set (match_operand:SI 0 "s_register_operand" "=r")
4807         (plus:SI (match_dup 1) (match_dup 2)))]
4808   "(! BYTES_BIG_ENDIAN)
4809    && ! TARGET_SHORT_BY_BYTES
4810    && REGNO (operands[0]) != FRAME_POINTER_REGNUM
4811    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4812    && (GET_CODE (operands[2]) != REG
4813        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4814   "ldr%?\\t%3, [%0, %2]!\\t%@ loadhi"
4815 [(set_attr "type" "load")])
4817 (define_insn ""
4818   [(set (match_operand:HI 3 "s_register_operand" "=r")
4819         (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4820                           (match_operand:SI 2 "s_register_operand" "r"))))
4821    (set (match_operand:SI 0 "s_register_operand" "=r")
4822         (minus:SI (match_dup 1) (match_dup 2)))]
4823   "(!BYTES_BIG_ENDIAN)
4824    && ! TARGET_SHORT_BY_BYTES
4825    && REGNO (operands[0]) != FRAME_POINTER_REGNUM
4826    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4827    && (GET_CODE (operands[2]) != REG
4828        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4829   "ldr%?\\t%3, [%0, -%2]!\\t%@ loadhi"
4830 [(set_attr "type" "load")])
4832 (define_insn ""
4833   [(set (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
4834                           [(match_operand:SI 3 "s_register_operand" "r")
4835                            (match_operand:SI 4 "const_shift_operand" "n")])
4836                          (match_operand:SI 1 "s_register_operand" "0")))
4837         (match_operand:QI 5 "s_register_operand" "r"))
4838    (set (match_operand:SI 0 "s_register_operand" "=r")
4839         (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
4840                  (match_dup 1)))]
4841   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4842    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4843    && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4844   "str%?b\\t%5, [%0, %3%S2]!"
4845 [(set_attr "type" "store1")])
4847 (define_insn ""
4848   [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4849                           (match_operator:SI 2 "shift_operator"
4850                            [(match_operand:SI 3 "s_register_operand" "r")
4851                             (match_operand:SI 4 "const_shift_operand" "n")])))
4852         (match_operand:QI 5 "s_register_operand" "r"))
4853    (set (match_operand:SI 0 "s_register_operand" "=r")
4854         (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4855                                                  (match_dup 4)])))]
4856   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4857    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4858    && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4859   "str%?b\\t%5, [%0, -%3%S2]!"
4860 [(set_attr "type" "store1")])
4862 (define_insn ""
4863   [(set (match_operand:QI 5 "s_register_operand" "=r")
4864         (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
4865                           [(match_operand:SI 3 "s_register_operand" "r")
4866                            (match_operand:SI 4 "const_shift_operand" "n")])
4867                          (match_operand:SI 1 "s_register_operand" "0"))))
4868    (set (match_operand:SI 0 "s_register_operand" "=r")
4869         (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
4870                  (match_dup 1)))]
4871   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4872    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4873    && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4874   "ldr%?b\\t%5, [%0, %3%S2]!"
4875 [(set_attr "type" "load")])
4877 (define_insn ""
4878   [(set (match_operand:QI 5 "s_register_operand" "=r")
4879         (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4880                           (match_operator:SI 2 "shift_operator"
4881                            [(match_operand:SI 3 "s_register_operand" "r")
4882                             (match_operand:SI 4 "const_shift_operand" "n")]))))
4883    (set (match_operand:SI 0 "s_register_operand" "=r")
4884         (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4885                                                  (match_dup 4)])))]
4886   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4887    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4888    && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4889   "ldr%?b\\t%5, [%0, -%3%S2]!"
4890 [(set_attr "type" "load")])
4892 (define_insn ""
4893   [(set (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
4894                           [(match_operand:SI 3 "s_register_operand" "r")
4895                            (match_operand:SI 4 "const_shift_operand" "n")])
4896                          (match_operand:SI 1 "s_register_operand" "0")))
4897         (match_operand:SI 5 "s_register_operand" "r"))
4898    (set (match_operand:SI 0 "s_register_operand" "=r")
4899         (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
4900                  (match_dup 1)))]
4901   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4902    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4903    && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4904   "str%?\\t%5, [%0, %3%S2]!"
4905 [(set_attr "type" "store1")])
4907 (define_insn ""
4908   [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4909                           (match_operator:SI 2 "shift_operator"
4910                            [(match_operand:SI 3 "s_register_operand" "r")
4911                             (match_operand:SI 4 "const_shift_operand" "n")])))
4912         (match_operand:SI 5 "s_register_operand" "r"))
4913    (set (match_operand:SI 0 "s_register_operand" "=r")
4914         (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4915                                                  (match_dup 4)])))]
4916   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4917    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4918    && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4919   "str%?\\t%5, [%0, -%3%S2]!"
4920 [(set_attr "type" "store1")])
4922 (define_insn ""
4923   [(set (match_operand:SI 5 "s_register_operand" "=r")
4924         (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
4925                           [(match_operand:SI 3 "s_register_operand" "r")
4926                            (match_operand:SI 4 "const_shift_operand" "n")])
4927                          (match_operand:SI 1 "s_register_operand" "0"))))
4928    (set (match_operand:SI 0 "s_register_operand" "=r")
4929         (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
4930                  (match_dup 1)))]
4931   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4932    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4933    && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4934   "ldr%?\\t%5, [%0, %3%S2]!"
4935 [(set_attr "type" "load")])
4937 (define_insn ""
4938   [(set (match_operand:SI 5 "s_register_operand" "=r")
4939         (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4940                           (match_operator:SI 2 "shift_operator"
4941                            [(match_operand:SI 3 "s_register_operand" "r")
4942                             (match_operand:SI 4 "const_shift_operand" "n")]))))
4943    (set (match_operand:SI 0 "s_register_operand" "=r")
4944         (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4945                                                  (match_dup 4)])))]
4946   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4947    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4948    && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4949   "ldr%?\\t%5, [%0, -%3%S2]!"
4950 [(set_attr "type" "load")])
4952 (define_insn ""
4953   [(set (match_operand:HI 5 "s_register_operand" "=r")
4954         (mem:HI (plus:SI (match_operator:SI 2 "shift_operator"
4955                           [(match_operand:SI 3 "s_register_operand" "r")
4956                            (match_operand:SI 4 "const_shift_operand" "n")])
4957                          (match_operand:SI 1 "s_register_operand" "0"))))
4958    (set (match_operand:SI 0 "s_register_operand" "=r")
4959         (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
4960                  (match_dup 1)))]
4961   "(! BYTES_BIG_ENDIAN)
4962    && ! TARGET_SHORT_BY_BYTES
4963    && REGNO (operands[0]) != FRAME_POINTER_REGNUM
4964    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4965    && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4966   "ldr%?\\t%5, [%0, %3%S2]!\\t%@ loadhi"
4967 [(set_attr "type" "load")])
4969 (define_insn ""
4970   [(set (match_operand:HI 5 "s_register_operand" "=r")
4971         (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4972                           (match_operator:SI 2 "shift_operator"
4973                            [(match_operand:SI 3 "s_register_operand" "r")
4974                             (match_operand:SI 4 "const_shift_operand" "n")]))))
4975    (set (match_operand:SI 0 "s_register_operand" "=r")
4976         (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4977                                                  (match_dup 4)])))]
4978   "(! BYTES_BIG_ENDIAN)
4979    && ! TARGET_SHORT_BY_BYTES
4980    && REGNO (operands[0]) != FRAME_POINTER_REGNUM
4981    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4982    && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4983   "ldr%?\\t%5, [%0, -%3%S2]!\\t%@ loadhi"
4984 [(set_attr "type" "load")])
4986 ; It can also support extended post-inc expressions, but combine doesn't
4987 ; try these....
4988 ; It doesn't seem worth adding peepholes for anything but the most common
4989 ; cases since, unlike combine, the increment must immediately follow the load
4990 ; for this pattern to match.
4991 ; When loading we must watch to see that the base register isn't trampled by
4992 ; the load.  In such cases this isn't a post-inc expression.
4994 (define_peephole
4995   [(set (mem:QI (match_operand:SI 0 "s_register_operand" "+r"))
4996         (match_operand:QI 2 "s_register_operand" "r"))
4997    (set (match_dup 0)
4998         (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
4999   ""
5000   "str%?b\\t%2, [%0], %1")
5002 (define_peephole
5003   [(set (match_operand:QI 0 "s_register_operand" "=r")
5004         (mem:QI (match_operand:SI 1 "s_register_operand" "+r")))
5005    (set (match_dup 1)
5006         (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
5007   "REGNO(operands[0]) != REGNO(operands[1])
5008    && (GET_CODE (operands[2]) != REG
5009        || REGNO(operands[0]) != REGNO (operands[2]))"
5010   "ldr%?b\\t%0, [%1], %2")
5012 (define_peephole
5013   [(set (mem:SI (match_operand:SI 0 "s_register_operand" "+r"))
5014         (match_operand:SI 2 "s_register_operand" "r"))
5015    (set (match_dup 0)
5016         (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
5017   ""
5018   "str%?\\t%2, [%0], %1")
5020 (define_peephole
5021   [(set (match_operand:HI 0 "s_register_operand" "=r")
5022         (mem:HI (match_operand:SI 1 "s_register_operand" "+r")))
5023    (set (match_dup 1)
5024         (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
5025   "(! BYTES_BIG_ENDIAN)
5026    && ! TARGET_SHORT_BY_BYTES
5027    && REGNO(operands[0]) != REGNO(operands[1])
5028    && (GET_CODE (operands[2]) != REG
5029        || REGNO(operands[0]) != REGNO (operands[2]))"
5030   "ldr%?\\t%0, [%1], %2\\t%@ loadhi")
5032 (define_peephole
5033   [(set (match_operand:SI 0 "s_register_operand" "=r")
5034         (mem:SI (match_operand:SI 1 "s_register_operand" "+r")))
5035    (set (match_dup 1)
5036         (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
5037   "REGNO(operands[0]) != REGNO(operands[1])
5038    && (GET_CODE (operands[2]) != REG
5039        || REGNO(operands[0]) != REGNO (operands[2]))"
5040   "ldr%?\\t%0, [%1], %2")
5042 (define_peephole
5043   [(set (mem:QI (plus:SI (match_operand:SI 0 "s_register_operand" "+r")
5044                          (match_operand:SI 1 "index_operand" "rJ")))
5045         (match_operand:QI 2 "s_register_operand" "r"))
5046    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
5047   ""
5048   "str%?b\\t%2, [%0, %1]!")
5050 (define_peephole
5051   [(set (mem:QI (plus:SI (match_operator:SI 4 "shift_operator"
5052                           [(match_operand:SI 0 "s_register_operand" "r")
5053                            (match_operand:SI 1 "const_int_operand" "n")])
5054                          (match_operand:SI 2 "s_register_operand" "+r")))
5055         (match_operand:QI 3 "s_register_operand" "r"))
5056    (set (match_dup 2) (plus:SI (match_op_dup 4 [(match_dup 0) (match_dup 1)])
5057                                (match_dup 2)))]
5058   ""
5059   "str%?b\\t%3, [%2, %0%S4]!")
5061 ; This pattern is never tried by combine, so do it as a peephole
5063 (define_peephole
5064   [(set (match_operand:SI 0 "s_register_operand" "=r")
5065         (match_operand:SI 1 "s_register_operand" "r"))
5066    (set (match_operand 2 "cc_register" "")
5067         (compare (match_dup 1) (const_int 0)))]
5068   ""
5069   "sub%?s\\t%0, %1, #0"
5070 [(set_attr "conds" "set")])
5072 ; Peepholes to spot possible load- and store-multiples, if the ordering is
5073 ; reversed, check that the memory references aren't volatile.
5075 (define_peephole
5076   [(set (match_operand:SI 0 "s_register_operand" "=r")
5077         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5078                          (const_int 12))))
5079    (set (match_operand:SI 2 "s_register_operand" "=r")
5080         (mem:SI (plus:SI (match_dup 1) (const_int 8))))
5081    (set (match_operand:SI 3 "s_register_operand" "=r")
5082         (mem:SI (plus:SI (match_dup 1) (const_int 4))))
5083    (set (match_operand:SI 4 "s_register_operand" "=r")
5084         (mem:SI (match_dup 1)))]
5085   "REGNO (operands[0]) > REGNO (operands[2])
5086    && REGNO (operands[2]) > REGNO (operands[3])
5087    && REGNO (operands[3]) > REGNO (operands[4])
5088    && !(REGNO (operands[1]) == REGNO (operands[0])
5089        || REGNO (operands[1]) == REGNO (operands[2])
5090        || REGNO (operands[1]) == REGNO (operands[3])
5091        || REGNO (operands[1]) == REGNO (operands[4]))
5092    && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn)))
5093    && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))
5094    && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn
5095                                          (prev_nonnote_insn (insn)))))
5096    && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn
5097                                          (prev_nonnote_insn 
5098                                           (prev_nonnote_insn (insn))))))"
5099   "ldm%?ia\\t%1, {%4, %3, %2, %0}\\t%@ phole ldm")
5101 (define_peephole
5102   [(set (match_operand:SI 0 "s_register_operand" "=r")
5103         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5104                          (const_int 8))))
5105    (set (match_operand:SI 2 "s_register_operand" "=r")
5106         (mem:SI (plus:SI (match_dup 1) (const_int 4))))
5107    (set (match_operand:SI 3 "s_register_operand" "=r")
5108         (mem:SI (match_dup 1)))]
5109   "REGNO (operands[0]) >  REGNO (operands[2])
5110    && REGNO (operands[2]) > REGNO (operands[3])
5111    && !(REGNO (operands[1]) == REGNO (operands[0])
5112        || REGNO (operands[1]) == REGNO (operands[2])
5113        || REGNO (operands[1]) == REGNO (operands[3]))
5114    && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn)))
5115    && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))
5116    && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn
5117                                          (prev_nonnote_insn (insn)))))"
5118   "ldm%?ia\\t%1, {%3, %2, %0}\\t%@ phole ldm")
5120 (define_peephole
5121   [(set (match_operand:SI 0 "s_register_operand" "=r")
5122         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5123                          (const_int 4))))
5124    (set (match_operand:SI 2 "s_register_operand" "=r")
5125         (mem:SI (match_dup 1)))]
5126   "REGNO (operands[0]) > REGNO (operands[2])
5127    && !(REGNO (operands[1]) == REGNO (operands[0])
5128        || REGNO (operands[1]) == REGNO (operands[2]))
5129    && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn)))
5130    && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))"
5131   "ldm%?ia\\t%1, {%2, %0}\\t%@ phole ldm")
5133 (define_peephole
5134   [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5135                          (const_int 12)))
5136         (match_operand:SI 0 "s_register_operand" "r"))
5137    (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
5138         (match_operand:SI 2 "s_register_operand" "r"))
5139    (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5140         (match_operand:SI 3 "s_register_operand" "r"))
5141    (set (mem:SI (match_dup 1))
5142         (match_operand:SI 4 "s_register_operand" "r"))]
5143   "REGNO (operands[0]) >  REGNO (operands[2])
5144    && REGNO (operands[2]) > REGNO (operands[3])
5145    && REGNO (operands[3]) > REGNO (operands[4])
5146    && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn)))
5147    && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))
5148    && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn
5149                                           (prev_nonnote_insn (insn)))))
5150    && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn
5151                                           (prev_nonnote_insn 
5152                                            (prev_nonnote_insn (insn))))))"
5153   "stm%?ia\\t%1, {%4, %3, %2, %0}\\t%@ phole stm")
5155 (define_peephole
5156   [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5157                          (const_int 8)))
5158         (match_operand:SI 0 "s_register_operand" "r"))
5159    (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5160         (match_operand:SI 2 "s_register_operand" "r"))
5161    (set (mem:SI (match_dup 1))
5162         (match_operand:SI 3 "s_register_operand" "r"))]
5163   "REGNO (operands[0]) >  REGNO (operands[2])
5164    && REGNO (operands[2]) > REGNO (operands[3])
5165    && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn)))
5166    && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))
5167    && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn
5168                                           (prev_nonnote_insn (insn)))))"
5169   "stm%?ia\\t%1, {%3, %2, %0}\\t%@ phole stm")
5171 (define_peephole
5172   [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5173                          (const_int 4)))
5174         (match_operand:SI 0 "s_register_operand" "r"))
5175    (set (mem:SI (match_dup 1))
5176         (match_operand:SI 2 "s_register_operand" "r"))]
5177   "REGNO (operands[0]) >  REGNO (operands[2])
5178    && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn)))
5179    && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))"
5180   "stm%?ia\\t%1, {%2, %0}\\t%@ phole stm")
5182 ;; A call followed by return can be replaced by restoring the regs and
5183 ;; jumping to the subroutine, provided we aren't passing the address of
5184 ;; any of our local variables.  If we call alloca then this is unsafe
5185 ;; since restoring the frame frees the memory, which is not what we want.
5186 ;; Sometimes the return might have been targeted by the final prescan:
5187 ;; if so then emit a propper return insn as well.
5188 ;; Unfortunately, if the frame pointer is required, we don't know if the
5189 ;; current function has any implicit stack pointer adjustments that will 
5190 ;; be restored by the return: we can't therefore do a tail call.
5191 ;; Another unfortunate that we can't handle is if current_function_args_size
5192 ;; is non-zero: in this case elimination of the argument pointer assumed
5193 ;; that lr was pushed onto the stack, so eliminating upsets the offset
5194 ;; calculations.
5196 (define_peephole
5197   [(parallel [(call (mem:SI (match_operand:SI 0 "" "i"))
5198                           (match_operand:SI 1 "general_operand" "g"))
5199                     (clobber (reg:SI 14))])
5200    (return)]
5201   "(GET_CODE (operands[0]) == SYMBOL_REF && USE_RETURN_INSN
5202     && !get_frame_size () && !current_function_calls_alloca
5203     && !frame_pointer_needed && !current_function_args_size)"
5204   "*
5206   extern rtx arm_target_insn;
5207   extern int arm_ccfsm_state, arm_current_cc;
5209   if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
5210   {
5211     arm_current_cc ^= 1;
5212     output_return_instruction (NULL, TRUE);
5213     arm_ccfsm_state = 0;
5214     arm_target_insn = NULL;
5215   }
5217   output_return_instruction (NULL, FALSE);
5218   return \"b%?\\t%a0\";
5220 [(set (attr "conds")
5221       (if_then_else (eq_attr "cpu" "arm6")
5222                     (const_string "clob")
5223                     (const_string "nocond")))
5224  (set_attr "length" "8")])
5226 (define_peephole
5227   [(parallel [(set (match_operand 0 "s_register_operand" "=rf")
5228                    (call (mem:SI (match_operand:SI 1 "" "i"))
5229                          (match_operand:SI 2 "general_operand" "g")))
5230               (clobber (reg:SI 14))])
5231    (return)]
5232   "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN
5233     && !get_frame_size () && !current_function_calls_alloca
5234     && !frame_pointer_needed && !current_function_args_size)"
5235   "*
5237   extern rtx arm_target_insn;
5238   extern int arm_ccfsm_state, arm_current_cc;
5240   if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
5241   {
5242     arm_current_cc ^= 1;
5243     output_return_instruction (NULL, TRUE);
5244     arm_ccfsm_state = 0;
5245     arm_target_insn = NULL;
5246   }
5248   output_return_instruction (NULL, FALSE);
5249   return \"b%?\\t%a1\";
5251 [(set (attr "conds")
5252       (if_then_else (eq_attr "cpu" "arm6")
5253                     (const_string "clob")
5254                     (const_string "nocond")))
5255  (set_attr "length" "8")])
5257 ;; As above but when this function is not void, we must be returning the
5258 ;; result of the called subroutine.
5260 (define_peephole
5261   [(parallel [(set (match_operand 0 "s_register_operand" "=rf")
5262                    (call (mem:SI (match_operand:SI 1 "" "i"))
5263                          (match_operand:SI 2 "general_operand" "g")))
5264               (clobber (reg:SI 14))])
5265    (use (match_dup 0))
5266    (return)]
5267   "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN
5268     && !get_frame_size () && !current_function_calls_alloca
5269     && !frame_pointer_needed && !current_function_args_size)"
5270   "*
5272   extern rtx arm_target_insn;
5273   extern int arm_ccfsm_state, arm_current_cc;
5275   if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
5276   {
5277     arm_current_cc ^= 1;
5278     output_return_instruction (NULL, TRUE);
5279     arm_ccfsm_state = 0;
5280     arm_target_insn = NULL;
5281   }
5283   output_return_instruction (NULL, FALSE);
5284   return \"b%?\\t%a1\";
5286 [(set (attr "conds")
5287       (if_then_else (eq_attr "cpu" "arm6")
5288                     (const_string "clob")
5289                     (const_string "nocond")))
5290  (set_attr "length" "8")])
5292 ;; If calling a subroutine and then jumping back to somewhere else, but not
5293 ;; too far away, then we can set the link register with the branch address
5294 ;; and jump direct to the subroutine.  On return from the subroutine
5295 ;; execution continues at the branch; this avoids a prefetch stall.
5296 ;; We use the length attribute (via short_branch ()) to establish whether or
5297 ;; not this is possible, this is the same asthe sparc does.
5299 (define_peephole
5300   [(parallel[(call (mem:SI (match_operand:SI 0 "" "i"))
5301                    (match_operand:SI 1 "general_operand" "g"))
5302              (clobber (reg:SI 14))])
5303    (set (pc)
5304         (label_ref (match_operand 2 "" "")))]
5305   "0 && GET_CODE (operands[0]) == SYMBOL_REF 
5306    && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
5307    && arm_insn_not_targeted (insn)"
5308   "*
5310   int backward = arm_backwards_branch (INSN_UID (insn),
5311                                        INSN_UID (operands[2]));
5313 #if 0
5314   /* Putting this in means that TARGET_6 code will ONLY run on an arm6 or
5315    * above, leaving it out means that the code will still run on an arm 2 or 3
5316    */
5317   if (TARGET_6)
5318     {
5319       if (backward)
5320         output_asm_insn (\"sub%?\\t%|lr, %|pc, #(8 + . -%l2)\", operands);
5321       else
5322         output_asm_insn (\"add%?\\t%|lr, %|pc, #(%l2 - . -8)\", operands);
5323     }
5324   else
5325 #endif
5326     {
5327       output_asm_insn (\"mov%?\\t%|lr, %|pc\\t%@ protect cc\", operands);
5328       if (backward)
5329         output_asm_insn (\"sub%?\\t%|lr, %|lr, #(4 + . -%l2)\", operands);
5330       else
5331         output_asm_insn (\"add%?\\t%|lr, %|lr, #(%l2 - . -4)\", operands);
5332     }
5333   return \"b%?\\t%a0\";
5335 [(set (attr "conds")
5336       (if_then_else (eq_attr "cpu" "arm6")
5337                     (const_string "clob")
5338                     (const_string "nocond")))
5339  (set (attr "length")
5340       (if_then_else (eq_attr "cpu" "arm6")
5341                     (const_int 8)
5342                     (const_int 12)))])
5344 (define_peephole
5345   [(parallel[(set (match_operand:SI 0 "s_register_operand" "=r")
5346                   (call (mem:SI (match_operand:SI 1 "" "i"))
5347                         (match_operand:SI 2 "general_operand" "g")))
5348              (clobber (reg:SI 14))])
5349    (set (pc)
5350         (label_ref (match_operand 3 "" "")))]
5351   "0 && GET_CODE (operands[0]) == SYMBOL_REF
5352    && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
5353    && arm_insn_not_targeted (insn)"
5354   "*
5356   int backward = arm_backwards_branch (INSN_UID (insn),
5357                                        INSN_UID (operands[3]));
5359 #if 0
5360   /* Putting this in means that TARGET_6 code will ONLY run on an arm6 or
5361    * above, leaving it out means that the code will still run on an arm 2 or 3
5362    */
5363   if (TARGET_6)
5364     {
5365       if (backward)
5366         output_asm_insn (\"sub%?\\t%|lr, %|pc, #(8 + . -%l3)\", operands);
5367       else
5368         output_asm_insn (\"add%?\\t%|lr, %|pc, #(%l3 - . -8)\", operands);
5369     }
5370   else
5371 #endif
5372     {
5373       output_asm_insn (\"mov%?\\t%|lr, %|pc\\t%@ protect cc\", operands);
5374       if (backward)
5375         output_asm_insn (\"sub%?\\t%|lr, %|lr, #(4 + . -%l3)\", operands);
5376       else
5377         output_asm_insn (\"add%?\\t%|lr, %|lr, #(%l3 - . -4)\", operands);
5378     }
5379   return \"b%?\\t%a1\";
5381 [(set (attr "conds")
5382       (if_then_else (eq_attr "cpu" "arm6")
5383                     (const_string "clob")
5384                     (const_string "nocond")))
5385  (set (attr "length")
5386       (if_then_else (eq_attr "cpu" "arm6")
5387                     (const_int 8)
5388                     (const_int 12)))])
5390 (define_split
5391   [(set (pc)
5392         (if_then_else (match_operator 0 "comparison_operator"
5393                        [(match_operator:SI 1 "shift_operator"
5394                          [(match_operand:SI 2 "s_register_operand" "r")
5395                           (match_operand:SI 3 "reg_or_int_operand" "rM")])
5396                         (match_operand:SI 4 "s_register_operand" "r")])
5397                       (label_ref (match_operand 5 "" ""))
5398                       (pc)))
5399    (clobber (reg 24))]
5400   ""
5401   [(set (reg:CC 24)
5402         (compare:CC (match_dup 4)
5403                     (match_op_dup 1 [(match_dup 2) (match_dup 3)])))
5404    (set (pc)
5405         (if_then_else (match_op_dup 0 [(reg 24) (const_int 0)])
5406                       (label_ref (match_dup 5))
5407                       (pc)))]
5408   "
5409   operands[0] = gen_rtx (swap_condition (GET_CODE (operands[0])), VOIDmode,
5410                          operands[1], operands[2]);
5413 (define_split
5414   [(set (match_operand:SI 0 "s_register_operand" "")
5415         (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
5416                        (const_int 0))
5417                 (neg:SI (match_operator:SI 2 "comparison_operator"
5418                          [(match_operand:SI 3 "s_register_operand" "")
5419                           (match_operand:SI 4 "arm_rhs_operand" "")]))))
5420    (clobber (match_operand:SI 5 "s_register_operand" ""))]
5421   ""
5422   [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
5423    (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
5424                               (match_dup 5)))]
5425   "")
5427 ;; This pattern can be used because cc_noov mode implies that the following
5428 ;; branch will be an equality (EQ or NE), so the sign extension is not
5429 ;; needed.  Combine doesn't eliminate these because by the time it sees the
5430 ;; branch it no-longer knows that the data came from memory.
5432 (define_insn ""
5433   [(set (reg:CC_NOOV 24)
5434         (compare:CC_NOOV
5435          (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "m") 0)
5436                     (const_int 24))
5437          (match_operand 1 "immediate_operand" "I")))
5438    (clobber (match_scratch:SI 2 "=r"))]
5439   "((unsigned long) INTVAL (operands[1]))
5440    == (((unsigned long) INTVAL (operands[1])) >> 24) << 24"
5441   "*
5442   operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
5443   output_asm_insn (\"ldr%?b\\t%2, %0\", operands);
5444   output_asm_insn (\"cmp%?\\t%2, %1\", operands);
5445   return \"\";
5447 [(set_attr "conds" "set")
5448  (set_attr "length" "8")
5449  (set_attr "type" "load")])
5451 (define_expand "prologue"
5452   [(clobber (const_int 0))]
5453   ""
5454   "
5455   arm_expand_prologue ();
5456   DONE;
5459 ;; This split is only used during output to reduce the number of patterns
5460 ;; that need assembler instructions adding to them.  We allowed the setting
5461 ;; of the conditions to be implicit during rtl generation so that
5462 ;; the conditional compare patterns would work.  However this conflicts to
5463 ;; some extend with the conditional data operations, so we have to split them
5464 ;; up again here.
5466 (define_split
5467   [(set (match_operand:SI 0 "s_register_operand" "")
5468         (if_then_else:SI (match_operator 1 "comparison_operator"
5469                           [(match_operand 2 "" "") (match_operand 3 "" "")])
5470                          (match_operand 4 "" "")
5471                          (match_operand 5 "" "")))
5472    (clobber (reg 24))]
5473   "reload_completed"
5474   [(set (match_dup 6) (match_dup 7))
5475    (set (match_dup 0) 
5476         (if_then_else:SI (match_op_dup 1 [(match_dup 6) (const_int 0)])
5477                          (match_dup 4)
5478                          (match_dup 5)))]
5479   "
5481   enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), operands[2],
5482                                            operands[3]);
5484   operands[6] = gen_rtx (REG, mode, 24);
5485   operands[7] = gen_rtx (COMPARE, mode, operands[2], operands[3]);
5490 (define_insn ""
5491   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5492         (if_then_else:SI (match_operator 4 "comparison_operator"
5493                           [(match_operand 3 "reversible_cc_register" "")
5494                            (const_int 0)])
5495                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
5496                          (not:SI
5497                           (match_operand:SI 2 "s_register_operand" "r,r"))))]
5498   ""
5499   "@
5500    mvn%D4\\t%0, %2
5501    mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
5502 [(set_attr "conds" "use")
5503  (set_attr "length" "4,8")])
5505 ;; The next two patterns occur when an AND operation is followed by a
5506 ;; scc insn sequence 
5508 (define_insn ""
5509   [(set (match_operand:SI 0 "s_register_operand" "=r")
5510         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
5511                          (const_int 1)
5512                          (match_operand:SI 2 "immediate_operand" "n")))]
5513   ""
5514   "*
5515   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
5516   output_asm_insn (\"ands\\t%0, %1, %2\", operands);
5517   return \"mvnne\\t%0, #0\";
5519 [(set_attr "conds" "clob")
5520  (set_attr "length" "8")])
5522 (define_insn ""
5523   [(set (match_operand:SI 0 "s_register_operand" "=r")
5524         (not:SI
5525          (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
5526                           (const_int 1)
5527                           (match_operand:SI 2 "immediate_operand" "n"))))]
5528   ""
5529   "*
5530   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
5531   output_asm_insn (\"tst\\t%1, %2\", operands);
5532   output_asm_insn (\"mvneq\\t%0, #0\", operands);
5533   return \"movne\\t%0, #0\";
5535 [(set_attr "conds" "clob")
5536  (set_attr "length" "12")])
5538 ;; Push multiple registers to the stack.  The first register is in the
5539 ;; unspec part of the insn; subsequent registers are in parallel (use ...)
5540 ;; expressions.
5541 (define_insn ""
5542   [(match_parallel 2 "multi_register_push"
5543     [(set (match_operand:BLK 0 "memory_operand" "=m")
5544           (unspec:BLK [(match_operand:SI 1 "s_register_operand" "r")] 2))])]
5545   ""
5546   "*
5548   char pattern[100];
5549   int i;
5550   extern int lr_save_eliminated;
5552   if (lr_save_eliminated)
5553     {
5554       if (XVECLEN (operands[2], 0) > 1)
5555         abort ();
5556       return \"\";
5557     }
5558   strcpy (pattern, \"stmfd\\t%m0!, {%|%1\");
5559   for (i = 1; i < XVECLEN (operands[2], 0); i++)
5560     {
5561       strcat (pattern, \", %|\");
5562       strcat (pattern, reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i),
5563                                               0))]);
5564     }
5565   strcat (pattern, \"}\");
5566   output_asm_insn (pattern, operands);
5567   return \"\";
5569 [(set_attr "type" "store4")])