(all output patterns): Use new capabilities of arm_print_operand to
[official-gcc.git] / gcc / config / arm / arm.md
blob756d7bb8548b865df529f7bfcf07a4386d04c5ba
1 ;;- Machine description Acorn RISC Machine 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 RISCiX 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
35 ;; Attributes
37 ; condition codes: this one is used by final_prescan_insn to speed up
38 ; conditionalizing instructions.  It saves having to scan the rtl to see if
39 ; it uses or alters the condition codes.
41 ; USE means that the condition codes are used by the insn in the process of
42 ; outputting code, this means (at present) that we can't use the insn in
43 ; inlined branches
45 ; SET means that the purpose of the insn is to set the condition codes in a
46 ; well defined manner.
48 ; CLOB means that the condition codes are altered in an undefined manner, if
49 ; they are altered at all
51 ; JUMP_CLOB is used when the conditions are not defined if a branch is taken,
52 ; but are if the branch wasn't taken; the effect is to limit the branch
53 ; elimination scanning.
55 ; NOCOND means that the condition codes are niether altered nor affect the
56 ; output of this insn
58 (define_attr "conds" "use,set,clob,jump_clob,nocond"
59         (const_string "nocond"))
61 ; CPU attribute is used to determine whether condition codes are clobbered
62 ; by a call insn: on the arm6 they are if in 32-bit addressing mode; on the
63 ; arm2 and arm3 the condition codes are restored by the return.
65 (define_attr "cpu" "arm2,arm3,arm6" (const (symbol_ref "arm_cpu_attr")))
67 ; LENGTH of an instruction (in bytes)
68 (define_attr "length" "" (const_int 4))
70 ; An assembler sequence may clobber the condition codes without us knowing
71 (define_asm_attributes
72  [(set_attr "conds" "clob")
73   (set_attr "length" "4")])
75 ; TYPE attribute is used to detect floating point instructions which, if
76 ; running on a co-processor can run in parallel with other, basic instructions
77 ; If write-buffer scheduling is enabled then it can also be used in the
78 ; scheduling of writes.
80 ; Classification of each insn
81 ; normal        any data instruction that doesn't hit memory or fp regs
82 ; block         blockage insn, this blocks all functional units
83 ; float         a floating point arithmetic operation (subject to expansion)
84 ; float_em      a floating point arithmetic operation that is normally emulated
85 ; f_load        a floating point load from memory
86 ; f_store       a floating point store to memory
87 ; f_mem_r       a transfer of a floating point register to a real reg via mem
88 ; r_mem_f       the reverse of f_mem_r
89 ; f_2_r         fast transfer float to arm (no memory needed)
90 ; r_2_f         fast transfer arm to float
91 ; call          a subroutine call
92 ; load          any load from memory
93 ; store1        store 1 word to memory from arm registers
94 ; store2        store 2 words
95 ; store3        store 3 words
96 ; store4        store 4 words
98 (define_attr "type"
99         "normal,block,float,float_em,f_load,f_store,f_mem_r,r_mem_f,f_2_r,r_2_f,call,load,store1,store2,store3,store4" 
100         (const_string "normal"))
102 (define_attr "write_conflict" "no,yes"
103   (if_then_else (eq_attr "type"
104                  "block,float_em,f_load,f_store,f_mem_r,r_mem_f,call,load")
105                 (const_string "yes")
106                 (const_string "no")))
108 ; The write buffer on some of the arm6 processors is hard to model exactly.
109 ; There is room in the buffer for up to two addresses and up to eight words
110 ; of memory, but the two needn't be split evenly.  When writing the two
111 ; addresses are fully pipelined.  However, a read from memory that is not
112 ; currently in the cache will block until the writes have completed.
113 ; It is normally the case that FCLK and MCLK will be in the ratio 2:1, so
114 ; writes will take 2 FCLK cycles per word, if FCLK and MCLK are asynchronous
115 ; (they aren't allowed to be at present) then there is a startup cost of 1MCLK
116 ; cycle to add as well.
118 ;; (define_function_unit {name} {num-units} {n-users} {test}
119 ;;                       {ready-delay} {issue-delay} [{conflict-list}])
120 ;; This is not well tuned, but I don't have all the details.
121 (define_function_unit "fpa" 1 1 (eq_attr "type" "float") 5 0)
123 (define_function_unit "write_buf" 1 2 (eq_attr "type" "store1") 3 3
124         [(eq_attr "write_conflict" "yes")])
125 (define_function_unit "write_buf" 1 2 (eq_attr "type" "store2") 5 5
126         [(eq_attr "write_conflict" "yes")])
127 (define_function_unit "write_buf" 1 2 (eq_attr "type" "store3") 7 7
128         [(eq_attr "write_conflict" "yes")])
129 (define_function_unit "write_buf" 1 2 (eq_attr "type" "store4") 9 9
130         [(eq_attr "write_conflict" "yes")])
131 (define_function_unit "write_buf" 1 2 (eq_attr "type" "r_mem_f") 3 3
132         [(eq_attr "write_conflict" "yes")])
134 ;; Note: For DImode insns, there is normally no reason why operands should
135 ;; not be in the same register, what we don't want is for something being
136 ;; written to partially overlap something that is an input.
138 ;; Addition insns.
140 (define_insn "adddi3"
141   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
142         (plus:DI (match_operand:DI 1 "s_register_operand" "%0,0")
143                  (match_operand:DI 2 "s_register_operand" "r,0")))
144    (clobber (reg:CC 24))]
145   ""
146   "adds\\t%0, %1, %2\;adc\\t%R0, %R1, %R2"
147 [(set_attr "conds" "clob")
148  (set_attr "length" "8")])
150 (define_insn ""
151   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
152         (plus:DI (sign_extend:DI
153                   (match_operand:SI 1 "s_register_operand" "r,r"))
154                  (match_operand:DI 2 "s_register_operand" "r,0")))
155    (clobber (reg:CC 24))]
156   ""
157   "adds\\t%0, %2, %1\;adc\\t%R0, %R2, %1, asr #31"
158 [(set_attr "conds" "clob")
159  (set_attr "length" "8")])
161 (define_insn ""
162   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
163         (plus:DI (zero_extend:DI
164                   (match_operand:SI 1 "s_register_operand" "r,r"))
165                  (match_operand:DI 2 "s_register_operand" "r,0")))
166    (clobber (reg:CC 24))]
167   ""
168   "adds\\t%0, %2, %1\;adc\\t%R0, %R2, #0"
169 [(set_attr "conds" "clob")
170  (set_attr "length" "8")])
172 (define_insn "addsi3"
173   [(set (match_operand:SI 0 "s_register_operand" "=r")
174         (plus:SI (match_operand:SI 1 "s_register_operand" "r")
175                  (match_operand:SI 2 "arm_add_operand" "rL")))]
176   ""
177   "*
178   if (GET_CODE (operands[2]) == CONST_INT
179       && !const_ok_for_arm (INTVAL (operands[2])))
180     return \"sub%?\\t%0, %1, #%n2\";
181   return \"add%?\\t%0, %1, %2\";
184 (define_insn ""
185   [(set (reg:CC_NOOV 24)
186         (compare:CC_NOOV (plus:SI (match_operand:SI 1 "s_register_operand" "r")
187                                   (match_operand:SI 2 "arm_add_operand" "rL"))
188                          (const_int 0)))
189    (set (match_operand:SI 0 "s_register_operand" "=r")
190         (plus:SI (match_dup 1) (match_dup 2)))]
191   ""
192   "*
193   if (GET_CODE (operands[2]) == CONST_INT
194       && !const_ok_for_arm (INTVAL (operands[2])))
195     return \"sub%?s\\t%0, %1, #%n2\";
196   return \"add%?s\\t%0, %1, %2\";
198 [(set_attr "conds" "set")])
200 (define_insn ""
201   [(set (reg:CC 24)
202         (compare:CC (match_operand:SI 1 "s_register_operand" "r")
203                     (neg:SI (match_operand:SI 2 "arm_add_operand" "rL"))))
204    (set (match_operand:SI 0 "s_register_operand" "=r")
205         (plus:SI (match_dup 1) (match_dup 2)))]
206   ""
207   "*
208   if (GET_CODE (operands[2]) == CONST_INT
209       && !const_ok_for_arm (INTVAL (operands[2])))
210     return \"sub%?s\\t%0, %1, #%n2\";
211   return \"add%?s\\t%0, %1, %2\";
213 [(set_attr "conds" "set")])
215 (define_insn "incscc"
216   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
217         (plus:SI (match_operator:SI 2 "comparison_operator"
218                     [(reg 24) (const_int 0)])
219                  (match_operand:SI 1 "s_register_operand" "0,?r")))]
220   ""
221   "*
222   if (which_alternative == 1)
223     output_asm_insn (\"mov%D2\\t%0, %1\", operands);
224   return \"add%d2\\t%0, %1, #1\";
226 [(set_attr "conds" "use")
227  (set_attr "length" "*,8")])
229 ; If a constant is too big to fit in a single instruction then the constant
230 ; will be pre-loaded into a register taking at least two insns, we might be
231 ; able to merge it with an add, but it depends on the exact value.
233 (define_split
234   [(set (match_operand:SI 0 "s_register_operand" "=r")
235         (plus:SI (match_operand:SI 1 "s_register_operand" "r")
236                  (match_operand:SI 2 "immediate_operand" "n")))]
237   "!(const_ok_for_arm (INTVAL (operands[2]))
238      || const_ok_for_arm (-INTVAL (operands[2])))"
239   [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
240    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
241   "
243   unsigned int val = (unsigned) INTVAL (operands[2]);
244   int i;
245   unsigned int temp;
247   /* this code is similar to the approach followed in movsi, but it must
248      generate exactly two insns */
250   for (i = 30; i >= 0; i -= 2)
251     {
252       if (val & (3 << i))
253         {
254           i -= 6;
255           if (i < 0) i = 0;
256           if (const_ok_for_arm (temp = (val & ~(255 << i))))
257             {
258               val &= 255 << i;
259               break;
260             }
261           /* we might be able to do this as (larger number - small number) */
262           temp = ((val >> i) & 255) + 1;
263           if (temp > 255 && i < 24)
264             {
265               i += 2;
266               temp = ((val >> i) & 255) + 1;
267             }
268           if (const_ok_for_arm ((temp << i) - val))
269             {
270               i = temp << i;
271               temp = (unsigned) - (int) (i - val);
272               val = i;
273               break;
274             }
275           FAIL;
276         }
277     }
278   /* if we got here, we have found a way of doing it in two instructions.
279      the two constants are in val and temp */
280   operands[2] = GEN_INT ((int)val);
281   operands[3] = GEN_INT ((int)temp);
285 (define_insn "addsf3"
286   [(set (match_operand:SF 0 "s_register_operand" "=f,f")
287         (plus:SF (match_operand:SF 1 "s_register_operand" "f,f")
288                  (match_operand:SF 2 "fpu_add_operand" "fG,H")))]
289   ""
290   "*
292   REAL_VALUE_TYPE r;
294   switch (which_alternative)
295     {
296     case 0:
297       return \"adf%?s\\t%0, %1, %2\";
298     case 1:
299       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
300       r = REAL_VALUE_NEGATE (r);
301       operands[2] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[2]));
302       output_asm_insn (\"suf%?s\\t%0, %1, %2\", operands);
303       return \"\";
304     }
307 [(set_attr "type" "float")])
309 (define_insn "adddf3"
310   [(set (match_operand:DF 0 "s_register_operand" "=f,f")
311         (plus:DF (match_operand:DF 1 "s_register_operand" "f,f")
312                  (match_operand:DF 2 "fpu_add_operand" "fG,H")))]
313   ""
314   "*
316   REAL_VALUE_TYPE r;
318   switch (which_alternative)
319     {
320     case 0:
321       return \"adf%?d\\t%0, %1, %2\";
322     case 1:
323       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
324       r = REAL_VALUE_NEGATE (r);
325       operands[2] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[2]));
326       output_asm_insn (\"suf%?d\\t%0, %1, %2\", operands);
327       return \"\";
328     }
331 [(set_attr "type" "float")])
333 (define_insn ""
334   [(set (match_operand:DF 0 "s_register_operand" "=f,f")
335         (plus:DF (float_extend:DF
336                   (match_operand:SF 1 "s_register_operand" "f,f"))
337                  (match_operand:DF 2 "fpu_add_operand" "fG,H")))]
338   ""
339   "*
341   REAL_VALUE_TYPE r;
343   switch (which_alternative)
344     {
345     case 0:
346       return \"adf%?d\\t%0, %1, %2\";
347     case 1:
348       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
349       r = REAL_VALUE_NEGATE (r);
350       operands[2] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[2]));
351       output_asm_insn (\"suf%?d\\t%0, %1, %2\", operands);
352       return \"\";
353     }
356 [(set_attr "type" "float")])
358 (define_insn ""
359   [(set (match_operand:DF 0 "s_register_operand" "=f")
360         (plus:DF (match_operand:DF 1 "s_register_operand" "f")
361                  (float_extend:DF
362                   (match_operand:SF 2 "s_register_operand" "f"))))]
363   ""
364   "adf%?d\\t%0, %1, %2"
365 [(set_attr "type" "float")])
367 (define_insn ""
368   [(set (match_operand:DF 0 "s_register_operand" "=f")
369         (plus:DF (float_extend:DF 
370                   (match_operand:SF 1 "s_register_operand" "f"))
371                  (float_extend:DF
372                   (match_operand:SF 2 "s_register_operand" "f"))))]
373   ""
374   "adf%?d\\t%0, %1, %2"
375 [(set_attr "type" "float")])
377 (define_insn "addxf3"
378   [(set (match_operand:XF 0 "s_register_operand" "=f,f")
379         (plus:XF (match_operand:XF 1 "s_register_operand" "f,f")
380                  (match_operand:XF 2 "fpu_add_operand" "fG,H")))]
381   "ENABLE_XF_PATTERNS"
382   "*
384   REAL_VALUE_TYPE r;
386   switch (which_alternative)
387     {
388     case 0:
389       return \"adf%?e\\t%0, %1, %2\";
390     case 1:
391       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
392       r = REAL_VALUE_NEGATE (r);
393       operands[2] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[2]));
394       output_asm_insn (\"suf%?e\\t%0, %1, %2\", operands);
395       return \"\";
396     }
399 [(set_attr "type" "float")])
401 (define_insn "subdi3"
402   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
403         (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
404                   (match_operand:DI 2 "s_register_operand" "r,0,0")))
405    (clobber (reg:CC 24))]
406   ""
407   "subs\\t%0, %1, %2\;sbc\\t%R0, %R1, %R2"
408 [(set_attr "conds" "clob")
409  (set_attr "length" "8")])
411 (define_insn ""
412   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
413         (minus:DI (match_operand:DI 1 "s_register_operand" "?r,0")
414                   (zero_extend:DI
415                    (match_operand:SI 2 "s_register_operand" "r,r"))))
416    (clobber (reg:CC 24))]
417   ""
418   "subs\\t%0, %1, %2\;sbc\\t%R0, %R1, #0"
419 [(set_attr "conds" "clob")
420  (set_attr "length" "8")])
422 (define_insn ""
423   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
424         (minus:DI (match_operand:DI 1 "s_register_operand" "r,0")
425                   (sign_extend:DI
426                    (match_operand:SI 2 "s_register_operand" "r,r"))))
427    (clobber (reg:CC 24))]
428   ""
429   "subs\\t%0, %1, %2\;sbc\\t%R0, %R1, %2, asr #31"
430 [(set_attr "conds" "clob")
431  (set_attr "length" "8")])
433 (define_insn ""
434   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
435         (minus:DI (zero_extend:DI
436                    (match_operand:SI 2 "s_register_operand" "r,r"))
437                   (match_operand:DI 1 "s_register_operand" "?r,0")))
438    (clobber (reg:CC 24))]
439   ""
440   "rsbs\\t%0, %1, %2\;rsc\\t%R0, %R1, #0"
441 [(set_attr "conds" "clob")
442  (set_attr "length" "8")])
444 (define_insn ""
445   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
446         (minus:DI (sign_extend:DI
447                    (match_operand:SI 2 "s_register_operand" "r,r"))
448                   (match_operand:DI 1 "s_register_operand" "?r,0")))
449    (clobber (reg:CC 24))]
450   ""
451   "rsbs\\t%0, %1, %2\;rsc\\t%R0, %R1, %2, asr #31"
452 [(set_attr "conds" "clob")
453  (set_attr "length" "8")])
455 (define_insn ""
456   [(set (match_operand:DI 0 "s_register_operand" "=r")
457         (minus:DI (zero_extend:DI
458                    (match_operand:SI 1 "s_register_operand" "r"))
459                   (zero_extend:DI
460                    (match_operand:SI 2 "s_register_operand" "r"))))
461    (clobber (reg:CC 24))]
462   ""
463   "subs\\t%0, %1, %2\;rsc\\t%R0, %1, %1"
464 [(set_attr "conds" "clob")
465  (set_attr "length" "8")])
467 (define_insn "subsi3"
468   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
469         (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,I")
470                   (match_operand:SI 2 "arm_rhs_operand" "rI,r")))]
471   ""
472   "@
473    sub%?\\t%0, %1, %2
474    rsb%?\\t%0, %2, %1")
476 (define_insn ""
477   [(set (reg:CC_NOOV 24)
478         (compare:CC_NOOV (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,I")
479                                  (match_operand:SI 2 "arm_rhs_operand" "rI,r"))
480                          (const_int 0)))
481    (set (match_operand:SI 0 "s_register_operand" "=r,r")
482         (minus:SI (match_dup 1) (match_dup 2)))]
483   ""
484   "@
485    sub%?s\\t%0, %1, %2
486    rsb%?s\\t%0, %2, %1"
487 [(set_attr "conds" "set")])
489 (define_insn "decscc"
490   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
491         (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
492                   (match_operator:SI 2 "comparison_operator"
493                    [(reg 24) (const_int 0)])))]
494   ""
495   "@
496   sub%d2\\t%0, %1, #1
497   mov%D2\\t%0, %1\;sub%d2\\t%0, %1, #1"
498 [(set_attr "conds" "use")
499  (set_attr "length" "*,8")])
501 (define_insn "subsf3"
502   [(set (match_operand:SF 0 "s_register_operand" "=f,f")
503         (minus:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
504                   (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
505   ""
506   "@
507    suf%?s\\t%0, %1, %2
508    rsf%?s\\t%0, %2, %1"
509 [(set_attr "type" "float")])
511 (define_insn "subdf3"
512   [(set (match_operand:DF 0 "s_register_operand" "=f,f")
513         (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
514                   (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
515   ""
516   "@
517    suf%?d\\t%0, %1, %2
518    rsf%?d\\t%0, %2, %1"
519 [(set_attr "type" "float")])
521 (define_insn ""
522   [(set (match_operand:DF 0 "s_register_operand" "=f")
523         (minus:DF (float_extend:DF
524                    (match_operand:SF 1 "s_register_operand" "f"))
525                   (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
526   ""
527   "suf%?d\\t%0, %1, %2"
528 [(set_attr "type" "float")])
530 (define_insn ""
531   [(set (match_operand:DF 0 "s_register_operand" "=f,f")
532         (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
533                   (float_extend:DF
534                    (match_operand:SF 2 "s_register_operand" "f,f"))))]
535   ""
536   "@
537    suf%?d\\t%0, %1, %2
538    rsf%?d\\t%0, %2, %1"
539 [(set_attr "type" "float")])
541 (define_insn ""
542   [(set (match_operand:DF 0 "s_register_operand" "=f")
543         (minus:DF (float_extend:DF
544                    (match_operand:SF 1 "s_register_operand" "f"))
545                   (float_extend:DF
546                    (match_operand:SF 2 "s_register_operand" "f"))))]
547   ""
548   "suf%?d\\t%0, %1, %2"
549 [(set_attr "type" "float")])
551 (define_insn "subxf3"
552   [(set (match_operand:XF 0 "s_register_operand" "=f,f")
553         (minus:XF (match_operand:XF 1 "fpu_rhs_operand" "f,G")
554                   (match_operand:XF 2 "fpu_rhs_operand" "fG,f")))]
555   "ENABLE_XF_PATTERNS"
556   "@
557    suf%?e\\t%0, %1, %2
558    rsf%?e\\t%0, %2, %1"
559 [(set_attr "type" "float")])
561 ;; Multiplication insns
563 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
564 (define_insn "mulsi3"
565   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
566         (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
567                  (match_operand:SI 1 "s_register_operand" "%?r,0")))]
568   ""
569   "mul%?\\t%0, %2, %1")
571 (define_insn ""
572   [(set (reg:CC_NOOV 24)
573         (compare:CC_NOOV (mult:SI
574                           (match_operand:SI 2 "s_register_operand" "r,r")
575                           (match_operand:SI 1 "s_register_operand" "%?r,0"))
576                          (const_int 0)))
577    (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
578         (mult:SI (match_dup 2) (match_dup 1)))]
579   ""
580   "mul%?s\\t%0, %2, %1"
581 [(set_attr "conds" "set")])
583 (define_insn ""
584   [(set (reg:CC_NOOV 24)
585         (compare:CC_NOOV (mult:SI
586                           (match_operand:SI 2 "s_register_operand" "r,r")
587                           (match_operand:SI 1 "s_register_operand" "%?r,0"))
588                          (const_int 0)))
589    (clobber (match_scratch:SI 0 "=&r,&r"))]
590   ""
591   "mul%?s\\t%0, %2, %1"
592 [(set_attr "conds" "set")])
594 ;; Unnamed templates to match MLA instruction.
596 (define_insn ""
597   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
598         (plus:SI
599           (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
600                    (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
601           (match_operand:SI 3 "s_register_operand" "?r,r,0,0")))]
602   ""
603   "mla%?\\t%0, %2, %1, %3")
605 (define_insn ""
606   [(set (reg:CC_NOOV 24)
607         (compare:CC_NOOV (plus:SI
608                           (mult:SI
609                            (match_operand:SI 2 "s_register_operand" "r,r,r,r")
610                            (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
611                           (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
612                          (const_int 0)))
613    (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
614         (plus:SI (mult:SI (match_dup 2) (match_dup 1))
615                  (match_dup 3)))]
616   ""
617   "mla%?s\\t%0, %2, %1, %3"
618 [(set_attr "conds" "set")])
620 (define_insn ""
621   [(set (reg:CC_NOOV 24)
622         (compare:CC_NOOV (plus:SI
623                           (mult:SI
624                            (match_operand:SI 2 "s_register_operand" "r,r,r,r")
625                            (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
626                           (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
627                          (const_int 0)))
628    (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
629   ""
630   "mla%?s\\t%0, %2, %1, %3"
631 [(set_attr "conds" "set")])
633 (define_insn "mulsf3"
634   [(set (match_operand:SF 0 "s_register_operand" "=f")
635         (mult:SF (match_operand:SF 1 "s_register_operand" "f")
636                  (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
637   ""
638   "fml%?s\\t%0, %1, %2"
639 [(set_attr "type" "float")])
641 (define_insn "muldf3"
642   [(set (match_operand:DF 0 "s_register_operand" "=f")
643         (mult:DF (match_operand:DF 1 "s_register_operand" "f")
644                  (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
645   ""
646   "muf%?d\\t%0, %1, %2"
647 [(set_attr "type" "float")])
649 (define_insn ""
650   [(set (match_operand:DF 0 "s_register_operand" "=f")
651         (mult:DF (float_extend:DF
652                   (match_operand:SF 1 "s_register_operand" "f"))
653                  (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
654   ""
655   "muf%?d\\t%0, %1, %2"
656 [(set_attr "type" "float")])
658 (define_insn ""
659   [(set (match_operand:DF 0 "s_register_operand" "=f")
660         (mult:DF (match_operand:DF 1 "s_register_operand" "f")
661                  (float_extend:DF
662                   (match_operand:SF 2 "s_register_operand" "f"))))]
663   ""
664   "muf%?d\\t%0, %1, %2"
665 [(set_attr "type" "float")])
667 (define_insn ""
668   [(set (match_operand:DF 0 "s_register_operand" "=f")
669         (mult:DF (float_extend:DF
670                   (match_operand:SF 1 "s_register_operand" "f"))
671                  (float_extend:DF
672                   (match_operand:SF 2 "s_register_operand" "f"))))]
673   ""
674   "muf%?d\\t%0, %1, %2"
675 [(set_attr "type" "float")])
677 (define_insn "mulxf3"
678   [(set (match_operand:XF 0 "s_register_operand" "=f")
679         (mult:XF (match_operand:XF 1 "s_register_operand" "f")
680                  (match_operand:XF 2 "fpu_rhs_operand" "fG")))]
681   "ENABLE_XF_PATTERNS"
682   "muf%?e\\t%0, %1, %2"
683 [(set_attr "type" "float")])
685 ;; Division insns
687 (define_insn "divsf3"
688   [(set (match_operand:SF 0 "s_register_operand" "=f,f")
689         (div:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
690                 (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
691   ""
692   "@
693    fdv%?s\\t%0, %1, %2
694    frd%?s\\t%0, %2, %1"
695 [(set_attr "type" "float")])
697 (define_insn "divdf3"
698   [(set (match_operand:DF 0 "s_register_operand" "=f,f")
699         (div:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
700                 (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
701   ""
702   "@
703    dvf%?d\\t%0, %1, %2
704    rdf%?d\\t%0, %2, %1"
705 [(set_attr "type" "float")])
707 (define_insn ""
708   [(set (match_operand:DF 0 "s_register_operand" "=f")
709         (div:DF (float_extend:DF
710                  (match_operand:SF 1 "s_register_operand" "f"))
711                 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
712   ""
713   "dvf%?d\\t%0, %1, %2"
714 [(set_attr "type" "float")])
716 (define_insn ""
717   [(set (match_operand:DF 0 "s_register_operand" "=f")
718         (div:DF (match_operand:DF 1 "fpu_rhs_operand" "fG")
719                 (float_extend:DF
720                  (match_operand:SF 2 "s_register_operand" "f"))))]
721   ""
722   "rdf%?d\\t%0, %2, %1"
723 [(set_attr "type" "float")])
725 (define_insn ""
726   [(set (match_operand:DF 0 "s_register_operand" "=f")
727         (div:DF (float_extend:DF
728                  (match_operand:SF 1 "s_register_operand" "f"))
729                 (float_extend:DF
730                  (match_operand:SF 2 "s_register_operand" "f"))))]
731   ""
732   "dvf%?d\\t%0, %1, %2"
733 [(set_attr "type" "float")])
735 (define_insn "divxf3"
736   [(set (match_operand:XF 0 "s_register_operand" "=f,f")
737         (div:XF (match_operand:XF 1 "fpu_rhs_operand" "f,G")
738                 (match_operand:XF 2 "fpu_rhs_operand" "fG,f")))]
739   "ENABLE_XF_PATTERNS"
740   "@
741    dvf%?e\\t%0, %1, %2
742    rdf%?e\\t%0, %2, %1"
743 [(set_attr "type" "float")])
745 ;; Modulo insns
747 (define_insn "modsf3"
748   [(set (match_operand:SF 0 "s_register_operand" "=f")
749         (mod:SF (match_operand:SF 1 "s_register_operand" "f")
750                 (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
751   ""
752   "rmf%?s\\t%0, %1, %2"
753 [(set_attr "type" "float")])
755 (define_insn "moddf3"
756   [(set (match_operand:DF 0 "s_register_operand" "=f")
757         (mod:DF (match_operand:DF 1 "s_register_operand" "f")
758                 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
759   ""
760   "rmf%?d\\t%0, %1, %2"
761 [(set_attr "type" "float")])
763 (define_insn ""
764   [(set (match_operand:DF 0 "s_register_operand" "=f")
765         (mod:DF (float_extend:DF
766                  (match_operand:SF 1 "s_register_operand" "f"))
767                 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
768   ""
769   "rmf%?d\\t%0, %1, %2"
770 [(set_attr "type" "float")])
772 (define_insn ""
773   [(set (match_operand:DF 0 "s_register_operand" "=f")
774         (mod:DF (match_operand:DF 1 "s_register_operand" "f")
775                 (float_extend:DF
776                  (match_operand:SF 2 "s_register_operand" "f"))))]
777   ""
778   "rmf%?d\\t%0, %1, %2"
779 [(set_attr "type" "float")])
781 (define_insn ""
782   [(set (match_operand:DF 0 "s_register_operand" "=f")
783         (mod:DF (float_extend:DF
784                  (match_operand:SF 1 "s_register_operand" "f"))
785                 (float_extend:DF
786                  (match_operand:SF 2 "s_register_operand" "f"))))]
787   ""
788   "rmf%?d\\t%0, %1, %2"
789 [(set_attr "type" "float")])
791 (define_insn "modxf3"
792   [(set (match_operand:XF 0 "s_register_operand" "=f")
793         (mod:XF (match_operand:XF 1 "s_register_operand" "f")
794                 (match_operand:XF 2 "fpu_rhs_operand" "fG")))]
795   "ENABLE_XF_PATTERNS"
796   "rmf%?e\\t%0, %1, %2"
797 [(set_attr "type" "float")])
799 ;; Boolean and,ior,xor insns
801 (define_insn "anddi3"
802   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
803         (and:DI (match_operand:DI 1 "s_register_operand" "%0,0")
804                 (match_operand:DI 2 "s_register_operand" "r,0")))]
805   ""
806   "and%?\\t%0, %1, %2\;and%?\\t%R0, %R1, %R2"
807 [(set_attr "length" "8")])
809 (define_insn ""
810   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
811         (and:DI (zero_extend:DI
812                  (match_operand:SI 2 "s_register_operand" "r,r"))
813                 (match_operand:DI 1 "s_register_operand" "?r,0")))]
814   ""
815   "and%?\\t%0, %1, %2\;mov%?\\t%R0, #0"
816 [(set_attr "length" "8")])
818 (define_insn ""
819   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
820         (and:DI (sign_extend:DI
821                  (match_operand:SI 2 "s_register_operand" "r,r"))
822                 (match_operand:DI 1 "s_register_operand" "?r,0")))]
823   ""
824   "and%?\\t%0, %1, %2\;and%?\\t%R0, %R1, %2, asr #31"
825 [(set_attr "length" "8")])
827 (define_insn "andsi3"
828   [(set (match_operand:SI 0 "s_register_operand" "=r")
829         (and:SI (match_operand:SI 1 "s_register_operand" "r")
830                 (match_operand:SI 2 "arm_not_operand" "rK")))]
831   ""
832   "*
833   if (GET_CODE (operands[2]) == CONST_INT
834       && !const_ok_for_arm (INTVAL (operands[2])))
835     {
836       operands[2] = GEN_INT (~INTVAL (operands[2]));
837       output_asm_insn (\"bic%?\\t%0, %1, %2\", operands);
838       return \"\";
839     }
840   return \"and%?\\t%0, %1, %2\";
843 (define_insn ""
844   [(set (reg:CC_NOOV 24)
845         (compare:CC_NOOV (and:SI (match_operand:SI 1 "s_register_operand" "r")
846                                  (match_operand:SI 2 "arm_not_operand" "rK"))
847                          (const_int 0)))
848    (set (match_operand:SI 0 "s_register_operand" "=r")
849         (and:SI (match_dup 1) (match_dup 2)))]
850   ""
851   "*
852   if (GET_CODE (operands[2]) == CONST_INT
853       && !const_ok_for_arm (INTVAL (operands[2])))
854     {
855       operands[2] = GEN_INT (~INTVAL (operands[2]));
856       output_asm_insn (\"bic%?s\\t%0, %1, %2\", operands);
857       return \"\";
858     }
859   return \"and%?s\\t%0, %1, %2\";
861 [(set_attr "conds" "set")])
863 (define_insn ""
864   [(set (reg:CC_NOOV 24)
865         (compare:CC_NOOV (and:SI (match_operand:SI 0 "s_register_operand" "r")
866                                  (match_operand:SI 1 "arm_rhs_operand" "rI"))
867                          (const_int 0)))]
868   ""
869   "tst%?\\t%0, %1"
870 [(set_attr "conds" "set")])
872 (define_insn ""
873   [(set (reg:CC_NOOV 24)
874         (compare:CC_NOOV (and:SI (match_operand:SI 0 "s_register_operand" "r")
875                                  (match_operand:SI 1 "immediate_operand" "K"))
876                          (const_int 0)))
877    (clobber (match_scratch:SI 3 "=r"))]
878   "const_ok_for_arm (~INTVAL (operands[1]))"
879   "*
880   operands[1] = GEN_INT (~INTVAL (operands[1]));
881   output_asm_insn (\"bic%?s\\t%3, %0, %1\", operands);
882   return \"\";
884 [(set_attr "conds" "set")])
886 (define_insn ""
887   [(set (reg:CC_NOOV 24)
888         (compare:CC_NOOV (zero_extract:SI
889                           (match_operand:SI 0 "s_register_operand" "r")
890                           (match_operand:SI 1 "immediate_operand" "n")
891                           (match_operand:SI 2 "immediate_operand" "n"))
892                          (const_int 0)))]
893   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
894    && INTVAL (operands[1]) > 0 
895    && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
896    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32"
897   "*
899   unsigned int mask = 0;
900   int cnt = INTVAL (operands[1]);
901   
902   while (cnt--)
903     mask = (mask << 1) | 1;
904   operands[1] = GEN_INT (mask << INTVAL (operands[2]));
905   output_asm_insn (\"tst%?\\t%0, %1\", operands);
906   return \"\";
909 [(set_attr "conds" "set")])
911 (define_insn ""
912   [(set (reg:CC_NOOV 24)
913         (compare:CC_NOOV (zero_extract:SI
914                           (match_operand:QI 0 "memory_operand" "m")
915                           (match_operand 1 "immediate_operand" "n")
916                           (match_operand 2 "immediate_operand" "n"))
917                          (const_int 0)))
918    (clobber (match_scratch:QI 3 "=r"))]
919   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 8
920    && INTVAL (operands[1]) > 0 && INTVAL (operands[1]) <= 8"
921   "*
923   unsigned int mask = 0;
924   int cnt = INTVAL (operands[1]);
925   
926   while (cnt--)
927     mask = (mask << 1) | 1;
928   operands[1] = GEN_INT (mask << INTVAL (operands[2]));
929   output_asm_insn (\"ldr%?b\\t%3, %0\", operands);
930   output_asm_insn (\"tst%?\\t%3, %1\", operands);
931   return \"\";
934 [(set_attr "conds" "set")
935  (set_attr "length" "8")])
937 ;; constants for op 2 will never be given to these patterns.
938 (define_insn ""
939   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
940         (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r,0"))
941                 (match_operand:DI 1 "s_register_operand" "0,r")))]
942   ""
943   "bic%?\\t%0, %1, %2\;bic%?\\t%R0, %R1, %R2"
944 [(set_attr "length" "8")])
945   
946 (define_insn ""
947   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
948         (and:DI (not:DI (zero_extend:DI
949                          (match_operand:SI 2 "s_register_operand" "r,r")))
950                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
951   ""
952   "@
953    bic%?\\t%0, %1, %2
954    bic%?\\t%0, %1, %2\;mov%?\\t%R0, %R1"
955 [(set_attr "length" "4,8")])
956   
957 (define_insn ""
958   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
959         (and:DI (not:DI (sign_extend:DI
960                          (match_operand:SI 2 "s_register_operand" "r,r")))
961                 (match_operand:DI 1 "s_register_operand" "?r,0")))]
962   ""
963   "bic%?\\t%0, %1, %2\;bic%?\\t%R0, %R1, %2, asr #31"
964 [(set_attr "length" "8")])
965   
966 (define_insn ""
967   [(set (match_operand:SI 0 "s_register_operand" "=r")
968         (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
969                 (match_operand:SI 1 "s_register_operand" "r")))]
970   ""
971   "bic%?\\t%0, %1, %2")
973 (define_insn ""
974   [(set (reg:CC_NOOV 24)
975         (compare:CC_NOOV
976          (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
977                  (match_operand:SI 1 "s_register_operand" "r"))
978          (const_int 0)))
979    (set (match_operand:SI 0 "s_register_operand" "=r")
980         (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
981   ""
982   "bic%?s\\t%0, %1, %2"
983 [(set_attr "conds" "set")])
985 (define_insn ""
986   [(set (reg:CC_NOOV 24)
987         (compare:CC_NOOV
988          (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
989                  (match_operand:SI 1 "s_register_operand" "r"))
990          (const_int 0)))
991    (clobber (match_scratch:SI 0 "=r"))]
992   ""
993   "bic%?s\\t%0, %1, %2"
994 [(set_attr "conds" "set")])
996 (define_insn "iordi3"
997   [(set (match_operand:DI 0 "s_register_operand" "=&r")
998         (ior:DI (match_operand:DI 1 "s_register_operand" "%0")
999                 (match_operand:DI 2 "s_register_operand" "r")))]
1000   ""
1001   "orr%?\\t%0, %1, %2\;orr%?\\t%R0, %R1, %R2"
1002 [(set_attr "length" "8")])
1004 (define_insn ""
1005   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1006         (ior:DI (zero_extend:DI
1007                  (match_operand:SI 2 "s_register_operand" "r,r"))
1008                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
1009   ""
1010   "@
1011    orr%?\\t%0, %1, %2
1012    orr%?\\t%0, %1, %2\;mov%?\\t%R0, %R1"
1013 [(set_attr "length" "4,8")])
1015 (define_insn ""
1016   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1017         (ior:DI (sign_extend:DI
1018                  (match_operand:SI 2 "s_register_operand" "r,r"))
1019                 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1020   ""
1021   "orr%?\\t%0, %1, %2\;orr%?\\t%R0, %R1, %2, asr #31"
1022 [(set_attr "length" "8")])
1024 (define_insn "iorsi3"
1025   [(set (match_operand:SI 0 "s_register_operand" "=r")
1026         (ior:SI (match_operand:SI 1 "s_register_operand" "r")
1027                 (match_operand:SI 2 "arm_rhs_operand" "rI")))]
1028   ""
1029   "orr%?\\t%0, %1, %2")
1031 (define_insn ""
1032   [(set (reg:CC_NOOV 24)
1033         (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
1034                                  (match_operand:SI 2 "arm_rhs_operand" "rI"))
1035                          (const_int 0)))
1036    (set (match_operand:SI 0 "s_register_operand" "=r")
1037         (ior:SI (match_dup 1) (match_dup 2)))]
1038   ""
1039   "orr%?s\\t%0, %1, %2"
1040 [(set_attr "conds" "set")])
1042 (define_insn ""
1043   [(set (reg:CC_NOOV 24)
1044         (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
1045                                  (match_operand:SI 2 "arm_rhs_operand" "rI"))
1046                          (const_int 0)))
1047    (clobber (match_scratch:SI 0 "=r"))]
1048   ""
1049   "orr%?s\\t%0, %1, %2"
1050 [(set_attr "conds" "set")])
1052 (define_insn "xordi3"
1053   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1054         (xor:DI (match_operand:DI 1 "s_register_operand" "%0,0")
1055                 (match_operand:DI 2 "s_register_operand" "r,0")))]
1056   ""
1057   "eor%?\\t%0, %1, %2\;eor%?\\t%R0, %R1, %R2"
1058 [(set_attr "length" "8")])
1060 (define_insn ""
1061   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1062         (xor:DI (zero_extend:DI
1063                  (match_operand:SI 2 "s_register_operand" "r,r"))
1064                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
1065   ""
1066   "@
1067    eor%?\\t%0, %1, %2
1068    eor%?\\t%0, %1, %2\;mov%?\\t%R0, %R1"
1069 [(set_attr "length" "4,8")])
1071 (define_insn ""
1072   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1073         (xor:DI (sign_extend:DI
1074                  (match_operand:SI 2 "s_register_operand" "r,r"))
1075                 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1076   ""
1077   "eor%?\\t%0, %1, %2\;eor%?\\t%R0, %R1, %2, asr #31"
1078 [(set_attr "length" "8")])
1080 (define_insn "xorsi3"
1081   [(set (match_operand:SI 0 "s_register_operand" "=r")
1082         (xor:SI (match_operand:SI 1 "s_register_operand" "r")
1083                 (match_operand:SI 2 "arm_rhs_operand" "rI")))]
1084   ""
1085   "eor%?\\t%0, %1, %2")
1087 (define_insn ""
1088   [(set (reg:CC_NOOV 24)
1089         (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r")
1090                                  (match_operand:SI 2 "arm_rhs_operand" "rI"))
1091                          (const_int 0)))
1092    (set (match_operand:SI 0 "s_register_operand" "=r")
1093         (xor:SI (match_dup 1) (match_dup 2)))]
1094   ""
1095   "eor%?s\\t%0, %1, %2"
1096 [(set_attr "conds" "set")])
1098 (define_insn ""
1099   [(set (reg:CC_NOOV 24)
1100         (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r")
1101                                  (match_operand:SI 1 "arm_rhs_operand" "rI"))
1102                          (const_int 0)))]
1103   ""
1104   "teq%?\\t%0, %1"
1105 [(set_attr "conds" "set")])
1107 ;; by splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C), 
1108 ;; (NOT D) we can sometimes merge the final NOT into one of the following
1109 ;; insns
1111 (define_split
1112   [(set (match_operand:SI 0 "s_register_operand" "=r")
1113         (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" "r"))
1114                         (not:SI (match_operand:SI 2 "arm_rhs_operand" "rI")))
1115                 (match_operand:SI 3 "arm_rhs_operand" "rI")))
1116    (clobber (match_operand:SI 4 "s_register_operand" "=r"))]
1117   ""
1118   [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
1119                               (not:SI (match_dup 3))))
1120    (set (match_dup 0) (not:SI (match_dup 4)))]
1121   ""
1124 (define_insn ""
1125   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
1126         (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "r,r,0")
1127                         (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
1128                 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
1129   ""
1130   "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
1131 [(set_attr "length" "8")])
1135 ;; Minimum and maximum insns
1137 (define_insn "smaxsi3"
1138   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1139         (smax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
1140                  (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
1141    (clobber (reg:CC 24))]
1142   ""
1143   "@
1144    cmp\\t%1, %2\;movlt\\t%0, %2
1145    cmp\\t%1, %2\;movge\\t%0, %1
1146    cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
1147 [(set_attr "conds" "clob")
1148  (set_attr "length" "8,8,12")])
1150 (define_insn "sminsi3"
1151   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1152         (smin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
1153                  (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
1154    (clobber (reg:CC 24))]
1155   ""
1156   "@
1157    cmp\\t%1, %2\;movge\\t%0, %2
1158    cmp\\t%1, %2\;movlt\\t%0, %1
1159    cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
1160 [(set_attr "conds" "clob")
1161  (set_attr "length" "8,8,12")])
1163 (define_insn "umaxsi3"
1164   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1165         (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
1166                  (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
1167    (clobber (reg:CC 24))]
1168   ""
1169   "@
1170    cmp\\t%1, %2\;movcc\\t%0, %2
1171    cmp\\t%1, %2\;movcs\\t%0, %1
1172    cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
1173 [(set_attr "conds" "clob")
1174  (set_attr "length" "8,8,12")])
1176 (define_insn "uminsi3"
1177   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1178         (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
1179                  (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
1180    (clobber (reg:CC 24))]
1181   ""
1182   "@
1183    cmp\\t%1, %2\;movcs\\t%0, %2
1184    cmp\\t%1, %2\;movcc\\t%0, %1
1185    cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
1186 [(set_attr "conds" "clob")
1187  (set_attr "length" "8,8,12")])
1189 (define_insn ""
1190   [(set (match_operand:SI 0 "memory_operand" "=m")
1191         (match_operator:SI 3 "minmax_operator"
1192          [(match_operand:SI 1 "s_register_operand" "r")
1193           (match_operand:SI 2 "s_register_operand" "r")]))
1194    (clobber (reg:CC 24))]
1195   ""
1196   "*
1197   operands[3] = gen_rtx (minmax_code (operands[3]), SImode, operands[1],
1198                          operands[2]);
1199   output_asm_insn (\"cmp\\t%1, %2\", operands);
1200   output_asm_insn (\"str%d3\\t%1, %0\", operands);
1201   output_asm_insn (\"str%D3\\t%2, %0\", operands);
1202   return \"\";
1204 [(set_attr "conds" "clob")
1205  (set_attr "length" "12")
1206  (set_attr "type" "store1")])
1208 (define_insn ""
1209   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1210         (match_operator:SI 4 "shiftable_operator"
1211          [(match_operator:SI 5 "minmax_operator"
1212            [(match_operand:SI 2 "s_register_operand" "r,r")
1213             (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
1214           (match_operand:SI 1 "s_register_operand" "0,?r")]))
1215    (clobber (reg:CC 24))]
1216   ""
1217   "*
1219   enum rtx_code code = GET_CODE (operands[4]);
1221   operands[5] = gen_rtx (minmax_code (operands[5]), SImode, operands[2],
1222                          operands[3]);
1223   output_asm_insn (\"cmp\\t%2, %3\", operands);
1224   output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
1225   if (which_alternative != 0 || operands[3] != const0_rtx
1226       || (code != PLUS && code != MINUS && code != IOR && code != XOR))
1227     output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
1228   return \"\";
1231 [(set_attr "conds" "clob")
1232  (set_attr "length" "12")])
1235 ;; Shift and rotation insns
1237 (define_insn "ashlsi3"
1238   [(set (match_operand:SI 0 "s_register_operand" "=r")
1239         (ashift:SI (match_operand:SI 1 "s_register_operand" "r")
1240                    (match_operand:SI 2 "arm_rhs_operand" "rn")))]
1241   ""
1242   "mov%?\\t%0, %1, asl %2")
1244 (define_insn "ashrsi3"
1245   [(set (match_operand:SI 0 "s_register_operand" "=r")
1246         (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "r")
1247                      (match_operand:SI 2 "arm_rhs_operand" "rn")))]
1248   ""
1249   "mov%?\\t%0, %1, asr %2")
1251 (define_insn "lshrsi3"
1252   [(set (match_operand:SI 0 "s_register_operand" "=r")
1253         (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "r")
1254                      (match_operand:SI 2 "arm_rhs_operand" "rn")))]
1255   ""
1256   "mov%?\\t%0, %1, lsr %2")
1258 ;; rotlsi3 is not defined yet to see what happens
1260 (define_insn "rotrsi3"
1261   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1262         (rotatert:SI (match_operand:SI 1 "s_register_operand" "r,r")
1263                      (match_operand:SI 2 "arm_rhs_operand" "r,n")))]
1264   ""
1265   "*
1266   switch (which_alternative)
1267     {
1268     case 0:
1269       return \"mov%?\\t%0, %1, ror %2\";
1270     case 1:
1271       if (INTVAL(operands[2]) > 31)
1272         operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
1273       output_asm_insn (\"mov%?\\t%0, %1, ror %2\", operands);
1274       return \"\";
1275     }
1278 (define_insn ""
1279   [(set (reg:CC_NOOV 24)
1280         (compare:CC_NOOV (match_operator:SI 1 "shift_operator"
1281                           [(match_operand:SI 2 "s_register_operand" "r")
1282                            (match_operand:SI 3 "arm_rhs_operand" "rn")])
1283                          (const_int 0)))
1284    (set (match_operand:SI 0 "s_register_operand" "=r")
1285         (match_op_dup 1 [(match_dup 2) (match_dup 3)]))]
1286   ""
1287   "mov%?s\\t%0, %2, %S1"
1288 [(set_attr "conds" "set")])
1290 (define_insn ""
1291   [(set (reg:CC_NOOV 24)
1292         (compare:CC_NOOV (match_operator:SI 1 "shift_operator"
1293                           [(match_operand:SI 2 "s_register_operand" "r")
1294                            (match_operand:SI 3 "arm_rhs_operand" "rn")])
1295                          (const_int 0)))
1296    (clobber (match_scratch:SI 0 "=r"))]
1297   ""
1298   "mov%?s\\t%0, %2, %S1"
1299 [(set_attr "conds" "set")])
1301 (define_insn ""
1302   [(set (match_operand:SI 0 "s_register_operand" "=r")
1303         (not:SI (match_operator:SI 1 "shift_operator"
1304                  [(match_operand:SI 2 "s_register_operand" "r")
1305                   (match_operand:SI 3 "arm_rhs_operand" "rn")])))]
1306   ""
1307   "mvn%?\\t%0, %2, %S1")
1309 (define_insn ""
1310   [(set (reg:CC_NOOV 24)
1311         (compare:CC_NOOV (not:SI (match_operator:SI 1 "shift_operator"
1312                           [(match_operand:SI 2 "s_register_operand" "r")
1313                            (match_operand:SI 3 "arm_rhs_operand" "rn")]))
1314                          (const_int 0)))
1315    (set (match_operand:SI 0 "s_register_operand" "=r")
1316         (not:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])))]
1317   ""
1318   "mvn%?s\\t%0, %2, %S1"
1319 [(set_attr "conds" "set")])
1321 (define_insn ""
1322   [(set (reg:CC_NOOV 24)
1323         (compare:CC_NOOV (not:SI (match_operator:SI 1 "shift_operator"
1324                           [(match_operand:SI 2 "s_register_operand" "r")
1325                            (match_operand:SI 3 "arm_rhs_operand" "rn")]))
1326                          (const_int 0)))
1327    (clobber (match_scratch:SI 0 "=r"))]
1328   ""
1329   "mvn%?s\\t%0, %2, %S1"
1330 [(set_attr "conds" "set")])
1333 ;; Unary arithmetic insns
1335 (define_insn "negdi2"
1336   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1337         (neg:DI (match_operand:DI 1 "s_register_operand" "?r,0")))]
1338   ""
1339   "rsbs\\t%0, %1, #0\;rsc\\t%R0, %R1, #0"
1340 [(set_attr "conds" "clob")
1341  (set_attr "length" "8")])
1343 (define_insn "negsi2"
1344   [(set (match_operand:SI 0 "s_register_operand" "=r")
1345         (neg:SI (match_operand:SI 1 "s_register_operand" "r")))]
1346   ""
1347   "rsb%?\\t%0, %1, #0")
1349 (define_insn "negsf2"
1350   [(set (match_operand:SF 0 "s_register_operand" "=f")
1351         (neg:SF (match_operand:SF 1 "s_register_operand" "f")))]
1352   ""
1353   "mnf%?s\\t%0, %1"
1354 [(set_attr "type" "float")])
1356 (define_insn "negdf2"
1357   [(set (match_operand:DF 0 "s_register_operand" "=f")
1358         (neg:DF (match_operand:DF 1 "s_register_operand" "f")))]
1359   ""
1360   "mnf%?d\\t%0, %1"
1361 [(set_attr "type" "float")])
1363 (define_insn ""
1364   [(set (match_operand:DF 0 "s_register_operand" "=f")
1365         (neg:DF (float_extend:DF
1366                  (match_operand:SF 1 "s_register_operand" "f"))))]
1367   ""
1368   "mnf%?d\\t%0, %1"
1369 [(set_attr "type" "float")])
1371 (define_insn "negxf2"
1372   [(set (match_operand:XF 0 "s_register_operand" "=f")
1373         (neg:XF (match_operand:XF 1 "s_register_operand" "f")))]
1374   "ENABLE_XF_PATTERNS"
1375   "mnf%?e\\t%0, %1"
1376 [(set_attr "type" "float")])
1378 ;; abssi2 doesn't really clobber the condition codes if a different register
1379 ;; is being set.  To keep things simple, assume during rtl manipulations that
1380 ;; it does, but tell the final scan operator the truth.  Similarly for
1381 ;; (neg (abs...))
1383 (define_insn "abssi2"
1384   [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
1385         (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
1386    (clobber (reg 24))]
1387   ""
1388   "@
1389    cmp\\t%0, #0\;rsblt\\t%0, %0, #0
1390    eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31"
1391 [(set_attr "conds" "clob,*")
1392  (set_attr "length" "8")])
1394 (define_insn ""
1395   [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
1396         (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
1397    (clobber (reg 24))]
1398   ""
1399   "@
1400    cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
1401    eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31"
1402 [(set_attr "conds" "clob,*")
1403  (set_attr "length" "8")])
1405 (define_insn "abssf2"
1406   [(set (match_operand:SF 0 "s_register_operand" "=f")
1407          (abs:SF (match_operand:SF 1 "s_register_operand" "f")))]
1408   ""
1409   "abs%?s\\t%0, %1"
1410 [(set_attr "type" "float")])
1412 (define_insn "absdf2"
1413   [(set (match_operand:DF 0 "s_register_operand" "=f")
1414         (abs:DF (match_operand:DF 1 "s_register_operand" "f")))]
1415   ""
1416   "abs%?d\\t%0, %1"
1417 [(set_attr "type" "float")])
1419 (define_insn ""
1420   [(set (match_operand:DF 0 "s_register_operand" "=f")
1421         (abs:DF (float_extend:DF
1422                  (match_operand:SF 1 "s_register_operand" "f"))))]
1423   ""
1424   "abs%?d\\t%0, %1"
1425 [(set_attr "type" "float")])
1427 (define_insn "absxf2"
1428   [(set (match_operand:XF 0 "s_register_operand" "=f")
1429         (abs:XF (match_operand:XF 1 "s_register_operand" "f")))]
1430   "ENABLE_XF_PATTERNS"
1431   "abs%?e\\t%0, %1"
1432 [(set_attr "type" "float")])
1434 (define_insn "sqrtsf2"
1435   [(set (match_operand:SF 0 "s_register_operand" "=f")
1436         (sqrt:SF (match_operand:SF 1 "s_register_operand" "f")))]
1437   ""
1438   "sqt%?s\\t%0, %1"
1439 [(set_attr "type" "float_em")])
1441 (define_insn "sqrtdf2"
1442   [(set (match_operand:DF 0 "s_register_operand" "=f")
1443         (sqrt:DF (match_operand:DF 1 "s_register_operand" "f")))]
1444   ""
1445   "sqt%?d\\t%0, %1"
1446 [(set_attr "type" "float_em")])
1448 (define_insn ""
1449   [(set (match_operand:DF 0 "s_register_operand" "=f")
1450         (sqrt:DF (float_extend:DF
1451                   (match_operand:SF 1 "s_register_operand" "f"))))]
1452   ""
1453   "sqt%?d\\t%0, %1"
1454 [(set_attr "type" "float_em")])
1456 (define_insn "sqrtxf2"
1457   [(set (match_operand:XF 0 "s_register_operand" "=f")
1458         (sqrt:XF (match_operand:XF 1 "s_register_operand" "f")))]
1459   "ENABLE_XF_PATTERNS"
1460   "sqt%?e\\t%0, %1"
1461 [(set_attr "type" "float_em")])
1463 (define_insn "sinsf2"
1464   [(set (match_operand:SF 0 "s_register_operand" "=f")
1465         (unspec:SF [(match_operand:SF 1 "s_register_operand" "f")] 0))]
1466   ""
1467   "sin%?s\\t%0, %1"
1468 [(set_attr "type" "float_em")])
1470 (define_insn "sindf2"
1471   [(set (match_operand:DF 0 "s_register_operand" "=f")
1472         (unspec:DF [(match_operand:DF 1 "s_register_operand" "f")] 0))]
1473   ""
1474   "sin%?d\\t%0, %1"
1475 [(set_attr "type" "float_em")])
1477 (define_insn ""
1478   [(set (match_operand:DF 0 "s_register_operand" "=f")
1479         (unspec:DF [(float_extend:DF
1480                      (match_operand:SF 1 "s_register_operand" "f"))] 0))]
1481   ""
1482   "sin%?d\\t%0, %1"
1483 [(set_attr "type" "float_em")])
1485 (define_insn "sinxf2"
1486   [(set (match_operand:XF 0 "s_register_operand" "=f")
1487         (unspec:XF [(match_operand:XF 1 "s_register_operand" "f")] 0))]
1488   "ENABLE_XF_PATTERNS"
1489   "sin%?e\\t%0, %1"
1490 [(set_attr "type" "float_em")])
1492 (define_insn "cossf2"
1493   [(set (match_operand:SF 0 "s_register_operand" "=f")
1494         (unspec:SF [(match_operand:SF 1 "s_register_operand" "f")] 1))]
1495   ""
1496   "cos%?s\\t%0, %1"
1497 [(set_attr "type" "float_em")])
1499 (define_insn "cosdf2"
1500   [(set (match_operand:DF 0 "s_register_operand" "=f")
1501         (unspec:DF [(match_operand:DF 1 "s_register_operand" "f")] 1))]
1502   ""
1503   "cos%?d\\t%0, %1"
1504 [(set_attr "type" "float_em")])
1506 (define_insn ""
1507   [(set (match_operand:DF 0 "s_register_operand" "=f")
1508         (unspec:DF [(float_extend:DF
1509                      (match_operand:SF 1 "s_register_operand" "f"))] 1))]
1510   ""
1511   "cos%?d\\t%0, %1"
1512 [(set_attr "type" "float_em")])
1514 (define_insn "cosxf2"
1515   [(set (match_operand:XF 0 "s_register_operand" "=f")
1516         (unspec:XF [(match_operand:XF 1 "s_register_operand" "f")] 1))]
1517   "ENABLE_XF_PATTERNS"
1518   "cos%?e\\t%0, %1"
1519 [(set_attr "type" "float_em")])
1521 (define_insn "one_cmpldi2"
1522   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1523         (not:DI (match_operand:DI 1 "s_register_operand" "?r,0")))]
1524   ""
1525   "mvn%?\\t%0, %1\;mvn%?\\t%R0, %R1"
1526 [(set_attr "length" "8")])
1528 (define_insn "one_cmplsi2"
1529   [(set (match_operand:SI 0 "s_register_operand" "=r")
1530         (not:SI (match_operand:SI 1 "s_register_operand" "r")))]
1531   ""
1532   "mvn%?\\t%0, %1")
1534 (define_insn ""
1535   [(set (reg:CC_NOOV 24)
1536         (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
1537                          (const_int 0)))
1538    (set (match_operand:SI 0 "s_register_operand" "=r")
1539         (not:SI (match_dup 1)))]
1540   ""
1541   "mvn%?s\\t%0, %1"
1542 [(set_attr "conds" "set")])
1544 (define_insn ""
1545   [(set (reg:CC_NOOV 24)
1546         (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
1547                          (const_int 0)))
1548    (clobber (match_scratch:SI 0 "=r"))]
1549   ""
1550   "mvn%?s\\t%0, %1"
1551 [(set_attr "conds" "set")])
1553 ;; Fixed <--> Floating conversion insns
1555 (define_insn "floatsisf2"
1556   [(set (match_operand:SF 0 "s_register_operand" "=f")
1557         (float:SF (match_operand:SI 1 "s_register_operand" "r")))]
1558   ""
1559   "flt%?s\\t%0, %1"
1560 [(set_attr "type" "r_2_f")])
1562 (define_insn "floatsidf2"
1563   [(set (match_operand:DF 0 "s_register_operand" "=f")
1564         (float:DF (match_operand:SI 1 "s_register_operand" "r")))]
1565   ""
1566   "flt%?d\\t%0, %1"
1567 [(set_attr "type" "r_2_f")])
1569 (define_insn "floatsixf2"
1570   [(set (match_operand:XF 0 "s_register_operand" "=f")
1571         (float:XF (match_operand:SI 1 "s_register_operand" "r")))]
1572   "ENABLE_XF_PATTERNS"
1573   "flt%?e\\t%0, %1"
1574 [(set_attr "type" "r_2_f")])
1576 (define_insn "fix_truncsfsi2"
1577   [(set (match_operand:SI 0 "s_register_operand" "=r")
1578         (fix:SI (match_operand:SF 1 "s_register_operand" "f")))]
1579   ""
1580   "fix%?z\\t%0, %1"
1581 [(set_attr "type" "f_2_r")])
1583 (define_insn "fix_truncdfsi2"
1584   [(set (match_operand:SI 0 "s_register_operand" "=r")
1585         (fix:SI (match_operand:DF 1 "s_register_operand" "f")))]
1586   ""
1587   "fix%?z\\t%0, %1"
1588 [(set_attr "type" "f_2_r")])
1590 (define_insn "fix_truncxfsi2"
1591   [(set (match_operand:SI 0 "s_register_operand" "=r")
1592         (fix:SI (match_operand:XF 1 "s_register_operand" "f")))]
1593   "ENABLE_XF_PATTERNS"
1594   "fix%?z\\t%0, %1"
1595 [(set_attr "type" "f_2_r")])
1597 ;; Truncation insns
1599 (define_insn "truncdfsf2"
1600   [(set (match_operand:SF 0 "s_register_operand" "=f")
1601         (float_truncate:SF
1602          (match_operand:DF 1 "s_register_operand" "f")))]
1603   ""
1604   "mvf%?s\\t%0, %1"
1605 [(set_attr "type" "float")])
1607 (define_insn "truncxfsf2"
1608   [(set (match_operand:SF 0 "s_register_operand" "=f")
1609         (float_truncate:SF
1610          (match_operand:XF 1 "s_register_operand" "f")))]
1611   "ENABLE_XF_PATTERNS"
1612   "mvf%?s\\t%0, %1"
1613 [(set_attr "type" "float")])
1615 (define_insn "truncxfdf2"
1616   [(set (match_operand:DF 0 "s_register_operand" "=f")
1617         (float_truncate:DF
1618          (match_operand:XF 1 "s_register_operand" "f")))]
1619   "ENABLE_XF_PATTERNS"
1620   "mvf%?d\\t%0, %1"
1621 [(set_attr "type" "float")])
1623 ;; Zero and sign extension instructions.
1625 (define_insn "zero_extendsidi2"
1626   [(set (match_operand:DI 0 "s_register_operand" "=r")
1627         (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
1628   ""
1629   "*
1630   if (REGNO (operands[1]) != REGNO (operands[0]))
1631     output_asm_insn (\"mov%?\\t%0, %1\", operands);
1632   return \"mov%?\\t%R0, #0\";
1634 [(set_attr "length" "8")])
1636 (define_insn "zero_extendqidi2"
1637   [(set (match_operand:DI 0 "s_register_operand" "=r,r")
1638         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1639   ""
1640   "@
1641    and%?\\t%0, %1, #255\;mov%?\\t%R0, #0
1642    ldr%?b\\t%0, %1\;mov%?\\t%R0, #0"
1643 [(set_attr "length" "8")
1644  (set_attr "type" "*,load")])
1646 (define_insn "extendsidi2"
1647   [(set (match_operand:DI 0 "s_register_operand" "=r")
1648         (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
1649   ""
1650   "*
1651   if (REGNO (operands[1]) != REGNO (operands[0]))
1652     output_asm_insn (\"mov%?\\t%0, %1\", operands);
1653   return \"mov%?\\t%R0, %0, asr #31\";
1655 [(set_attr "length" "8")])
1657 (define_expand "zero_extendhisi2"
1658   [(set (match_dup 2)
1659         (ashift:SI (match_operand:HI 1 "s_register_operand" "")
1660                    (const_int 16)))
1661    (set (match_operand:SI 0 "s_register_operand" "")
1662         (lshiftrt:SI (match_dup 2)
1663                      (const_int 16)))]
1664   ""
1665   "
1666 { operands[1] = gen_lowpart (SImode, operands[1]);
1667   operands[2] = gen_reg_rtx (SImode); }")
1669 (define_insn "zero_extendqihi2"
1670   [(set (match_operand:HI 0 "s_register_operand" "=r")
1671         (zero_extend:HI
1672          (match_operand:QI 1 "s_register_operand" "r")))]
1673   ""
1674   "and%?\\t%0, %1, #255\\t%@ zero_extendqihi2")
1676 (define_insn ""
1677   [(set (reg:CC_NOOV 24)
1678         (compare:CC_NOOV (match_operand:QI 1 "s_register_operand" "r")
1679                          (const_int 0)))
1680    (set (match_operand:SI 0 "s_register_operand" "=r")
1681         (zero_extend:HI (match_dup 1)))]
1682   ""
1683   "and%?s\\t%0, %1, #255"
1684 [(set_attr "conds" "set")])
1686 (define_insn ""
1687   [(set (reg:CC_NOOV 24)
1688         (compare:CC_NOOV (match_operand:QI 0 "s_register_operand" "r")
1689                          (const_int 0)))]
1690   ""
1691   "tst%?\\t%0, #255"
1692 [(set_attr "conds" "set")])
1694 (define_insn "zero_extendqisi2"
1695   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1696         (zero_extend:SI
1697          (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1698   ""
1699   "@
1700    and%?\\t%0, %1, #255\\t%@ zero_extendqisi2
1701    ldr%?b\\t%0, %1\\t%@ zero_extendqisi2"
1702 [(set_attr "type" "*,load")])
1704 (define_insn ""
1705   [(set (reg:CC_NOOV 24)
1706         (compare:CC_NOOV (match_operand:QI 1 "s_register_operand" "r")
1707                          (const_int 0)))
1708    (set (match_operand:SI 0 "s_register_operand" "=r")
1709         (zero_extend:SI (match_dup 1)))]
1710   ""
1711   "and%?s\\t%0, %1, #255"
1712 [(set_attr "conds" "set")])
1714 (define_insn ""
1715   [(set (reg:CC_NOOV 24)
1716         (compare:CC_NOOV (match_operand:QI 1 "s_register_operand" "r")
1717                          (const_int 0)))
1718    (set (match_operand:QI 0 "s_register_operand" "=r")
1719         (match_dup 1))]
1720   ""
1721   "and%?s\\t%0, %1, #255"
1722 [(set_attr "conds" "set")])
1724 (define_expand "extendhisi2"
1725   [(set (match_dup 2)
1726         (ashift:SI (match_operand:HI 1 "s_register_operand" "")
1727                    (const_int 16)))
1728    (set (match_operand:SI 0 "s_register_operand" "")
1729         (ashiftrt:SI (match_dup 2)
1730                      (const_int 16)))]
1731   ""
1732   "
1733 { operands[1] = gen_lowpart (SImode, operands[1]);
1734   operands[2] = gen_reg_rtx (SImode); }")
1736 (define_expand "extendqihi2"
1737   [(set (match_dup 2)
1738         (ashift:SI (match_operand:QI 1 "s_register_operand" "")
1739                    (const_int 24)))
1740    (set (match_operand:HI 0 "s_register_operand" "")
1741         (ashiftrt:SI (match_dup 2)
1742                      (const_int 24)))]
1743   ""
1744   "
1745 { operands[0] = gen_lowpart (SImode, operands[0]);
1746   operands[1] = gen_lowpart (SImode, operands[1]);
1747   operands[2] = gen_reg_rtx (SImode); }")
1749 (define_expand "extendqisi2"
1750   [(set (match_dup 2)
1751         (ashift:SI (match_operand:QI 1 "s_register_operand" "")
1752                    (const_int 24)))
1753    (set (match_operand:SI 0 "s_register_operand" "")
1754         (ashiftrt:SI (match_dup 2)
1755                      (const_int 24)))]
1756   ""
1757   "
1758 { operands[1] = gen_lowpart (SImode, operands[1]);
1759   operands[2] = gen_reg_rtx (SImode); }")
1761 (define_insn "extendsfdf2"
1762   [(set (match_operand:DF 0 "s_register_operand" "=f")
1763         (float_extend:DF (match_operand:SF 1 "s_register_operand" "f")))]
1764   ""
1765   "mvf%?d\\t%0, %1"
1766 [(set_attr "type" "float")])
1768 (define_insn "extendsfxf2"
1769   [(set (match_operand:XF 0 "s_register_operand" "=f")
1770         (float_extend:XF (match_operand:SF 1 "s_register_operand" "f")))]
1771   "ENABLE_XF_PATTERNS"
1772   "mvf%?e\\t%0, %1")
1774 (define_insn "extenddfxf2"
1775   [(set (match_operand:XF 0 "s_register_operand" "=f")
1776         (float_extend:XF (match_operand:DF 1 "s_register_operand" "f")))]
1777   "ENABLE_XF_PATTERNS"
1778   "mvf%?e\\t%0, %1"
1779 [(set_attr "type" "float")])
1782 ;; Move insns (including loads and stores)
1784 ;; XXX Just some ideas about movti.
1785 ;; I don't think these are a good idea on the arm, there just aren't enough
1786 ;; registers
1787 ;;(define_expand "loadti"
1788 ;;  [(set (match_operand:TI 0 "s_register_operand" "")
1789 ;;      (mem:TI (match_operand:SI 1 "address_operand" "")))]
1790 ;;  "" "")
1792 ;;(define_expand "storeti"
1793 ;;  [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
1794 ;;      (match_operand:TI 1 "s_register_operand" ""))]
1795 ;;  "" "")
1797 ;;(define_expand "movti"
1798 ;;  [(set (match_operand:TI 0 "general_operand" "")
1799 ;;      (match_operand:TI 1 "general_operand" ""))]
1800 ;;  ""
1801 ;;  "
1803 ;;  rtx insn;
1805 ;;  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1806 ;;    operands[1] = copy_to_reg (operands[1]);
1807 ;;  if (GET_CODE (operands[0]) == MEM)
1808 ;;    insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
1809 ;;  else if (GET_CODE (operands[1]) == MEM)
1810 ;;    insn = gen_loadti (operands[0], XEXP (operands[1], 0));
1811 ;;  else
1812 ;;    FAIL;
1814 ;;  emit_insn (insn);
1815 ;;  DONE;
1816 ;;}")
1818 ;; Recognise garbage generated above.
1820 ;;(define_insn ""
1821 ;;  [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
1822 ;;      (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
1823 ;;  ""
1824 ;;  "*
1825 ;;  {
1826 ;;    register mem = (which_alternative < 3);
1827 ;;    register char *template;
1829 ;;    operands[mem] = XEXP (operands[mem], 0);
1830 ;;    switch (which_alternative)
1831 ;;      {
1832 ;;      case 0: template = \"ldmdb\\t%1!, %M0\"; break;
1833 ;;      case 1: template = \"ldmia\\t%1!, %M0\"; break;
1834 ;;      case 2: template = \"ldmia\\t%1, %M0\"; break;
1835 ;;      case 3: template = \"stmdb\\t%0!, %M1\"; break;
1836 ;;      case 4: template = \"stmia\\t%0!, %M1\"; break;
1837 ;;      case 5: template = \"stmia\\t%0, %M1\"; break;
1838 ;;      }
1839 ;;    output_asm_insn (template, operands);
1840 ;;    return \"\";
1841 ;;  }")
1844 (define_insn "movdi"
1845   [(set (match_operand:DI 0 "di_operand" "=r,r,r,o<>,r")
1846         (match_operand:DI 1 "di_operand" "rK,n,o<>,r,F"))]
1847   ""
1848   "*
1849   return (output_move_double (operands));
1851 [(set_attr "length" "8,32,8,8,32")
1852  (set_attr "type" "*,*,load,store2,*")])
1854 (define_expand "movsi"
1855   [(set (match_operand:SI 0 "general_operand" "")
1856         (match_operand:SI 1 "general_operand" ""))]
1857   ""
1858   "
1859   /* Everything except mem = const or mem = mem can be done easily */
1860   if (GET_CODE (operands[0]) == MEM)
1861     operands[1] = force_reg (SImode, operands[1]);
1862   if (GET_CODE (operands[1]) == CONST_INT
1863       && !(const_ok_for_arm (INTVAL (operands[1]))
1864            || const_ok_for_arm (~INTVAL (operands[1]))))
1865     {
1866       int n = INTVAL (operands[1]);
1867       rtx tmpreg, tmpreg2;
1868       int i, n_ones = 0, first = 1, last = 0;
1870       if (GET_CODE (operands[0]) != REG
1871           && GET_CODE (operands[0]) != SUBREG)
1872         abort ();
1873       for (i = 0; i < 32; i++)
1874         if (n & 1 << i)
1875           n_ones++;
1876       /* These loops go the opposite way around to those in arm.c so that
1877          the last constant may be more likely to be eliminted into the
1878          next instruction */
1880       if (n_ones > 16)
1881         {
1882           n = (~n) & 0xffffffff;
1883           for (i = 30; i >= 0; i -= 2)
1884             {
1885               if (n & (3 << i))
1886                 {
1887                   i -= 6;
1888                   if (i < 0)
1889                     i = 0;
1890                   if ((n & (255 << i)) == n)
1891                     last = 1;
1892                   if (first)
1893                     {
1894                       rtx equal;
1895                       rtx insn =
1896                         emit_insn (gen_movsi (tmpreg = (reload_in_progress
1897                                                         || reload_completed)
1898                                                       ? operands[0]
1899                                                       : gen_reg_rtx (SImode),
1900                                       equal = gen_rtx (CONST_INT, VOIDmode,
1901                                                        ~(n & (255 << i)))));
1902                       first = 0;
1903                     }
1904                   else
1905                     {
1906                       rtx constant;
1907                       rtx insn =
1908                         emit_insn (gen_subsi3 (tmpreg2 = (reload_in_progress
1909                                                           || reload_completed
1910                                                           || last)
1911                                                         ? operands[0]
1912                                                         : gen_reg_rtx (SImode),
1913                                                tmpreg,
1914                                     constant = gen_rtx (CONST_INT, VOIDmode,
1915                                                         n & (255 << i))));
1916                       tmpreg = tmpreg2;
1917                     }
1918                   n &= ~(255 << i);
1919                 }
1920             }
1921         }
1922       else
1923         {
1924           for (i = 30; i >= 0; i -= 2)
1925             {
1926               if (n & (3 << i))
1927                 {
1928                   i -= 6;
1929                   if (i < 0)
1930                     i = 0;
1931                   if ((n & (255 << i)) == n)
1932                     last = 1;
1933                   if (first)
1934                     {
1935                       rtx equal;
1936                       rtx insn =
1937                         emit_insn (gen_movsi (tmpreg = (reload_in_progress
1938                                                         || reload_completed)
1939                                                       ? operands[0]
1940                                                       : gen_reg_rtx (SImode),
1941                                       equal = gen_rtx (CONST_INT, VOIDmode,
1942                                                        n & (255 << i))));
1943                       first = 0;
1944                     }
1945                   else
1946                     {
1947                       rtx constant;
1948                       rtx insn =
1949                         emit_insn (gen_addsi3 (tmpreg2 = (reload_in_progress
1950                                                           || reload_completed
1951                                                           || last)
1952                                                         ? operands[0]
1953                                                         : gen_reg_rtx (SImode),
1954                                                tmpreg,
1955                                     constant = gen_rtx (CONST_INT, VOIDmode,
1956                                                         n & (255 << i))));
1957                       tmpreg = tmpreg2;
1958                     }
1959                   n &= ~(255 << i);
1960                 }
1961             }
1962         }
1963       DONE;
1964     }
1967 (define_insn ""
1968   [(set (match_operand:SI 0 "general_operand" "=r,r,r,r,m,r")
1969         (match_operand:SI 1 "general_operand"  "R,m,K,r,r,S"))]
1970   "(register_operand (operands[0], SImode)
1971     && (GET_CODE (operands[1]) != CONST_INT
1972         || const_ok_for_arm (INTVAL (operands[1]))
1973         || const_ok_for_arm (~INTVAL (operands[1])))
1974     && (GET_CODE (operands[1]) != SYMBOL_REF
1975         || CONSTANT_ADDRESS_P (operands[1])))
1976    || register_operand (operands[1], SImode)"
1977   "*
1978   switch (which_alternative)
1979     {
1980     case 0:
1981       /* NB Calling get_attr_length may cause the insn to be re-extracted... */
1982       if (get_attr_length (insn) == 8)
1983         {
1984           /* ... so modify the operands here.  */
1985           operands[1] = XEXP (operands[1], 0);
1986           output_asm_insn (\"sub%?\\t%0, pc, #(8 + . - %a1) & ~4095\",
1987                            operands);
1988           output_asm_insn (\"ldr%?\\t%0, [%0, #- ((4 + . - %a1) & 4095)]\",
1989                            operands);
1990         }
1991       else
1992         {
1993           /* ... and here.  */
1994           operands[1] = XEXP (operands[1], 0);
1995           output_asm_insn (\"ldr%?\\t%0, [pc, %1 - . - 8]\", operands);
1996         }
1997       return \"\";
1999     case 1:
2000       if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2001           &&  CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0)))
2002         abort ();
2003       return \"ldr%?\\t%0, %1\";
2005     case 3:
2006       return \"mov%?\\t%0, %1\";
2007     case 2:
2008       if (!const_ok_for_arm (INTVAL (operands[1])))
2009         {
2010           operands[1] = GEN_INT (~INTVAL (operands[1]));
2011           output_asm_insn (\"mvn%?\\t%0, %1\", operands);
2012           return \"\";
2013         }
2014       return \"mov%?\\t%0, %1\";
2015     case 4:
2016       return \"str%?\\t%1, %0\";
2017     case 5:
2018       return output_load_symbol (insn, operands);
2019     }
2021 [(set (attr "length")
2022       (cond [(eq_attr "alternative" "0")
2023              (if_then_else
2024               (gt (minus 
2025                    (pc)
2026                    (symbol_ref "const_pool_offset (XEXP (operands[1], 0))"))
2027                   (const_int 4087))
2028               (const_int 8)
2029               (const_int 4))
2030              (eq_attr "alternative" "5") (const_int 16)]
2031             (const_int 4)))
2032  (set_attr "type" "load,load,*,*,store1,*")])
2034 ;; If copying one reg to another we can set the condition codes according to
2035 ;; its value.  Such a move is common after a return from subroutine and the
2036 ;; result is being tested against zero.
2038 (define_insn ""
2039   [(set (reg:CC 24) (compare (match_operand:SI 1 "s_register_operand" "0,r")
2040                              (const_int 0)))
2041    (set (match_operand:SI 0 "s_register_operand" "=r,r") (match_dup 1))]
2042   ""
2043   "@
2044    cmp%?\\t%0, #0
2045    sub%?s\\t%0, %1, #0"
2046 [(set_attr "conds" "set")])
2048 ;; Subroutine to store a half word from a register into memory.
2049 ;; Operand 0 is the source register (HImode)
2050 ;; Operand 1 is the destination address in a register (SImode)
2052 ;; In both this routine and the next, we must be careful not to spill
2053 ;; a memory address of reg+large_const into a seperate PLUS insn, since this
2054 ;; can generate unrecognizable rtl.
2056 (define_expand "storehi"
2057   [;; store the low byte
2058    (set (mem:QI (match_operand:SI 1 "" "")) (match_dup 3))
2059    ;; extract the high byte
2060    (set (match_dup 2)
2061         (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
2062    ;; store the high byte
2063    (set (mem:QI (match_dup 4))
2064         (subreg:QI (match_dup 2) 0))]   ;explicit subreg safe
2065   ""
2066   "
2068   enum rtx_code code = GET_CODE (operands[1]);
2070   if ((code == PLUS || code == MINUS)
2071       && (GET_CODE (XEXP (operands[1], 1)) == REG
2072           || GET_CODE (XEXP (operands[1], 0)) != REG))
2073     operands[1] = force_reg (SImode, operands[1]);
2074   operands[4] = plus_constant (operands[1], 1);
2075   operands[3] = gen_lowpart (QImode, operands[0]);
2076   operands[0] = gen_lowpart (SImode, operands[0]);
2077   operands[2] = gen_reg_rtx (SImode); 
2081 ;; Subroutine to store a half word integer constant into memory.
2082 ;; Operand 0 is the constant
2083 ;; Operand 1 is the destination address in a register (SImode)
2085 (define_expand "storeinthi"
2086   [;; store the low byte
2087    (set (mem:QI (match_operand:SI 1 "" "")) (match_operand 0 "" ""))
2088    ;; store the high byte
2089    (set (mem:QI (match_dup 3)) (match_dup 2))]
2090   ""
2091   "
2093   int value = INTVAL (operands[0]);
2094   enum rtx_code code = GET_CODE (operands[1]);
2096   if ((code == PLUS || code == MINUS)
2097       && (GET_CODE (XEXP (operands[1], 1)) == REG
2098           || GET_CODE (XEXP (operands[1], 0)) != REG))
2099   operands[1] = force_reg (SImode, operands[1]);
2101   operands[0] = force_reg (QImode, gen_rtx (CONST_INT, VOIDmode, value & 255));
2102   operands[2] = force_reg (QImode,
2103                            gen_rtx (CONST_INT, VOIDmode,(value>>8) & 255));
2104   operands[3] = plus_constant (operands[1], 1);
2108 (define_expand "movhi"
2109   [(set (match_operand:HI 0 "general_operand" "")
2110         (match_operand:HI 1 "general_operand" ""))]
2111   ""
2112   "
2114   rtx insn;
2116   if (reload_in_progress || reload_completed)
2117     insn = gen_rtx (SET, VOIDmode, operands[0], operands[1]);
2118   else
2119     {
2120       if (GET_CODE (operands[0]) == MEM)
2121         {
2122           if (GET_CODE (operands[1]) == CONST_INT)
2123             {
2124               insn = gen_storeinthi (operands[1], XEXP (operands[0],0));
2125             }
2126           else
2127             {
2128               if (GET_CODE (operands[1]) == MEM)
2129                 operands[1] = force_reg (HImode, operands[1]);
2130               insn = gen_storehi (operands[1], XEXP (operands[0], 0));
2131             }
2132         }
2133       else if (GET_CODE (operands[1]) == CONST_INT
2134                && !(const_ok_for_arm (INTVAL (operands[1]))
2135                    || const_ok_for_arm (~INTVAL (operands[1]))))
2136         {
2137           rtx reg, reg2;
2139           /* no need to be clever, this will always take two insns.
2140              The top sixteen bits should be all zeros or all ones. */
2141           if (INTVAL (operands[1]) < 0)
2142             {
2143               emit_insn (gen_movsi (reg = gen_reg_rtx (SImode),
2144                                     GEN_INT (INTVAL (operands[1])
2145                                              | ~(0x0ff00))));
2146               emit_insn (gen_addsi3 (reg2 = gen_reg_rtx (SImode), reg,
2147                                      GEN_INT (-((~INTVAL (operands[1]))
2148                                                 & 0xff))));
2149             }
2150           else
2151             {
2152               emit_insn (gen_movsi (reg = gen_reg_rtx (SImode),
2153                                     GEN_INT (INTVAL (operands[1]) & 0xff00)));
2154               emit_insn (gen_addsi3 (reg2 = gen_reg_rtx (SImode), reg,
2155                                      GEN_INT (INTVAL (operands[1]) & 0x00ff)));
2156             }
2157           insn = gen_rtx (SET, HImode, operands[0],
2158                           gen_rtx (SUBREG, HImode, reg2, 0));
2159         }
2160       else
2161         insn = gen_rtx (SET, VOIDmode, operands[0], operands[1]);
2162     }
2164   emit_insn (insn);
2165   DONE;
2168 ;; Pattern to recognise insn generated default case above
2170 (define_insn ""
2171   [(set (match_operand:HI 0 "general_operand" "=r,r,r,m")
2172         (match_operand:HI 1 "general_operand"  "r,K,m,r"))]
2173   "(register_operand (operands[0], HImode)
2174     && (GET_CODE (operands[1]) != CONST_INT
2175         || const_ok_for_arm (INTVAL (operands[1]))
2176         || const_ok_for_arm (~INTVAL (operands[1]))))
2177    || register_operand (operands[1], HImode)"
2178   "*
2179   switch (which_alternative)
2180     {
2181       case 1:
2182         if (!const_ok_for_arm (INTVAL (operands[1])))
2183           {
2184             operands[1] = GEN_INT (~INTVAL (operands[1]));
2185             output_asm_insn (\"mvn%?\\t%0, %1\", operands);
2186             return \"\";
2187           }
2188         /* fall through */
2189       case 0:
2190         return \"mov%?\\t%0, %1\\t%@ movhi\";
2191       case 2:
2192         return \"ldr%?\\t%0, %1\\t%@ movhi\";
2193       case 3:
2194         return \"str%?\\t%1, %0\\t%@ movhi\";
2195     }
2197 [(set_attr "type" "*,*,load,store1")])
2199 (define_expand "reload_outhi"
2200   [(parallel [(match_operand:HI 0 "reload_memory_operand" "=o")
2201               (match_operand:HI 1 "s_register_operand" "r")
2202               (match_operand:SI 2 "s_register_operand" "=&r")])]
2203   ""
2204   "
2205   arm_reload_out_hi (operands);
2206   DONE;
2209 (define_expand "movqi"
2210   [(set (match_operand:QI 0 "general_operand" "")
2211         (match_operand:QI 1 "general_operand" ""))]
2212   ""
2213   "
2214   /* Everything except mem = const or mem = mem can be done easily */
2216   if (!(reload_in_progress || reload_completed))
2217     {
2218       rtx reg;
2219       if (GET_CODE (operands[1]) == CONST_INT)
2220         {
2221           emit_insn (gen_movsi (reg = gen_reg_rtx (SImode), operands[1]));
2222           operands[1] = gen_rtx (SUBREG, QImode, reg, 0);
2223         }
2224     }
2225   if (GET_CODE (operands[0]) == MEM)
2226     operands[1] = force_reg (QImode, operands[1]);
2230 (define_insn ""
2231   [(set (match_operand:QI 0 "general_operand" "=r,r,r,m")
2232         (match_operand:QI 1 "general_operand" "r,K,m,r"))]
2233   "register_operand (operands[0], QImode)
2234    || register_operand (operands[1], QImode)"
2235   "*
2236   switch (which_alternative)
2237     {
2238     case 1:
2239       if (INTVAL (operands[1]) < 0)
2240         {
2241           operands[1] = GEN_INT (~INTVAL (operands[1]));
2242           output_asm_insn (\"mvn%?\\t%0, %1\", operands);
2243           return \"\";
2244         }
2245     case 0:
2246       return \"mov%?\\t%0, %1\";
2247     case 2:
2248       return \"ldr%?b\\t%0, %1\";
2249     case 3:
2250       return \"str%?b\\t%1, %0\";
2251     }
2253 [(set_attr "type" "*,*,load,store1")])
2255 (define_insn "movsf"
2256   [(set (match_operand:SF 0 "general_operand" "=f,f,f,m,f,r,r,r,m")
2257         (match_operand:SF 1 "general_operand" "fG,H,m,f,r,f,r,m,r"))]
2258   ""
2259   "*
2261   REAL_VALUE_TYPE r;
2263   switch (which_alternative)
2264     {
2265     case 0:
2266       return \"mvf%?s\\t%0, %1\";
2267     case 1:
2268       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2269       r = REAL_VALUE_NEGATE (r);
2270       operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
2271       output_asm_insn (\"mnf%?s\\t%0, %1\", operands);
2272       return \"\";
2273     case 2:
2274       return \"ldf%?s\\t%0, %1\";
2275     case 3:
2276       return \"stf%?s\\t%1, %0\";
2277     case 4:
2278       return \"str%?\\t%1, [sp, #-4]!\;ldf%?s\\t%0, [sp], #4\";
2279     case 5:
2280       return \"stf%?s\\t%1, [sp, #-4]!\;ldr%?\\t%0, [sp], #4\";
2281     case 6:
2282       return \"mov%?\\t%0, %1\";
2283     case 7:
2284       return \"ldr%?\\t%0, %1\\t%@ float\";
2285     case 8:
2286       return \"str%?\\t%1, %0\\t%@ float\";
2287   }
2290 [(set_attr "length" "4,4,4,4,8,8,4,4,4")
2291  (set_attr "type" "float,float,f_load,f_store,r_mem_f,f_mem_r,*,load,store1")])
2293 (define_expand "movdf"
2294   [(parallel [(set (match_operand:DF 0 "general_operand" "")
2295                    (match_operand:DF 1 "general_operand" ""))
2296               (clobber (match_scratch:SI 2 ""))])]
2297   ""
2298   "
2299   if (GET_CODE (operands[0]) == MEM)
2300     operands[1] = force_reg (DFmode, operands[1]);
2303 ;; Reloading a df mode value stored in integer regs to memory can require a
2304 ;; scratch reg.
2305 (define_expand "reload_outdf"
2306   [(parallel [(set (match_operand:DF 0 "reload_memory_operand" "=o")
2307                    (match_operand:DF 1 "s_register_operand" "r"))
2308               (clobber (match_operand:SI 2 "s_register_operand" "=&r"))])]
2309   ""
2310   "")
2312 (define_insn ""
2313   [(set (match_operand:DF 0 "general_operand" "=r,Q,r,o,f,f,f,f,m,!f,!r,r")
2314         (match_operand:DF 1 "general_operand" 
2315                 "Q,r,?o,?r,?f,!G,!H,m,f,r,f,??r"))
2316    (clobber (match_scratch:SI 2 "=X,X,X,&r,X,X,X,X,X,X,X,X"))]
2317   "GET_CODE (operands[0]) != MEM || register_operand (operands[1], DFmode)"
2318   "*
2320   REAL_VALUE_TYPE r;
2321   rtx ops[3];
2323   switch (which_alternative)
2324     {
2325     case 0:
2326       return \"ldm%?ia\\t%m1, {%0, %R0}\\t%@ double\";
2328     case 1:
2329       return \"stm%?ia\\t%m0, {%1, %R1}\\t%@ double\";
2331     case 2:
2332       ops[0] = operands[0];
2333       ops[1] = XEXP (XEXP (operands[1], 0), 0);
2334       ops[2] = XEXP (XEXP (operands[1], 0), 1);
2335       if (!INTVAL (ops[2]) || const_ok_for_arm (INTVAL (ops[2])))
2336         output_asm_insn (\"add%?\\t%0, %1, %2\", ops);
2337       else
2338         output_asm_insn (\"sub%?\\t%0, %1, #%n2\", ops);
2339       return \"ldm%?ia\\t%0, {%0, %R0}\\t%@ double\";
2341     case 3:
2342       ops[0] = operands[2];
2343       ops[1] = XEXP (XEXP (operands[0], 0), 0);
2344       ops[2] = XEXP (XEXP (operands[0], 0), 1);
2345       if (!INTVAL (ops[2]) || const_ok_for_arm (INTVAL (ops[2])))
2346         output_asm_insn (\"add%?\\t%0, %1, %2\", ops);
2347       else
2348         output_asm_insn (\"sub%?\\t%0, %1, #%n2\", ops);
2349       return \"stm%?ia\\t%2, {%1, %R1}\\t%@ double\";
2351     case 4:
2352     case 5:
2353       return \"mvf%?d\\t%0, %1\";
2355     case 6:
2356       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2357       r = REAL_VALUE_NEGATE (r);
2358       operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
2359       output_asm_insn (\"mnf%?d\\t%0, %1\", operands);
2360       return \"\";
2362     case 7: return \"ldf%?d\\t%0, %1\";
2363     case 8: return \"stf%?d\\t%1, %0\";
2364     case 9: return output_mov_double_fpu_from_arm (operands);
2365     case 10: return output_mov_double_arm_from_fpu (operands);
2366     case 11: return output_move_double (operands);
2367     }
2370 [(set_attr "length" "4,4,8,8,4,4,4,4,4,8,8,8")
2371  (set_attr "type" 
2372 "load,store2,load,store2,float,float,float,f_load,f_store,r_mem_f,f_mem_r,*")])
2374 (define_insn "movxf"
2375   [(set (match_operand:XF 0 "general_operand" "=f,f,f,m,f,r,r")
2376         (match_operand:XF 1 "general_operand" "fG,H,m,f,r,f,r"))]
2377   "ENABLE_XF_PATTERNS"
2378   "*
2380   REAL_VALUE_TYPE r;
2382   switch (which_alternative)
2383     {
2384     case 0: return \"mvf%?e\\t%0, %1\";
2385     case 1:
2386       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2387       r = REAL_VALUE_NEGATE (r);
2388       operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
2389       output_asm_insn (\"mnf%?e\\t%0, %1\", operands);
2390       return \"\";
2392     case 2: return \"ldf%?e\\t%0, %1\";
2393     case 3: return \"stf%?e\\t%1, %0\";
2394     case 4: return output_mov_long_double_fpu_from_arm (operands);
2395     case 5: return output_mov_long_double_arm_from_fpu (operands);
2396     case 6: return output_mov_long_double_arm_from_arm (operands);
2397     }
2400 [(set_attr "length" "4,4,4,4,8,8,12")
2401  (set_attr "type" "float,float,f_load,f_store,r_mem_f,f_mem_r,*")])
2404 ;; load- and store-multiple insns
2405 ;; The arm can load/store any set of registers, provided that they are in
2406 ;; ascending order; but that is beyond GCC so stick with what it knows.
2408 (define_expand "load_multiple"
2409   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
2410                           (match_operand:SI 1 "" ""))
2411                      (use (match_operand:SI 2 "" ""))])]
2412   ""
2413   "
2414   /* Support only fixed point registers */
2415   if (GET_CODE (operands[2]) != CONST_INT
2416       || INTVAL (operands[2]) > 14
2417       || INTVAL (operands[2]) < 2
2418       || GET_CODE (operands[1]) != MEM
2419       || GET_CODE (operands[0]) != REG
2420       || REGNO (operands[0]) > 14
2421       || REGNO (operands[0]) + INTVAL (operands[2]) > 15)
2422     FAIL;
2424   operands[3]
2425             = arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]),
2426                                      force_reg (SImode, XEXP (operands[1], 0)),
2427                                      TRUE, FALSE);
2430 ;; Load multiple with write-back
2432 (define_insn ""
2433   [(match_parallel 0 "load_multiple_operation"
2434                    [(set (match_operand:SI 1 "s_register_operand" "+r")
2435                          (plus:SI (match_dup 1)
2436                                   (match_operand:SI 2 "immediate_operand" "n")))
2437                     (set (match_operand:SI 3 "s_register_operand" "=r")
2438                          (mem:SI (match_dup 1)))])]
2439   "(INTVAL (operands[2])  == 4 * (XVECLEN (operands[0], 0) - 2))"
2440   "*
2442   rtx ops[3];
2443   int count = XVECLEN (operands[0], 0);
2445   ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
2446   ops[1] = SET_DEST (XVECEXP (operands[0], 0, 1));
2447   ops[2] = SET_DEST (XVECEXP (operands[0], 0, count - 2));
2449   output_asm_insn (\"ldm%?ia\\t%0!, {%1-%2}\\t%@ load multiple\", ops);
2450   return \"\";
2453 [(set_attr "type" "load")])
2455 ;; Ordinary load multiple
2457 (define_insn ""
2458   [(match_parallel 0 "load_multiple_operation"
2459                    [(set (match_operand:SI 1 "s_register_operand" "=r")
2460                          (match_operand:SI 2 "indirect_operand" "Q"))])]
2461   ""
2462   "*
2464   rtx ops[3];
2465   int count = XVECLEN (operands[0], 0);
2467   ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
2468   ops[1] = SET_DEST (XVECEXP (operands[0], 0, 0));
2469   ops[2] = SET_DEST (XVECEXP (operands[0], 0, count - 1));
2471   output_asm_insn (\"ldm%?ia\\t%0, {%1-%2}\\t%@ load multiple\", ops);
2472   return \"\";
2475 [(set_attr "type" "load")])
2477 (define_expand "store_multiple"
2478   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
2479                           (match_operand:SI 1 "" ""))
2480                      (use (match_operand:SI 2 "" ""))])]
2481   ""
2482   "
2483   /* Support only fixed point registers */
2484   if (GET_CODE (operands[2]) != CONST_INT
2485       || INTVAL (operands[2]) > 14
2486       || INTVAL (operands[2]) < 2
2487       || GET_CODE (operands[1]) != REG
2488       || GET_CODE (operands[0]) != MEM
2489       || REGNO (operands[1]) > 14
2490       || REGNO (operands[1]) + INTVAL (operands[2]) > 15)
2491     FAIL;
2493   operands[3]
2494            = arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]),
2495                                      force_reg (SImode, XEXP (operands[0], 0)),
2496                                      TRUE, FALSE);
2499 ;; Store multiple with write-back
2501 (define_insn ""
2502   [(match_parallel 0 "store_multiple_operation"
2503                    [(set (match_operand:SI 1 "s_register_operand" "+r")
2504                          (plus:SI (match_dup 1)
2505                                   (match_operand:SI 2 "immediate_operand" "n")))
2506                     (set (mem:SI (match_dup 1))
2507                          (match_operand:SI 3 "s_register_operand" "r"))])]
2508   "(INTVAL (operands[2]) == 4 * (XVECLEN (operands[0], 0) - 2))"
2509   "*
2511   rtx ops[3];
2512   int count = XVECLEN (operands[0], 0);
2514   ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
2515   ops[1] = SET_SRC (XVECEXP (operands[0], 0, 1));
2516   ops[2] = SET_SRC (XVECEXP (operands[0], 0, count - 2));
2518   output_asm_insn (\"stm%?ia\\t%0!, {%1-%2}\\t%@ str multiple\", ops);
2519   return \"\";
2522 [(set (attr "type")
2523       (cond [(eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 4))
2524                 (const_string "store2")
2525              (eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 5))
2526                 (const_string "store3")]
2527           (const_string "store4")))])
2529 ;; Ordinary store multiple
2531 (define_insn ""
2532   [(match_parallel 0 "store_multiple_operation"
2533                    [(set (match_operand:SI 2 "indirect_operand" "=Q")
2534                          (match_operand:SI 1 "s_register_operand" "r"))])]
2535   ""
2536   "*
2538   rtx ops[3];
2539   int count = XVECLEN (operands[0], 0);
2541   ops[0] = XEXP (SET_DEST (XVECEXP (operands[0], 0, 0)), 0);
2542   ops[1] = SET_SRC (XVECEXP (operands[0], 0, 0));
2543   ops[2] = SET_SRC (XVECEXP (operands[0], 0, count - 1));
2545   output_asm_insn (\"stm%?ia\\t%0, {%1-%2}\\t%@ str multiple\", ops);
2546   return \"\";
2549 [(set (attr "type")
2550       (cond [(eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 3))
2551                 (const_string "store2")
2552              (eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 4))
2553                 (const_string "store3")]
2554           (const_string "store4")))])
2556 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
2557 ;; We could let this apply for blocks of less than this, but it clobbers so
2558 ;; many registers that there is then probably a better way.
2560 ;; If optimizing, output redundant moves with REG_NOTES on them, this 
2561 ;; produces better code.
2563 (define_expand "movstrsi"
2564   [(set (match_operand:BLK 0 "general_operand" "=m")
2565         (match_operand:BLK 1 "general_operand" "m"))
2566    (use (match_operand:SI 2 "immediate_operand" "n"))
2567    (use (match_operand:SI 3 "immediate_operand" "n"))
2568    (clobber (reg:SI 0))
2569    (clobber (reg:SI 1))
2570    (clobber (reg:SI 2))
2571    (clobber (reg:SI 3))
2572    (clobber (match_scratch:SI 4 "=+r"))
2573    (clobber (match_scratch:SI 5 "=+r"))]
2574   ""
2575   "
2577   int words_to_go;
2578   int i, r;
2579   rtx const_sxteen = gen_rtx (CONST_INT, SImode, 16);
2580   rtx src = gen_reg_rtx (SImode);
2581   rtx dst = gen_reg_rtx (SImode);
2582   rtx st_src, st_dst, end_src, end_dst, fin_src, fin_dst;
2583   extern int optimize;
2585   if (GET_CODE (operands[2]) != CONST_INT
2586       || GET_CODE (operands[3]) != CONST_INT
2587       || INTVAL (operands[2]) % 4 != 0
2588       || INTVAL (operands[2]) < 4
2589       || INTVAL (operands[2]) > 64
2590       || INTVAL (operands[3]) < 4
2591       || INTVAL (operands[3]) % 4 != 0)
2592     FAIL;
2593   emit_move_insn (dst, st_dst = force_reg (SImode, XEXP (operands[0], 0)));
2594   emit_move_insn (src, st_src = force_reg (SImode, XEXP (operands[1], 0)));
2595   fin_src = src;
2596   fin_dst = dst;
2598   for (i = 0, words_to_go = INTVAL (operands[2]) / 4; words_to_go >= 2; i+=4)
2599     {
2600       emit_insn (arm_gen_load_multiple (0, words_to_go > 4 ? 4 : words_to_go,
2601                                         src, TRUE, TRUE));
2602       emit_insn (arm_gen_store_multiple (0, words_to_go > 4 ? 4 : words_to_go,
2603                                         dst, TRUE, TRUE));
2604       if (optimize)
2605         for (r = (words_to_go > 4) ? 3 : words_to_go - 1; r >= 0; r--)
2606           {
2607             rtx note;
2608             note = emit_move_insn (gen_reg_rtx (SImode),
2609                                    gen_rtx (REG, SImode, r));
2610             REG_NOTES (note) = gen_rtx (EXPR_LIST, REG_EQUIV,
2611                                         gen_rtx (MEM, SImode,
2612                                               plus_constant (st_src, 4*(i+r))),
2613                                         REG_NOTES (note));
2614             REG_NOTES (note) = gen_rtx (EXPR_LIST, REG_EQUIV,
2615                                         gen_rtx (MEM, SImode,
2616                                               plus_constant (st_dst, 4*(i+r))),
2617                                         REG_NOTES (note));
2618           }
2619       words_to_go -= words_to_go < 4 ? words_to_go : 4;
2620     }
2621   if (words_to_go)
2622   {
2623     rtx sreg;
2625     emit_move_insn (sreg = gen_reg_rtx (SImode), gen_rtx (MEM, SImode, src));
2626     emit_move_insn (fin_src = gen_reg_rtx (SImode), plus_constant (src, 4));
2627     emit_move_insn (gen_rtx (MEM, SImode, dst), sreg);
2628     emit_move_insn (fin_dst = gen_reg_rtx (SImode), plus_constant (dst, 4));
2629   }
2630   if (optimize)
2631     {
2632       /* Insns for the REG_NOTES: These notes tell the optimiser where the
2633          index registers have got to so that consecutive block moves of
2634          contiguous data work efficiently */
2636       end_src = emit_move_insn (fin_src, fin_src);
2637       REG_NOTES (end_src) = gen_rtx(EXPR_LIST, REG_EQUAL,
2638                                   plus_constant (st_src, INTVAL (operands[2])),
2639                                   REG_NOTES (end_src));
2640       end_dst = emit_move_insn (fin_dst, fin_dst);
2641       REG_NOTES (end_dst) = gen_rtx(EXPR_LIST, REG_EQUAL,
2642                                   plus_constant (st_dst, INTVAL (operands[2])),
2643                                   REG_NOTES (end_dst));
2644     }
2645   DONE;
2650 ;; Comparison and test insns
2652 (define_expand "cmpsi"
2653   [(set (reg:CC 24)
2654         (compare:CC (match_operand:SI 0 "s_register_operand" "")
2655                     (match_operand:SI 1 "arm_add_operand" "")))]
2656   ""
2657   "
2659   arm_compare_op0 = operands[0];
2660   arm_compare_op1 = operands[1];
2661   arm_compare_fp = 0;
2662   DONE;
2666 (define_expand "cmpsf"
2667   [(set (reg:CC 24)
2668         (compare:CC (match_operand:SF 0 "s_register_operand" "")
2669                     (match_operand:SF 1 "fpu_rhs_operand" "")))]
2670   ""
2671   "
2673   arm_compare_op0 = operands[0];
2674   arm_compare_op1 = operands[1];
2675   arm_compare_fp = 1;
2676   DONE;
2680 (define_expand "cmpdf"
2681   [(set (reg:CC 24)
2682         (compare:CC (match_operand:DF 0 "s_register_operand" "")
2683                     (match_operand:DF 1 "fpu_rhs_operand" "")))]
2684   ""
2685   "
2687   arm_compare_op0 = operands[0];
2688   arm_compare_op1 = operands[1];
2689   arm_compare_fp = 1;
2690   DONE;
2694 (define_expand "cmpxf"
2695   [(set (reg:CC 24)
2696         (compare:CC (match_operand:XF 0 "s_register_operand" "")
2697                     (match_operand:XF 1 "fpu_rhs_operand" "")))]
2698   "ENABLE_XF_PATTERNS"
2699   "
2701   arm_compare_op0 = operands[0];
2702   arm_compare_op1 = operands[1];
2703   arm_compare_fp = 1;
2704   DONE;
2708 (define_insn ""
2709   [(set (match_operand 0 "cc_register" "")
2710         (compare (match_operand:SI 1 "s_register_operand" "r")
2711                  (match_operand:SI 2 "arm_add_operand" "rL")))]
2712   ""
2713   "*
2714   if (GET_CODE (operands[2]) == CONST_INT
2715       && !const_ok_for_arm (INTVAL (operands[2])))
2716     return \"cmn%?\\t%1, #%n2\";
2717   return \"cmp%?\\t%1, %2\";
2719 [(set_attr "conds" "set")])
2721 (define_insn ""
2722   [(set (match_operand 0 "cc_register" "")
2723         (compare (match_operand:SI 1 "s_register_operand" "r")
2724                  (neg:SI (match_operand:SI 2 "s_register_operand" "r"))))]
2725   ""
2726   "cmn%?\\t%1, %2"
2727 [(set_attr "conds" "set")])
2729 (define_insn ""
2730   [(set (match_operand 0 "cc_register" "")
2731         (compare (match_operand:SI 1 "s_register_operand" "r")
2732                  (match_operator:SI 2 "shift_operator"
2733                   [(match_operand:SI 3 "s_register_operand" "r")
2734                    (match_operand:SI 4 "arm_rhs_operand" "rn")])))]
2735   ""
2736   "cmp%?\\t%1, %3, %S2"
2737 [(set_attr "conds" "set")])
2739 (define_insn ""
2740   [(set (match_operand 0 "cc_register" "")
2741         (compare (match_operand:SI 1 "s_register_operand" "r")
2742                  (neg:SI (match_operator:SI 2 "shift_operator"
2743                           [(match_operand:SI 3 "s_register_operand" "r")
2744                            (match_operand:SI 4 "arm_rhs_operand" "rn")]))))]
2745   ""
2746   "cmn%?\\t%1, %3, %S2"
2747 [(set_attr "conds" "set")])
2749 (define_insn ""
2750   [(set (reg:CCFP 24)
2751         (compare:CCFP (match_operand:SF 0 "s_register_operand" "f,f")
2752                       (match_operand:SF 1 "fpu_add_operand" "fG,H")))]
2753   ""
2754   "*
2756   REAL_VALUE_TYPE r;
2758   switch (which_alternative)
2759     {
2760     case 0:
2761       return \"cmf%?\\t%0, %1\";
2762     case 1:
2763       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2764       r = REAL_VALUE_NEGATE (r);
2765       operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
2766       output_asm_insn (\"cnf%?\\t%0, %1\", operands);
2767       return \"\";
2768     }
2771 [(set_attr "conds" "set")
2772  (set_attr "type" "f_2_r")])
2774 (define_insn ""
2775   [(set (reg:CCFP 24)
2776         (compare:CCFP (match_operand:DF 0 "s_register_operand" "f,f")
2777                       (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
2778   ""
2779   "*
2781   REAL_VALUE_TYPE r;
2783   switch (which_alternative)
2784     {
2785     case 0:
2786       return \"cmf%?\\t%0, %1\";
2787     case 1:
2788       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2789       r = REAL_VALUE_NEGATE (r);
2790       operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
2791       output_asm_insn (\"cnf%?\\t%0, %1\", operands);
2792       return \"\";
2793     }
2796 [(set_attr "conds" "set")
2797  (set_attr "type" "f_2_r")])
2799 (define_insn ""
2800   [(set (reg:CCFP 24)
2801         (compare:CCFP (float_extend:DF
2802                        (match_operand:SF 0 "s_register_operand" "f,f"))
2803                       (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
2804   ""
2805   "*
2807   REAL_VALUE_TYPE r;
2809   switch (which_alternative)
2810     {
2811     case 0:
2812       return \"cmf%?\\t%0, %1\";
2813     case 1:
2814       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2815       r = REAL_VALUE_NEGATE (r);
2816       operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
2817       output_asm_insn (\"cnf%?\\t%0, %1\", operands);
2818       return \"\";
2819     }
2822 [(set_attr "conds" "set")
2823  (set_attr "type" "f_2_r")])
2825 (define_insn ""
2826   [(set (reg:CCFP 24)
2827         (compare:CCFP (match_operand:DF 0 "s_register_operand" "f")
2828                       (float_extend:DF
2829                        (match_operand:SF 1 "s_register_operand" "f"))))]
2830   ""
2831   "cmf%?\\t%0, %1"
2832 [(set_attr "conds" "set")
2833  (set_attr "type" "f_2_r")])
2835 (define_insn ""
2836   [(set (reg:CCFP 24)
2837         (compare:CCFP (match_operand:XF 0 "s_register_operand" "f,f")
2838                       (match_operand:XF 1 "fpu_add_operand" "fG,H")))]
2839   "ENABLE_XF_PATTERNS"
2840   "*
2842   REAL_VALUE_TYPE r;
2844   switch (which_alternative)
2845     {
2846     case 0:
2847       return \"cmf%?\\t%0, %1\";
2848     case 1:
2849       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2850       r = REAL_VALUE_NEGATE (r);
2851       operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
2852       output_asm_insn (\"cnf%?\\t%0, %1\", operands);
2853       return \"\";
2854     }
2857 [(set_attr "conds" "set")
2858  (set_attr "type" "f_2_r")])
2860 (define_insn ""
2861   [(set (reg:CCFPE 24)
2862         (compare:CCFPE (match_operand:SF 0 "s_register_operand" "f,f")
2863                        (match_operand:SF 1 "fpu_add_operand" "fG,H")))]
2864   ""
2865   "*
2867   REAL_VALUE_TYPE r;
2869   switch (which_alternative)
2870     {
2871     case 0:
2872       return \"cmf%?e\\t%0, %1\";
2873     case 1:
2874       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2875       r = REAL_VALUE_NEGATE (r);
2876       operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
2877       output_asm_insn (\"cnf%?e\\t%0, %1\", operands);
2878       return \"\";
2879     }
2882 [(set_attr "conds" "set")
2883  (set_attr "type" "f_2_r")])
2885 (define_insn ""
2886   [(set (reg:CCFPE 24)
2887         (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f,f")
2888                        (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
2889   ""
2890   "*
2892   REAL_VALUE_TYPE r;
2894   switch (which_alternative)
2895     {
2896     case 0:
2897       return \"cmf%?e\\t%0, %1\";
2898     case 1:
2899       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2900       r = REAL_VALUE_NEGATE (r);
2901       operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
2902       output_asm_insn (\"cnf%?e\\t%0, %1\", operands);
2903       return \"\";
2904     }
2907 [(set_attr "conds" "set")
2908  (set_attr "type" "f_2_r")])
2910 (define_insn ""
2911   [(set (reg:CCFPE 24)
2912         (compare:CCFPE (float_extend:DF
2913                         (match_operand:SF 0 "s_register_operand" "f,f"))
2914                        (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
2915   ""
2916   "*
2918   REAL_VALUE_TYPE r;
2920   switch (which_alternative)
2921     {
2922     case 0:
2923       return \"cmf%?e\\t%0, %1\";
2924     case 1:
2925       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2926       r = REAL_VALUE_NEGATE (r);
2927       operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
2928       output_asm_insn (\"cnf%?e\\t%0, %1\", operands);
2929       return \"\";
2930     }
2933 [(set_attr "conds" "set")
2934  (set_attr "type" "f_2_r")])
2936 (define_insn ""
2937   [(set (reg:CCFPE 24)
2938         (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f")
2939                        (float_extend:DF
2940                         (match_operand:SF 1 "s_register_operand" "f"))))]
2941   ""
2942   "cmf%?e\\t%0, %1"
2943 [(set_attr "conds" "set")
2944  (set_attr "type" "f_2_r")])
2946 (define_insn ""
2947   [(set (reg:CCFPE 24)
2948         (compare:CCFPE (match_operand:XF 0 "s_register_operand" "f,f")
2949                        (match_operand:XF 1 "fpu_add_operand" "fG,H")))]
2950   "ENABLE_XF_PATTERNS"
2951   "*
2953   REAL_VALUE_TYPE r;
2955   switch (which_alternative)
2956     {
2957     case 0:
2958       return \"cmf%?e\\t%0, %1\";
2959     case 1:
2960       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2961       r = REAL_VALUE_NEGATE (r);
2962       operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
2963       output_asm_insn (\"cnf%?e\\t%0, %1\", operands);
2964       return \"\";
2965     }
2968 [(set_attr "conds" "set")
2969  (set_attr "type" "f_2_r")])
2971 ; This insn allows redundant compares to be removed by cse, nothing should
2972 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
2973 ; is deleted later on. The match_dup will match the mode here, so that
2974 ; mode changes of the condition codes aren't lost by this even though we don't
2975 ; specify what they are.
2977 (define_insn ""
2978   [(set (match_operand 0 "cc_register" "") (match_dup 0))]
2979   ""
2980   "\\t%@ deleted compare"
2981 [(set_attr "conds" "set")
2982  (set_attr "length" "0")])
2985 ;; Conditional branch insns
2987 (define_expand "beq"
2988   [(set (pc)
2989         (if_then_else (eq (match_dup 1) (const_int 0))
2990                       (label_ref (match_operand 0 "" ""))
2991                       (pc)))]
2992   ""
2993   "
2995   operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1,
2996                                  arm_compare_fp);
3000 (define_expand "bne"
3001   [(set (pc)
3002         (if_then_else (ne (match_dup 1) (const_int 0))
3003                       (label_ref (match_operand 0 "" ""))
3004                       (pc)))]
3005   ""
3006   "
3008   operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1,
3009                                  arm_compare_fp);
3013 (define_expand "bgt"
3014   [(set (pc)
3015         (if_then_else (gt (match_dup 1) (const_int 0))
3016                       (label_ref (match_operand 0 "" ""))
3017                       (pc)))]
3018   ""
3019   "
3021   operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1,
3022                                  arm_compare_fp);
3026 (define_expand "ble"
3027   [(set (pc)
3028         (if_then_else (le (match_dup 1) (const_int 0))
3029                       (label_ref (match_operand 0 "" ""))
3030                       (pc)))]
3031   ""
3032   "
3034   operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1,
3035                                  arm_compare_fp);
3039 (define_expand "bge"
3040   [(set (pc)
3041         (if_then_else (ge (match_dup 1) (const_int 0))
3042                       (label_ref (match_operand 0 "" ""))
3043                       (pc)))]
3044   ""
3045   "
3047   operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1,
3048                                  arm_compare_fp);
3052 (define_expand "blt"
3053   [(set (pc)
3054         (if_then_else (lt (match_dup 1) (const_int 0))
3055                       (label_ref (match_operand 0 "" ""))
3056                       (pc)))]
3057   ""
3058   "
3060   operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1,
3061                                  arm_compare_fp);
3065 (define_expand "bgtu"
3066   [(set (pc)
3067         (if_then_else (gtu (match_dup 1) (const_int 0))
3068                       (label_ref (match_operand 0 "" ""))
3069                       (pc)))]
3070   ""
3071   "
3073   operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1,
3074                                  arm_compare_fp);
3078 (define_expand "bleu"
3079   [(set (pc)
3080         (if_then_else (leu (match_dup 1) (const_int 0))
3081                       (label_ref (match_operand 0 "" ""))
3082                       (pc)))]
3083   ""
3084   "
3086   operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1,
3087                                  arm_compare_fp);
3091 (define_expand "bgeu"
3092   [(set (pc)
3093         (if_then_else (geu (match_dup 1) (const_int 0))
3094                       (label_ref (match_operand 0 "" ""))
3095                       (pc)))]
3096   ""
3097   "
3099   operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1,
3100                                  arm_compare_fp);
3104 (define_expand "bltu"
3105   [(set (pc)
3106         (if_then_else (ltu (match_dup 1) (const_int 0))
3107                       (label_ref (match_operand 0 "" ""))
3108                       (pc)))]
3109   ""
3110   "
3112   operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1,
3113                                  arm_compare_fp);
3117 ;; patterns to match conditional branch insns
3119 (define_insn ""
3120   [(set (pc)
3121         (if_then_else (match_operator 1 "comparison_operator"
3122                                         [(reg 24) (const_int 0)])
3123                       (label_ref (match_operand 0 "" ""))
3124                       (pc)))]
3125   ""
3126   "*
3128   extern int arm_ccfsm_state;
3130   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3131   {
3132     arm_ccfsm_state += 2;
3133     return \"\";
3134   }
3135   return \"b%d1\\t%l0\";
3137 [(set_attr "conds" "use")])
3139 (define_insn ""
3140   [(set (pc)
3141         (if_then_else (match_operator 1 "comparison_operator"
3142                                         [(reg 24) (const_int 0)])
3143                       (pc)
3144                       (label_ref (match_operand 0 "" ""))))]
3145   ""
3146   "*
3148   extern int arm_ccfsm_state;
3150   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3151   {
3152     arm_ccfsm_state += 2;
3153     return \"\";
3154   }
3155   return \"b%D1\\t%l0\";
3157 [(set_attr "conds" "use")])
3160 ; scc insns
3162 (define_expand "seq"
3163   [(set (match_operand:SI 0 "s_register_operand" "=r")
3164         (eq:SI (match_dup 1) (const_int 0)))]
3165   ""
3166   "
3168   operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1,
3169                                  arm_compare_fp);
3173 (define_expand "sne"
3174   [(set (match_operand:SI 0 "s_register_operand" "=r")
3175         (ne:SI (match_dup 1) (const_int 0)))]
3176   ""
3177   "
3179   operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1,
3180                                  arm_compare_fp);
3184 (define_expand "sgt"
3185   [(set (match_operand:SI 0 "s_register_operand" "=r")
3186         (gt:SI (match_dup 1) (const_int 0)))]
3187   ""
3188   "
3190   operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1,
3191                                  arm_compare_fp);
3195 (define_expand "sle"
3196   [(set (match_operand:SI 0 "s_register_operand" "=r")
3197         (le:SI (match_dup 1) (const_int 0)))]
3198   ""
3199   "
3201   operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1,
3202                                  arm_compare_fp);
3206 (define_expand "sge"
3207   [(set (match_operand:SI 0 "s_register_operand" "=r")
3208         (ge:SI (match_dup 1) (const_int 0)))]
3209   ""
3210   "
3212   operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1,
3213                                  arm_compare_fp);
3217 (define_expand "slt"
3218   [(set (match_operand:SI 0 "s_register_operand" "=r")
3219         (lt:SI (match_dup 1) (const_int 0)))]
3220   ""
3221   "
3223   operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1,
3224                                  arm_compare_fp);
3228 (define_expand "sgtu"
3229   [(set (match_operand:SI 0 "s_register_operand" "=r")
3230         (gtu:SI (match_dup 1) (const_int 0)))]
3231   ""
3232   "
3234   operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1,
3235                                  arm_compare_fp);
3239 (define_expand "sleu"
3240   [(set (match_operand:SI 0 "s_register_operand" "=r")
3241         (leu:SI (match_dup 1) (const_int 0)))]
3242   ""
3243   "
3245   operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1,
3246                                  arm_compare_fp);
3250 (define_expand "sgeu"
3251   [(set (match_operand:SI 0 "s_register_operand" "=r")
3252         (geu:SI (match_dup 1) (const_int 0)))]
3253   ""
3254   "
3256   operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1,
3257                                  arm_compare_fp);
3261 (define_expand "sltu"
3262   [(set (match_operand:SI 0 "s_register_operand" "=r")
3263         (ltu:SI (match_dup 1) (const_int 0)))]
3264   ""
3265   "
3267   operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1,
3268                                  arm_compare_fp);
3272 (define_insn ""
3273   [(set (match_operand:SI 0 "s_register_operand" "=r")
3274         (match_operator:SI 1 "comparison_operator" [(reg 24) (const_int 0)]))]
3275   ""
3276   "mov%d1\\t%0, #1\;mov%D1\\t%0, #0"
3277 [(set_attr "conds" "use")
3278  (set_attr "length" "8")])
3280 (define_insn ""
3281   [(set (match_operand:SI 0 "s_register_operand" "=r")
3282         (neg:SI (match_operator:SI 1 "comparison_operator"
3283                  [(reg 24) (const_int 0)])))]
3284   ""
3285   "mvn%d1\\t%0, #0\;mov%D1\\t%0, #0"
3286 [(set_attr "conds" "use")
3287  (set_attr "length" "8")])
3289 (define_insn ""
3290   [(set (match_operand:SI 0 "s_register_operand" "=r")
3291         (not:SI (match_operator:SI 1 "comparison_operator"
3292                  [(reg 24) (const_int 0)])))]
3293   ""
3294   "mvn%d1\\t%0, #1\;mov%D1\\t%0, #0"
3295 [(set_attr "conds" "use")
3296  (set_attr "length" "8")])
3299 ;; Jump and linkage insns
3301 (define_insn "jump"
3302   [(set (pc)
3303         (label_ref (match_operand 0 "" "")))]
3304   ""
3305   "*
3307   extern int arm_ccfsm_state;
3309   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3310   {
3311     arm_ccfsm_state += 2;
3312     return \"\";
3313   }
3314   return \"b%?\\t%l0\";
3317 (define_expand "call"
3318   [(parallel [(call (match_operand 0 "memory_operand" "")
3319                     (match_operand 1 "general_operand" ""))
3320               (clobber (reg:SI 14))])]
3321   ""
3322   "")
3324 (define_insn ""
3325   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
3326          (match_operand 1 "" "g"))
3327    (clobber (reg:SI 14))]
3328   ""
3329   "*
3330   return (output_call (operands));
3332 [(set (attr "conds")
3333       (if_then_else (eq_attr "cpu" "arm6")
3334                     (const_string "clob")
3335                     (const_string "nocond")))
3336 ;; length is worst case, normally it is only two
3337  (set_attr "length" "12")
3338  (set_attr "type" "call")])
3340 (define_insn ""
3341   [(call (mem:SI (match_operand 0 "memory_operand" "m"))
3342          (match_operand 1 "general_operand" "g"))
3343    (clobber (reg:SI 14))]
3344   ""
3345   "*
3346   return (output_call_mem (operands));
3348 [(set (attr "conds")
3349       (if_then_else (eq_attr "cpu" "arm6")
3350                     (const_string "clob")
3351                     (const_string "nocond")))
3352  (set_attr "length" "12")
3353  (set_attr "type" "call")])
3355 (define_expand "call_value"
3356   [(parallel [(set (match_operand 0 "" "=rf")
3357                    (call (match_operand 1 "memory_operand" "m")
3358                          (match_operand 2 "general_operand" "g")))
3359               (clobber (reg:SI 14))])]
3360   ""
3361   "")
3363 (define_insn ""
3364   [(set (match_operand 0 "" "=rf")
3365         (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
3366               (match_operand 2 "general_operand" "g")))
3367    (clobber (reg:SI 14))]
3368   ""
3369   "*
3370   return (output_call (&operands[1]));
3372 [(set (attr "conds")
3373       (if_then_else (eq_attr "cpu" "arm6")
3374                     (const_string "clob")
3375                     (const_string "nocond")))
3376  (set_attr "length" "12")
3377  (set_attr "type" "call")])
3379 (define_insn ""
3380   [(set (match_operand 0 "" "=rf")
3381         (call (mem:SI (match_operand 1 "memory_operand" "m"))
3382         (match_operand 2 "general_operand" "g")))
3383    (clobber (reg:SI 14))]
3384   "! CONSTANT_ADDRESS_P (XEXP (operands[1], 0))"
3385   "*
3386   return (output_call_mem (&operands[1]));
3388 [(set (attr "conds")
3389       (if_then_else (eq_attr "cpu" "arm6")
3390                     (const_string "clob")
3391                     (const_string "nocond")))
3392  (set_attr "length" "12")
3393  (set_attr "type" "call")])
3395 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
3396 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
3398 (define_insn ""
3399   [(call (mem:SI (match_operand:SI 0 "" "i"))
3400          (match_operand:SI 1 "general_operand" "g"))
3401    (clobber (reg:SI 14))]
3402   "GET_CODE (operands[0]) == SYMBOL_REF"
3403   "bl%?\\t%a0"
3404 [(set (attr "conds")
3405       (if_then_else (eq_attr "cpu" "arm6")
3406                     (const_string "clob")
3407                     (const_string "nocond")))
3408  (set_attr "type" "call")])
3410 (define_insn ""
3411   [(set (match_operand 0 "s_register_operand" "=rf")
3412         (call (mem:SI (match_operand:SI 1 "" "i"))
3413         (match_operand:SI 2 "general_operand" "g")))
3414    (clobber (reg:SI 14))]
3415   "GET_CODE(operands[1]) == SYMBOL_REF"
3416   "bl%?\\t%a1"
3417 [(set (attr "conds")
3418       (if_then_else (eq_attr "cpu" "arm6")
3419                     (const_string "clob")
3420                     (const_string "nocond")))
3421  (set_attr "type" "call")])
3423 ;; Often the return insn will be the same as loading from memory, so set attr
3424 (define_insn "return"
3425   [(return)]
3426   "USE_RETURN_INSN"
3427   "*
3429   extern int arm_ccfsm_state;
3431   if (arm_ccfsm_state == 2)
3432   {
3433     arm_ccfsm_state += 2;
3434     return \"\";
3435   }
3436   return output_return_instruction (NULL, TRUE);
3438 [(set_attr "type" "load")])
3440 (define_insn ""
3441   [(set (pc)
3442         (if_then_else (match_operator 0 "comparison_operator"
3443                        [(reg 24) (const_int 0)])
3444                       (return)
3445                       (pc)))]
3446   "USE_RETURN_INSN"
3447   "*
3449   extern int arm_ccfsm_state;
3451   if (arm_ccfsm_state == 2)
3452   {
3453     arm_ccfsm_state += 2;
3454     return \"\";
3455   }
3456   return output_return_instruction (operands[0], TRUE);
3458 [(set_attr "conds" "use")
3459  (set_attr "type" "load")])
3461 (define_insn ""
3462   [(set (pc)
3463         (if_then_else (match_operator 0 "comparison_operator"
3464                        [(reg 24) (const_int 0)])
3465                       (pc)
3466                       (return)))]
3467   "USE_RETURN_INSN"
3468   "*
3470   extern int arm_ccfsm_state;
3472   if (arm_ccfsm_state == 2)
3473   {
3474     arm_ccfsm_state += 2;
3475     return \"\";
3476   }
3477   return output_return_instruction 
3478         (gen_rtx (reverse_condition (GET_CODE (operands[0])),
3479                   GET_MODE (operands[0]), XEXP (operands[0], 0),
3480                   XEXP (operands[0], 1)),
3481          TRUE);
3483 [(set_attr "conds" "use")
3484  (set_attr "type" "load")])
3486 ;; Call subroutine returning any type.
3488 (define_expand "untyped_call"
3489   [(parallel [(call (match_operand 0 "" "")
3490                     (const_int 0))
3491               (match_operand 1 "" "")
3492               (match_operand 2 "" "")])]
3493   ""
3494   "
3496   int i;
3498   emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
3500   for (i = 0; i < XVECLEN (operands[2], 0); i++)
3501     {
3502       rtx set = XVECEXP (operands[2], 0, i);
3503       emit_move_insn (SET_DEST (set), SET_SRC (set));
3504     }
3506   /* The optimizer does not know that the call sets the function value
3507      registers we stored in the result block.  We avoid problems by
3508      claiming that all hard registers are used and clobbered at this
3509      point.  */
3510   emit_insn (gen_blockage ());
3512   DONE;
3515 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
3516 ;; all of memory.  This blocks insns from being moved across this point.
3518 (define_insn "blockage"
3519   [(unspec_volatile [(const_int 0)] 0)]
3520   ""
3521   ""
3522 [(set_attr "length" "0")
3523  (set_attr "type" "block")])
3525 (define_insn "tablejump"
3526   [(set (pc)
3527         (match_operand:SI 0 "s_register_operand" "r"))
3528    (use (label_ref (match_operand 1 "" "")))]
3529   ""
3530   "mov%?\\tpc, %0\\t%@ table jump, label %l1")
3532 (define_insn ""
3533   [(set (pc)
3534         (match_operand:SI 0 "memory_operand" "m"))
3535    (use (label_ref (match_operand 1 "" "")))]
3536   ""
3537   "ldr%?\\tpc, %0\\t%@ table jump, label %l1"
3538 [(set_attr "type" "load")])
3540 (define_insn "indirect_jump"
3541   [(set (pc)
3542         (match_operand:SI 0 "s_register_operand" "r"))]
3543   ""
3544   "mov%?\\tpc, %0\\t%@ indirect jump")
3546 (define_insn ""
3547   [(set (pc)
3548         (match_operand:SI 0 "memory_operand" "m"))]
3549   ""
3550   "ldr%?\\tpc, %0\\t%@ indirect jump"
3551 [(set_attr "type" "load")])
3553 ;; Misc insns
3555 (define_insn "nop"
3556   [(const_int 0)]
3557   ""
3558   "mov%?\\tr0, r0\\t%@ nop")
3560 ;; Patterns to allow combination of arithmetic, cond code and shifts
3562 (define_insn ""
3563   [(set (match_operand:SI 0 "s_register_operand" "=r")
3564         (match_operator:SI 1 "shiftable_operator"
3565           [(match_operator:SI 3 "shift_operator"
3566              [(match_operand:SI 4 "s_register_operand" "r")
3567               (match_operand:SI 5 "nonmemory_operand" "rI")])
3568            (match_operand:SI 2 "s_register_operand" "r")]))]
3569   ""
3570   "%i1%?\\t%0, %2, %4, %S3")
3572 (define_insn ""
3573   [(set (reg:CC_NOOV 24)
3574         (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
3575                           [(match_operator:SI 3 "shift_operator"
3576                             [(match_operand:SI 4 "s_register_operand" "r")
3577                              (match_operand:SI 5 "nonmemory_operand" "rI")])
3578                            (match_operand:SI 2 "s_register_operand" "r")])
3579                          (const_int 0)))
3580    (set (match_operand:SI 0 "s_register_operand" "=r")
3581         (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
3582                          (match_dup 2)]))]
3583   ""
3584   "%i1%?s\\t%0, %2, %4, %S3"
3585 [(set_attr "conds" "set")])
3587 (define_insn ""
3588   [(set (reg:CC_NOOV 24)
3589         (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
3590                           [(match_operator:SI 3 "shift_operator"
3591                             [(match_operand:SI 4 "s_register_operand" "r")
3592                              (match_operand:SI 5 "nonmemory_operand" "rI")])
3593                            (match_operand:SI 2 "s_register_operand" "r")])
3594                          (const_int 0)))
3595    (clobber (match_scratch:SI 0 "=r"))]
3596   ""
3597   "%i1%?s\\t%0, %2, %4, %S3"
3598 [(set_attr "conds" "set")])
3600 (define_insn ""
3601   [(set (match_operand:SI 0 "s_register_operand" "=r")
3602         (minus:SI (match_operand:SI 1 "s_register_operand" "r")
3603                   (match_operator:SI 2 "shift_operator"
3604                    [(match_operand:SI 3 "s_register_operand" "r")
3605                     (match_operand:SI 4 "nonmemory_operand" "rn")])))]
3606   ""
3607   "sub%?\\t%0, %1, %3, %S2")
3609 (define_insn ""
3610   [(set (reg:CC_NOOV 24)
3611         (compare:CC_NOOV
3612          (minus:SI (match_operand:SI 1 "s_register_operand" "r")
3613                    (match_operator:SI 2 "shift_operator"
3614                     [(match_operand:SI 3 "s_register_operand" "r")
3615                      (match_operand:SI 4 "nonmemory_operand" "rn")]))
3616          (const_int 0)))
3617    (set (match_operand:SI 0 "s_register_operand" "=r")
3618         (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
3619                                                  (match_dup 4)])))]
3620   ""
3621   "sub%?s\\t%0, %1, %3, %S2"
3622 [(set_attr "conds" "set")])
3624 (define_insn ""
3625   [(set (reg:CC_NOOV 24)
3626         (compare:CC_NOOV
3627          (minus:SI (match_operand:SI 1 "s_register_operand" "r")
3628                    (match_operator:SI 2 "shift_operator"
3629                     [(match_operand:SI 3 "s_register_operand" "r")
3630                      (match_operand:SI 4 "nonmemory_operand" "rn")]))
3631          (const_int 0)))
3632    (clobber (match_scratch:SI 0 "=r"))]
3633   ""
3634   "sub%?s\\t%0, %1, %3, %S2"
3635 [(set_attr "conds" "set")])
3637 ;; These variants of the above insns can occur if the first operand is the
3638 ;; frame pointer and we eliminate that.  This is a kludge, but there doesn't
3639 ;; seem to be a way around it.  Most of the predicates have to be null
3640 ;; because the format can be generated part way through reload, so
3641 ;; if we don't match it as soon as it becomes available, reload doesn't know
3642 ;; how to reload pseudos that haven't got hard registers; the constraints will
3643 ;; sort everything out.
3645 (define_insn ""
3646   [(set (match_operand:SI 0 "" "=&r")
3647         (plus:SI (plus:SI (match_operator:SI 5 "shift_operator"
3648                            [(match_operand:SI 3 "" "r")
3649                             (match_operand:SI 4 "" "rn")])
3650                           (match_operand:SI 2 "" "r"))
3651                  (match_operand:SI 1 "const_int_operand" "n")))]
3652   "reload_in_progress"
3653   "*
3654   output_asm_insn (\"add%?\\t%0, %2, %3, %S5\", operands);
3655   operands[2] = operands[1];
3656   operands[1] = operands[0];
3657   return output_add_immediate (operands);
3659 ; we have no idea how long the add_immediate is, it could be up to 4.
3660 [(set_attr "length" "20")])
3662 (define_insn ""
3663   [(set (reg:CC_NOOV 24)
3664         (compare:CC_NOOV (plus:SI
3665                           (plus:SI 
3666                            (match_operator:SI 5 "shift_operator"
3667                             [(match_operand:SI 3 "" "r")
3668                              (match_operand:SI 4 "" "rn")])
3669                            (match_operand:SI 1 "" "r"))
3670                           (match_operand:SI 2 "const_int_operand" "n"))
3671                          (const_int 0)))
3672    (set (match_operand:SI 0 "" "=&r")
3673         (plus:SI (plus:SI (match_op_dup 5 [(match_dup 3) (match_dup 4)])
3674                           (match_dup 1))
3675                  (match_dup 2)))]
3676   "reload_in_progress"
3677   "*
3678   output_add_immediate (operands);
3679   return \"add%?s\\t%0, %0, %3, %S5\";
3681 [(set_attr "conds" "set")
3682  (set_attr "length" "20")])
3684 (define_insn ""
3685   [(set (reg:CC_NOOV 24)
3686         (compare:CC_NOOV (plus:SI
3687                           (plus:SI 
3688                            (match_operator:SI 5 "shift_operator"
3689                             [(match_operand:SI 3 "" "r")
3690                              (match_operand:SI 4 "" "rn")])
3691                            (match_operand:SI 1 "" "r"))
3692                           (match_operand:SI 2 "const_int_operand" "n"))
3693                          (const_int 0)))
3694    (clobber (match_scratch:SI 0 "=&r"))]
3695   "reload_in_progress"
3696   "*
3697   output_add_immediate (operands);
3698   return \"add%?s\\t%0, %0, %3, %S5\";
3700 [(set_attr "conds" "set")
3701  (set_attr "length" "20")])
3703 ;; These are similar, but are needed when the mla pattern contains the
3704 ;; eliminated register as operand 3.
3706 (define_insn ""
3707   [(set (match_operand:SI 0 "" "=&r,&r")
3708         (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "" "%0,r")
3709                                    (match_operand:SI 2 "" "r,r"))
3710                           (match_operand:SI 3 "" "r,r"))
3711                  (match_operand:SI 4 "const_int_operand" "n,n")))]
3712   "reload_in_progress"
3713   "*
3714   output_asm_insn (\"mla%?\\t%0, %2, %1, %3\", operands);
3715   operands[2] = operands[4];
3716   operands[1] = operands[0];
3717   return output_add_immediate (operands);
3719 [(set_attr "length" "20")])
3721 (define_insn ""
3722   [(set (reg:CC_NOOV 24)
3723         (compare:CC_NOOV (plus:SI (plus:SI (mult:SI
3724                                             (match_operand:SI 3 "" "r")
3725                                             (match_operand:SI 4 "" "r"))
3726                                            (match_operand:SI 1 "" "r"))
3727                                   (match_operand:SI 2 "const_int_operand" "n"))
3728                          (const_int 0)))
3729    (set (match_operand:SI 0 "" "=&r")
3730         (plus:SI (plus:SI (mult:SI (match_dup 3) (match_dup 4)) (match_dup 1))
3731                  (match_dup 2)))]
3732   "reload_in_progress"
3733   "*
3734   output_add_immediate (operands);
3735   output_asm_insn (\"mla%?s\\t%0, %3, %4, %0\", operands);
3736   return \"\";
3738 [(set_attr "length" "20")
3739  (set_attr "conds" "set")])
3741 (define_insn ""
3742   [(set (reg:CC_NOOV 24)
3743         (compare:CC_NOOV (plus:SI (plus:SI (mult:SI
3744                                             (match_operand:SI 3 "" "r")
3745                                             (match_operand:SI 4 "" "r"))
3746                                            (match_operand:SI 1 "" "r"))
3747                                   (match_operand:SI 2 "const_int_operand" "n"))
3748                          (const_int 0)))
3749    (clobber (match_scratch:SI 0 "=&r"))]
3750   "reload_in_progress"
3751   "*
3752   output_add_immediate (operands);
3753   return \"mla%?s\\t%0, %3, %4, %0\";
3755 [(set_attr "length" "20")
3756  (set_attr "conds" "set")])
3761 (define_insn ""
3762   [(set (match_operand:SI 0 "s_register_operand" "=r")
3763         (and:SI (match_operator 1 "comparison_operator"
3764                  [(reg 24) (const_int 0)])
3765                 (match_operand:SI 2 "s_register_operand" "r")))]
3766   ""
3767   "mov%D1\\t%0, #0\;and%d1\\t%0, %2, #1"
3768 [(set_attr "conds" "use")
3769  (set_attr "length" "8")])
3771 (define_insn ""
3772   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3773         (ior:SI (match_operator 2 "comparison_operator"
3774                  [(reg 24) (const_int 0)])
3775                 (match_operand:SI 1 "s_register_operand" "0,?r")))]
3776   ""
3777   "@
3778   orr%d2\\t%0, %1, #1
3779   mov%D2\\t%0, %1\;orr%d2\\t%0, %1, #1"
3780 [(set_attr "conds" "use")
3781  (set_attr "length" "4,8")])
3783 (define_insn ""
3784   [(set (match_operand:SI 0 "s_register_operand" "=r")
3785         (match_operator 1 "comparison_operator"
3786          [(match_operand:SI 2 "s_register_operand" "r")
3787           (match_operand:SI 3 "arm_add_operand" "rL")]))
3788    (clobber (reg 24))]
3789   ""
3790   "*
3791   if (GET_CODE (operands[1]) == LT && operands[3] == const0_rtx)
3792     return \"mov\\t%0, %2, lsr #31\";
3794   if (GET_CODE (operands[1]) == GE && operands[3] == const0_rtx)
3795     return \"mvn\\t%0, %2\;mov\\t%0, %0, lsr #31\";
3797   if (GET_CODE (operands[1]) == NE)
3798     {
3799       if (GET_CODE (operands[3]) == CONST_INT
3800           && !const_ok_for_arm (INTVAL (operands[3])))
3801         return \"adds\\t%0, %2, #%n3\;movne\\t%0, #1\";
3802       return \"subs\\t%0, %2, %3\;movne\\t%0, #1\";
3803     }
3804   if (GET_CODE (operands[3]) == CONST_INT
3805       && !const_ok_for_arm (INTVAL (operands[3])))
3806     output_asm_insn (\"cmn\\t%2, #%n3\", operands);
3807   else
3808     output_asm_insn (\"cmp\\t%2, %3\", operands);
3809   return \"mov%D1\\t%0, #0\;mov%d1\\t%0, #1\";
3811 [(set_attr "conds" "clob")
3812  (set_attr "length" "12")])
3814 (define_insn ""
3815   [(set (match_operand:SI 0 "s_register_operand" "=&r")
3816         (ior:SI (match_operator 1 "comparison_operator"
3817                  [(match_operand:SI 2 "s_register_operand" "r")
3818                   (match_operand:SI 3 "arm_rhs_operand" "rI")])
3819                 (match_operator 4 "comparison_operator"
3820                  [(match_operand:SI 5 "s_register_operand" "r")
3821                   (match_operand:SI 6 "arm_rhs_operand" "rI")])))
3822    (clobber (reg 24))]
3823   ""
3824   "*
3826   int dominant = comparison_dominates_p (GET_CODE (operands[4]),
3827                                          GET_CODE (operands[1]));
3829   output_asm_insn (dominant ? \"cmp\\t%5, %6\" : \"cmp\\t%2, %3\",
3830                    operands);
3831   output_asm_insn (\"mov\\t%0, #0\", operands);
3832   if (GET_CODE (operands[1]) == GET_CODE (operands[4])
3833       || comparison_dominates_p (GET_CODE (operands[1]),
3834                                  GET_CODE (operands[4]))
3835       || dominant)
3836     output_asm_insn (dominant ? \"cmp%D4\\t%2, %3\" : \"cmp%D1\\t%5,%6\",
3837                      operands);
3838   else
3839     output_asm_insn (\"mov%d1\\t%0, #1\;cmp\\t%5, %6\", operands);
3840   return dominant ? \"mov%d1\\t%0, #1\" : \"mov%d4\\t%0, #1\";
3843 [(set_attr "conds" "clob")
3844 ; worst case length
3845  (set_attr "length" "20")])
3847 (define_split
3848   [(set (pc)
3849         (if_then_else (match_operator 5 "equality_operator"
3850                        [(ior:SI (match_operator 6 "comparison_operator"
3851                                  [(match_operand:SI 0 "s_register_operand" "r")
3852                                   (match_operand:SI 1 "arm_add_operand" "rL")])
3853                                 (match_operator 7 "comparison_operator"
3854                                  [(match_operand:SI 2 "s_register_operand" "r")
3855                                   (match_operand:SI 3 "arm_add_operand" "rL")]))
3856                         (const_int 0)])
3857                       (label_ref (match_operand 4 "" ""))
3858                       (pc)))
3859    (clobber (reg 24))]
3860   "(GET_CODE (operands[6]) == GET_CODE (operands[7])
3861     || comparison_dominates_p (GET_CODE (operands[6]), GET_CODE (operands[7]))
3862     || comparison_dominates_p (GET_CODE (operands[7]), GET_CODE (operands[6])))"
3863   [(set (reg:CC 24)
3864         (compare:CC (ior:CC (match_op_dup 6
3865                              [(match_dup 0) (match_dup 1)])
3866                             (match_op_dup 7
3867                              [(match_dup 2) (match_dup 3)]))
3868                     (const_int 0)))
3869    (set (pc)
3870         (if_then_else (match_op_dup 5 [(reg:CC 24) (const_int 0)])
3871                       (label_ref (match_dup 4))
3872                       (pc)))]
3873   "
3875   enum rtx_code code = comparison_dominates_p (GET_CODE (operands[6]),
3876                                                GET_CODE (operands[7]))
3877                        ? GET_CODE (operands[7]) : GET_CODE (operands[6]);
3879   if (GET_CODE (operands[5]) == NE)
3880     operands[5] = gen_rtx (code, CCmode,
3881                            XEXP (operands[5], 0), XEXP (operands[5], 1));
3882   else
3883     operands[5] = gen_rtx (reverse_condition (code), CCmode,
3884                            XEXP (operands[5], 0), XEXP (operands[5], 1));
3888 ;; Don't match these patterns if we can use a conditional compare, since they
3889 ;; tell the final prescan branch elimator code that full branch inlining
3890 ;; can't be done.
3892 (define_insn ""
3893   [(set (pc)
3894         (if_then_else (ne
3895                        (ior:SI (match_operator 5 "comparison_operator"
3896                                 [(match_operand:SI 0 "s_register_operand" "r")
3897                                  (match_operand:SI 1 "arm_add_operand" "rL")])
3898                                (match_operator 6 "comparison_operator"
3899                                 [(match_operand:SI 2 "s_register_operand" "r")
3900                                  (match_operand:SI 3 "arm_rhs_operand" "rL")]))
3901                        (const_int 0))
3902                       (label_ref (match_operand 4 "" ""))
3903                       (pc)))
3904    (clobber (reg 24))]
3905   "!(GET_CODE (operands[5]) == GET_CODE (operands[6])
3906      || comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[6]))
3907      || comparison_dominates_p (GET_CODE (operands[6]), GET_CODE (operands[5])))"
3908   "*
3910   extern int arm_ccfsm_state;
3912   if (GET_CODE (operands[1]) == CONST_INT
3913       && !const_ok_for_arm (INTVAL (operands[1])))
3914     output_asm_insn (\"cmn\\t%0, #%n1\", operands);
3915   else
3916     output_asm_insn (\"cmp\\t%0, %1\", operands);
3918   output_asm_insn (\"b%d5\\t%l4\", operands);
3919   if (GET_CODE (operands[3]) == CONST_INT
3920       && !const_ok_for_arm (INTVAL (operands[3])))
3921     output_asm_insn (\"cmn\\t%2, #%n3\", operands);
3922   else
3923     output_asm_insn (\"cmp\\t%2, %3\", operands);
3925   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3926   {
3927     arm_ccfsm_state += 2;
3928     return \"\";
3929   }
3930   return \"b%d6\\t%l4\";
3932 [(set_attr "conds" "jump_clob")
3933  (set_attr "length" "16")])
3935 (define_insn ""
3936   [(set (reg:CC 24)
3937         (compare:CC (ior:CC (match_operator 4 "comparison_operator"
3938                              [(match_operand:SI 0 "s_register_operand" "r")
3939                               (match_operand:SI 1 "arm_add_operand" "rL")])
3940                             (match_operator 5 "comparison_operator"
3941                              [(match_operand:SI 2 "s_register_operand" "r")
3942                               (match_operand:SI 3 "arm_add_operand" "rL")]))
3943                     (const_int 0)))]
3944   "(GET_CODE (operands[4]) == GET_CODE (operands[5])
3945     || comparison_dominates_p (GET_CODE (operands[4]), GET_CODE (operands[5]))
3946     || comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])))"
3947   "*
3948   if (comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])))
3949     {
3950       if (GET_CODE (operands[3]) == CONST_INT
3951           && !const_ok_for_arm (INTVAL (operands[3])))
3952         output_asm_insn (\"cmn\\t%2, #%n3\", operands);
3953       else
3954         output_asm_insn (\"cmp\\t%2, %3\", operands);
3956       if (GET_CODE (operands[1]) == CONST_INT
3957           && !const_ok_for_arm (INTVAL (operands[1])))
3958         return \"cmn%D5\\t%0, #%n1\";
3959       return \"cmp%D5\\t%0, %1\";
3960     }
3962   if (GET_CODE (operands[1]) == CONST_INT
3963       && !const_ok_for_arm (INTVAL (operands[1])))
3964     output_asm_insn (\"cmn\\t%0, #%n1\", operands);
3965   else
3966     output_asm_insn (\"cmp\\t%0, %1\", operands);
3968   if (GET_CODE (operands[3]) == CONST_INT
3969       && !const_ok_for_arm (INTVAL (operands[3])))
3970     return \"cmn%D4\\t%2, #%n3\";
3971   return \"cmp%D4\\t%2, %3\";
3973 [(set_attr "conds" "set")
3974  (set_attr "length" "8")])
3976 (define_insn ""
3977   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3978         (if_then_else (match_operator 3 "equality_operator"
3979                        [(match_operator 4 "comparison_operator"
3980                          [(reg 24) (const_int 0)])
3981                         (const_int 0)])
3982                       (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
3983                       (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
3984   ""
3985   "*
3986   if (GET_CODE (operands[3]) == NE)
3987     {
3988       if (which_alternative != 0)
3989         output_asm_insn (\"mov%d4\\t%0, %1\", operands);
3990       if (which_alternative != 1)
3991         output_asm_insn (\"mov%D4\\t%0, %2\", operands);
3992       return \"\";
3993     }
3994   if (which_alternative != 0)
3995     output_asm_insn (\"mov%D4\\t%0, %1\", operands);
3996   if (which_alternative != 1)
3997     output_asm_insn (\"mov%d4\\t%0, %2\", operands);
3998   return \"\";
4000 [(set_attr "conds" "use")
4001  (set_attr "length" "4,4,8")])
4003 (define_insn ""
4004   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4005         (match_operator:SI 5 "shiftable_operator" 
4006          [(match_operator:SI 4 "comparison_operator"
4007            [(match_operand:SI 2 "s_register_operand" "r,r")
4008             (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
4009           (match_operand:SI 1 "s_register_operand" "0,?r")]))
4010    (clobber (reg 24))]
4011   ""
4012   "*
4013   if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
4014     return \"%i5\\t%0, %1, %2, lsr #31\";
4016   output_asm_insn (\"cmp\\t%2, %3\", operands);
4017   if (GET_CODE (operands[5]) == AND)
4018     output_asm_insn (\"mov%D4\\t%0, #0\", operands);
4019   else if (which_alternative != 0)
4020     output_asm_insn (\"mov%D4\\t%0, %1\", operands);
4021   return \"%i5%d4\\t%0, %1, #1\";
4023 [(set_attr "conds" "clob")
4024  (set_attr "length" "12")])
4026 (define_insn ""
4027   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4028         (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
4029                   (match_operator:SI 4 "comparison_operator"
4030                    [(match_operand:SI 2 "s_register_operand" "r,r")
4031                     (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
4032    (clobber (reg 24))]
4033   ""
4034   "*
4035   output_asm_insn (\"cmp\\t%2, %3\", operands);
4036   if (which_alternative != 0)
4037     output_asm_insn (\"mov%D4\\t%0, %1\", operands);
4038   return \"sub%d4\\t%0, %1, #1\";
4040 [(set_attr "conds" "clob")
4041  (set_attr "length" "8,12")])
4043 (define_insn ""
4044   [(set (match_operand:SI 0 "s_register_operand" "=&r")
4045         (and:SI (match_operator 1 "comparison_operator"
4046                  [(match_operand:SI 2 "s_register_operand" "r")
4047                   (match_operand:SI 3 "arm_rhs_operand" "rI")])
4048                 (match_operator 4 "comparison_operator"
4049                  [(match_operand:SI 5 "s_register_operand" "r")
4050                   (match_operand:SI 6 "arm_rhs_operand" "rI")])))
4051    (clobber (reg 24))]
4052   ""
4053   "*
4055   int dominant =
4056         comparison_dominates_p (reverse_condition (GET_CODE (operands[1])),
4057                                 reverse_condition (GET_CODE (operands[4])))
4058         ? 1 
4059         : comparison_dominates_p (reverse_condition (GET_CODE (operands[4])),
4060                                   reverse_condition (GET_CODE (operands[1])))
4061         ? 2 : 0;
4062   output_asm_insn (dominant == 2 ? \"cmp\\t%5, %6\" : \"cmp\\t%2, %3\",
4063                        operands);
4064   output_asm_insn (\"mov\\t%0, #1\", operands);
4065   if (GET_CODE (operands[1]) == GET_CODE (operands[4]) || dominant)
4066     {
4067       output_asm_insn (dominant == 2 ? \"cmp%d4\\t%2, %3\"
4068                            : \"cmp%d1\\t%5, %6\", operands);
4069     }
4070   else
4071     {
4072       output_asm_insn (\"mov%D1\\t%0, #0\", operands);
4073       output_asm_insn (\"cmp\\t%5, %6\", operands);
4074     }
4075   return dominant == 2 ? \"mov%D1\\t%0, #0\" : \"mov%D4\\t%0, #0\";
4078 [(set_attr "conds" "clob")
4079  (set_attr "length" "20")])
4081 (define_split
4082   [(set (pc)
4083         (if_then_else (match_operator 1 "equality_operator"
4084                        [(and:SI (match_operator 2 "comparison_operator"
4085                                  [(match_operand:SI 3 "s_register_operand" "r")
4086                                   (match_operand:SI 4 "arm_add_operand" "rL")])
4087                                 (match_operator 0 "comparison_operator"
4088                                  [(match_operand:SI 5 "s_register_operand" "r")
4089                                   (match_operand:SI 6 "arm_add_operand" "rL")]))
4090                         (const_int 0)])
4091                       (label_ref (match_operand 7 "" ""))
4092                       (pc)))
4093    (clobber (reg 24))]
4094   "(GET_CODE (operands[2]) == GET_CODE (operands[0])
4095     || comparison_dominates_p (reverse_condition (GET_CODE (operands[2])),
4096                                reverse_condition (GET_CODE (operands[0])))
4097     || comparison_dominates_p (reverse_condition (GET_CODE (operands[0])),
4098                                reverse_condition (GET_CODE (operands[2]))))"
4099   [(set (reg:CC 24)
4100         (compare:CC (ior:CC (match_op_dup 2
4101                              [(match_dup 3) (match_dup 4)])
4102                             (match_op_dup 0
4103                              [(match_dup 5) (match_dup 6)]))
4104                     (const_int 0)))
4105    (set (pc)
4106         (if_then_else (match_op_dup 1 [(reg:CC 24) (const_int 0)])
4107                       (label_ref (match_dup 7))
4108                       (pc)))]
4109   "
4111   /* Use DeMorgans law to convert this into an IOR of the inverse conditions 
4112      This is safe since we only do it for integer comparisons. */
4113   enum rtx_code code = 
4114         comparison_dominates_p (reverse_condition (GET_CODE (operands[2])),
4115                                 reverse_condition (GET_CODE (operands[0])))
4116         ? GET_CODE (operands[0]) : GET_CODE (operands[2]);
4118   operands[2] = gen_rtx (reverse_condition (GET_CODE (operands[2])),
4119                          GET_MODE (operands[2]), operands[3], operands[4]);
4120   operands[0] = gen_rtx (reverse_condition (GET_CODE (operands[0])),
4121                          GET_MODE (operands[0]), operands[5], operands[6]);
4122   if (GET_CODE (operands[1]) == NE)
4123     operands[1] = gen_rtx (code, CCmode,
4124                            XEXP (operands[1], 0), XEXP (operands[1], 1));
4125   else
4126     operands[1] = gen_rtx (reverse_condition (code), CCmode,
4127                            XEXP (operands[1], 0), XEXP (operands[1], 1));
4131 ;; Don't match these patterns if we can use a conditional compare, since they
4132 ;; tell the final prescan branch elimator code that full branch inlining
4133 ;; can't be done.
4135 (define_insn ""
4136   [(set (pc)
4137         (if_then_else (eq
4138                        (and:SI (match_operator 1 "comparison_operator"
4139                                 [(match_operand:SI 2 "s_register_operand" "r")
4140                                  (match_operand:SI 3 "arm_add_operand" "rL")])
4141                                (match_operator 4 "comparison_operator"
4142                                 [(match_operand:SI 5 "s_register_operand" "r")
4143                                  (match_operand:SI 6 "arm_rhs_operand" "rL")]))
4144                        (const_int 0))
4145                       (label_ref (match_operand 0 "" ""))
4146                       (pc)))
4147    (clobber (reg 24))]
4148   "!(GET_CODE (operands[1]) == GET_CODE (operands[4])
4149      || comparison_dominates_p (reverse_condition (GET_CODE (operands[1])),
4150                                 reverse_condition (GET_CODE (operands[4])))
4151      || comparison_dominates_p (reverse_condition (GET_CODE (operands[4])),
4152                                 reverse_condition (GET_CODE (operands[1]))))"
4153   "*
4155   extern int arm_ccfsm_state;
4157   if (GET_CODE (operands[3]) == CONST_INT
4158       && !const_ok_for_arm (INTVAL (operands[3])))
4159     output_asm_insn (\"cmn\\t%2, #%n3\", operands);
4160   else
4161     output_asm_insn (\"cmp\\t%2, %3\", operands);
4162   output_asm_insn (\"b%D1\\t%l0\", operands);
4163   if (GET_CODE (operands[6]) == CONST_INT
4164       && !const_ok_for_arm (INTVAL (operands[6])))
4165     output_asm_insn (\"cmn\\t%5, #%n6\", operands);
4166   else
4167     output_asm_insn (\"cmp\\t%5, %6\", operands);
4168   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
4169   {
4170     arm_ccfsm_state += 2;
4171     return \"\";
4172   }
4173   return \"b%D4\\t%l0\";
4175 [(set_attr "conds" "jump_clob")
4176  (set_attr "length" "16")])
4178 (define_insn ""
4179   [(set (match_operand:SI 0 "s_register_operand" "=r")
4180         (neg:SI (match_operator 3 "comparison_operator"
4181                  [(match_operand:SI 1 "s_register_operand" "r")
4182                   (match_operand:SI 2 "arm_rhs_operand" "rI")])))
4183    (clobber (reg 24))]
4184   ""
4185   "*
4186   if (GET_CODE (operands[3]) == LT && operands[3] == const0_rtx)
4187     return \"mov\\t%0, %1, asr #31\";
4189   if (GET_CODE (operands[3]) == NE)
4190     return \"subs\\t%0, %1, %2\;mvnne\\t%0, #0\";
4192   if (GET_CODE (operands[3]) == GT)
4193     return \"subs\\t%0, %1, %2\;mvnne\\t%0, %0, asr #31\";
4195   output_asm_insn (\"cmp\\t%1, %2\", operands);
4196   output_asm_insn (\"mov%D3\\t%0, #0\", operands);
4197   return \"mvn%d3\\t%0, #0\";
4199 [(set_attr "conds" "clob")
4200  (set_attr "length" "12")])
4202 (define_insn "movcond"
4203   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
4204         (if_then_else:SI (match_operator 5 "comparison_operator"
4205                           [(match_operand:SI 3 "s_register_operand" "r,r,r")
4206                            (match_operand:SI 4 "arm_add_operand" "rL,rL,rL")])
4207                          (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
4208                          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
4209    (clobber (reg 24))]
4210   ""
4211   "*
4212   if (GET_CODE (operands[5]) == LT
4213       && (operands[4] == const0_rtx))
4214     {
4215       if (which_alternative != 1 && GET_CODE (operands[4]) == REG)
4216         {
4217           if (operands[2] == const0_rtx)
4218             return \"and\\t%0, %1, %3, asr #31\";
4219           return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
4220         }
4221       else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
4222         {
4223           if (operands[1] == const0_rtx)
4224             return \"bic\\t%0, %2, %3, asr #31\";
4225           return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
4226         }
4227       /* The only case that falls through to here is when both ops 1 & 2
4228          are constants */
4229     }
4231   if (GET_CODE (operands[5]) == GE
4232       && (operands[4] == const0_rtx))
4233     {
4234       if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
4235         {
4236           if (operands[2] == const0_rtx)
4237             return \"bic\\t%0, %1, %3, asr #31\";
4238           return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
4239         }
4240       else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
4241         {
4242           if (operands[1] == const0_rtx)
4243             return \"and\\t%0, %2, %3, asr #31\";
4244           return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
4245         }
4246       /* The only case that falls through to here is when both ops 1 & 2
4247          are constants */
4248     }
4249   if (GET_CODE (operands[4]) == CONST_INT
4250       && !const_ok_for_arm (INTVAL (operands[4])))
4251     output_asm_insn (\"cmn\\t%3, #%n4\", operands);
4252   else
4253     output_asm_insn (\"cmp\\t%3, %4\", operands);
4254   if (which_alternative != 0)
4255     output_asm_insn (\"mov%d5\\t%0, %1\", operands);
4256   if (which_alternative != 1)
4257     output_asm_insn (\"mov%D5\\t%0, %2\", operands);
4258   return \"\";
4260 [(set_attr "conds" "clob")
4261  (set_attr "length" "8,8,12")])
4263 (define_insn ""
4264   [(set (match_operand:SI 0 "s_register_operand" "=r")
4265         (if_then_else:SI (match_operator 9 "comparison_operator"
4266                           [(match_operand:SI 5 "s_register_operand" "r")
4267                            (match_operand:SI 6 "arm_add_operand" "rL")])
4268                          (match_operator:SI 8 "shiftable_operator"
4269                           [(match_operand:SI 1 "s_register_operand" "r")
4270                            (match_operand:SI 2 "arm_rhs_operand" "rI")])
4271                          (match_operator:SI 7 "shiftable_operator"
4272                           [(match_operand:SI 3 "s_register_operand" "r")
4273                            (match_operand:SI 4 "arm_rhs_operand" "rI")])))
4274    (clobber (reg 24))]
4275   ""
4276   "*
4277   if (GET_CODE (operands[6]) == CONST_INT
4278       && !const_ok_for_arm (INTVAL (operands[6])))
4279     output_asm_insn (\"cmn\\t%5, #%n6\", operands);
4280   else
4281     output_asm_insn (\"cmp\\t%5, %6\", operands);
4282   return \"%I8%d9\\t%0, %1, %2\;%I7%D9\\t%0, %3, %4\";
4284 [(set_attr "conds" "clob")
4285  (set_attr "length" "12")])
4287 (define_insn ""
4288   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4289         (if_then_else:SI (match_operator 6 "comparison_operator"
4290                           [(match_operand:SI 2 "s_register_operand" "r,r")
4291                            (match_operand:SI 3 "arm_add_operand" "rL,rL")])
4292                          (match_operator:SI 7 "shiftable_operator"
4293                           [(match_operand:SI 4 "s_register_operand" "r,r")
4294                            (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
4295                          (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")))
4296    (clobber (reg 24))]
4297   ""
4298   "*
4299   /* If we have an operation where (op x 0) is the identity operation and
4300      the condtional operator is LT or GE and we are comparing against zero and
4301      everything is in registers then we can do this in two instructions */
4302   if (operands[3] == const0_rtx
4303       && GET_CODE (operands[7]) != AND
4304       && GET_CODE (operands[5]) == REG
4305       && GET_CODE (operands[1]) == REG 
4306       && REGNO (operands[1]) == REGNO (operands[4])
4307       && REGNO (operands[4]) != REGNO (operands[0]))
4308     {
4309       if (GET_CODE (operands[6]) == LT)
4310         return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
4311       else if (GET_CODE (operands[6]) == GE)
4312         return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
4313     }
4314   if (GET_CODE (operands[3]) == CONST_INT
4315       && !const_ok_for_arm (INTVAL (operands[3])))
4316     output_asm_insn (\"cmn\\t%2, #%n3\", operands);
4317   else
4318     output_asm_insn (\"cmp\\t%2, %3\", operands);
4319   output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
4320   if (which_alternative != 0)
4321     {
4322       if (GET_CODE (operands[1]) == MEM)
4323         return \"ldr%D6\\t%0, %1\";
4324       else
4325         return \"mov%D6\\t%0, %1\";
4326     }
4327   return \"\";
4329 [(set_attr "conds" "clob")
4330  (set_attr "length" "8,12")])
4332 (define_insn ""
4333   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4334         (if_then_else:SI (match_operator 6 "comparison_operator"
4335                           [(match_operand:SI 4 "s_register_operand" "r,r")
4336                            (match_operand:SI 5 "arm_add_operand" "rL,rL")])
4337                          (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")
4338                          (match_operator:SI 7 "shiftable_operator"
4339                           [(match_operand:SI 2 "s_register_operand" "r,r")
4340                            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
4341    (clobber (reg 24))]
4342   ""
4343   "*
4344   /* If we have an operation where (op x 0) is the identity operation and
4345      the condtional operator is LT or GE and we are comparing against zero and
4346      everything is in registers then we can do this in two instructions */
4347   if (operands[5] == const0_rtx
4348       && GET_CODE (operands[7]) != AND
4349       && GET_CODE (operands[3]) == REG
4350       && GET_CODE (operands[1]) == REG 
4351       && REGNO (operands[1]) == REGNO (operands[2])
4352       && REGNO (operands[2]) != REGNO (operands[0]))
4353     {
4354       if (GET_CODE (operands[6]) == GE)
4355         return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
4356       else if (GET_CODE (operands[6]) == LT)
4357         return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
4358     }
4360   if (GET_CODE (operands[5]) == CONST_INT
4361       && !const_ok_for_arm (INTVAL (operands[5])))
4362     output_asm_insn (\"cmn\\t%4, #%n5\", operands);
4363   else
4364     output_asm_insn (\"cmp\\t%4, %5\", operands);
4366   if (which_alternative != 0)
4367     {
4368       if (GET_CODE (operands[1]) == MEM)
4369         output_asm_insn (\"ldr%d6\\t%0, %1\", operands);
4370       else
4371         output_asm_insn (\"mov%d6\\t%0, %1\", operands);
4372     }
4373   return \"%I7%D6\\t%0, %2, %3\";
4375 [(set_attr "conds" "clob")
4376  (set_attr "length" "8,12")])
4378 (define_insn ""
4379   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4380         (if_then_else:SI (match_operator 6 "comparison_operator"
4381                           [(match_operand:SI 4 "s_register_operand" "r,r")
4382                            (match_operand:SI 5 "arm_add_operand" "rL,rL")])
4383                          (plus:SI
4384                           (match_operand:SI 2 "s_register_operand" "r,r")
4385                           (match_operand:SI 3 "arm_add_operand" "rL,rL"))
4386                          (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")))
4387    (clobber (reg 24))]
4388   ""
4389   "*
4391   if (GET_CODE (operands[5]) == CONST_INT
4392       && !const_ok_for_arm (INTVAL (operands[5])))
4393     output_asm_insn (\"cmn\\t%4, #%n5\", operands);
4394   else
4395     output_asm_insn (\"cmp\\t%4, %5\", operands);
4396   if (GET_CODE (operands[3]) == CONST_INT
4397       && !const_ok_for_arm (INTVAL (operands[3])))
4398     output_asm_insn (\"sub%d6\\t%0, %2, #%n3\", operands);
4399   else
4400     output_asm_insn (\"add%d6\\t%0, %2, %3\", operands);
4401   if (which_alternative != 0)
4402     {
4403       if (GET_CODE (operands[1]) == MEM)
4404         output_asm_insn (\"ldr%D6\\t%0, %1\", operands);
4405       else
4406         output_asm_insn (\"mov%D6\\t%0, %1\", operands);
4407     }
4408   return \"\";
4411 [(set_attr "conds" "clob")
4412  (set_attr "length" "8,12")])
4414 (define_insn ""
4415   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4416         (if_then_else:SI (match_operator 6 "comparison_operator"
4417                           [(match_operand:SI 4 "s_register_operand" "r,r")
4418                            (match_operand:SI 5 "arm_add_operand" "rL,rL")])
4419                          (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")
4420                          (plus:SI
4421                           (match_operand:SI 2 "s_register_operand" "r,r")
4422                           (match_operand:SI 3 "arm_add_operand" "rL,rL"))))
4423    (clobber (reg 24))]
4424   ""
4425   "*
4427   if (GET_CODE (operands[5]) == CONST_INT
4428       && !const_ok_for_arm (INTVAL (operands[5])))
4429     output_asm_insn (\"cmn\\t%4, #%n5\", operands);
4430   else
4431     output_asm_insn (\"cmp\\t%4, %5\", operands);
4432   if (GET_CODE (operands[3]) == CONST_INT
4433       && !const_ok_for_arm (INTVAL (operands[3])))
4434     output_asm_insn (\"sub%D6\\t%0, %2, #%n3\", operands);
4435   else
4436     output_asm_insn (\"add%D6\\t%0, %2, %3\", operands);
4437   if (which_alternative != 0)
4438     {
4439       if (GET_CODE (operands[6]) == MEM)
4440         output_asm_insn (\"ldr%d6\\t%0, %1\", operands);
4441       else
4442         output_asm_insn (\"mov%d6\\t%0, %1\", operands);
4443     }
4444   return \"\";
4447 [(set_attr "conds" "clob")
4448  (set_attr "length" "8,12")])
4450 (define_insn ""
4451   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4452         (if_then_else:SI (match_operator 5 "comparison_operator"
4453                           [(match_operand:SI 3 "s_register_operand" "r,r")
4454                            (match_operand:SI 4 "arm_add_operand" "rL,rL")])
4455                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
4456                          (not:SI
4457                           (match_operand:SI 2 "s_register_operand" "r,r"))))
4458    (clobber (reg 24))]
4459   ""
4460   "#"
4461 [(set_attr "conds" "clob")
4462  (set_attr "length" "8,12")])
4464 (define_insn ""
4465   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4466         (if_then_else:SI (match_operator 5 "comparison_operator"
4467                           [(match_operand:SI 3 "s_register_operand" "r,r")
4468                            (match_operand:SI 4 "arm_add_operand" "rL,rL")])
4469                          (not:SI
4470                           (match_operand:SI 2 "s_register_operand" "r,r"))
4471                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
4472    (clobber (reg 24))]
4473   ""
4474   "*
4476   char pattern[100];
4478   if (GET_CODE (operands[30]) == CONST_INT
4479       && !const_ok_for_arm (INTVAL (operands[4])))
4480     output_asm_insn (\"cmn\\t%3, #%n4\", operands);
4481   else
4482     output_asm_insn (\"cmp\\t%3, %4\", operands);
4483   if (which_alternative != 0)
4484     output_asm_insn (\"mov%D5\\t%0, %1\", operands);
4485   return \"mvn%d5\\t%0, %2\";
4489 [(set_attr "conds" "clob")
4490  (set_attr "length" "8,12")])
4492 (define_insn ""
4493   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4494         (if_then_else:SI (match_operator 6 "comparison_operator"
4495                           [(match_operand:SI 4 "s_register_operand" "r,r")
4496                            (match_operand:SI 5 "arm_add_operand" "rL,rL")])
4497                          (match_operator:SI 7 "shift_operator"
4498                           [(match_operand:SI 2 "s_register_operand" "r,r")
4499                            (match_operand:SI 3 "arm_rhs_operand" "rn,rn")])
4500                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
4501    (clobber (reg 24))]
4502   ""
4503   "*
4504   if (GET_CODE (operands[5]) == CONST_INT
4505       && !const_ok_for_arm (INTVAL (operands[5])))
4506     output_asm_insn (\"cmn\\t%4, #%n5\", operands);
4507   else
4508     output_asm_insn (\"cmp\\t%4, %5\", operands);
4509   if (which_alternative != 0)
4510     output_asm_insn (\"mov%D6\\t%0, %1\", operands);
4511   return \"mov%d6\\t%0, %2, %S7\";
4513 [(set_attr "conds" "clob")
4514  (set_attr "length" "8,12")])
4516 (define_insn ""
4517   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4518         (if_then_else:SI (match_operator 6 "comparison_operator"
4519                           [(match_operand:SI 4 "s_register_operand" "r,r")
4520                            (match_operand:SI 5 "arm_add_operand" "rL,rL")])
4521                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
4522                          (match_operator:SI 7 "shift_operator"
4523                           [(match_operand:SI 2 "s_register_operand" "r,r")
4524                            (match_operand:SI 3 "arm_rhs_operand" "rn,rn")])))
4525    (clobber (reg 24))]
4526   ""
4527   "*
4528   if (GET_CODE (operands[5]) == CONST_INT
4529       && !const_ok_for_arm (INTVAL (operands[5])))
4530     output_asm_insn (\"cmn\\t%4, #%n5\", operands);
4531   else
4532     output_asm_insn (\"cmp\\t%4, %5\", operands);
4533   if (which_alternative != 0)
4534     output_asm_insn (\"mov%d6\\t%0, %1\", operands);
4535   return \"mov%D6\\t%0, %2, %S7\";
4537 [(set_attr "conds" "clob")
4538  (set_attr "length" "8,12")])
4540 (define_insn ""
4541   [(set (match_operand:SI 0 "s_register_operand" "=r")
4542         (if_then_else:SI (match_operator 7 "comparison_operator"
4543                           [(match_operand:SI 5 "s_register_operand" "r")
4544                            (match_operand:SI 6 "arm_add_operand" "rL")])
4545                          (match_operator:SI 8 "shift_operator"
4546                           [(match_operand:SI 1 "s_register_operand" "r")
4547                            (match_operand:SI 2 "arm_rhs_operand" "rn")])
4548                          (match_operator:SI 9 "shift_operator"
4549                           [(match_operand:SI 3 "s_register_operand" "r")
4550                            (match_operand:SI 4 "arm_rhs_operand" "rI")])))
4551    (clobber (reg 24))]
4552   ""
4553   "*
4554   if (GET_CODE (operands[6]) == CONST_INT
4555       && !const_ok_for_arm (INTVAL (operands[6])))
4556     output_asm_insn (\"cmn\\t%5, #%n6\", operands);
4557   else
4558     output_asm_insn (\"cmp\\t%5, %6\", operands);
4559   return \"mov%d7\\t%0, %1, %S8\;mov%D7\\t%0, %3, %S9\";
4561 [(set_attr "conds" "clob")
4562  (set_attr "length" "12")])
4564 (define_insn ""
4565   [(set (match_operand:SI 0 "s_register_operand" "=r")
4566         (if_then_else:SI (match_operator 6 "comparison_operator"
4567                           [(match_operand:SI 4 "s_register_operand" "r")
4568                            (match_operand:SI 5 "arm_add_operand" "rL")])
4569                          (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4570                          (match_operator:SI 7 "shiftable_operator"
4571                           [(match_operand:SI 2 "s_register_operand" "r")
4572                            (match_operand:SI 3 "arm_rhs_operand" "rI")])))
4573    (clobber (reg 24))]
4574   ""
4575   "*
4576   if (GET_CODE (operands[5]) == CONST_INT
4577       && !const_ok_for_arm (INTVAL (operands[5])))
4578     output_asm_insn (\"cmn\\t%4, #%n5\", operands);
4579   else
4580     output_asm_insn (\"cmp\\t%4, %5\", operands);
4581   return \"mvn%d6\\t%0, %1\;%I7%D6\\t%0, %2, %3\";
4583 [(set_attr "conds" "clob")
4584  (set_attr "length" "12")])
4586 (define_insn ""
4587   [(set (match_operand:SI 0 "s_register_operand" "=r")
4588         (if_then_else:SI (match_operator 6 "comparison_operator"
4589                           [(match_operand:SI 4 "s_register_operand" "r")
4590                            (match_operand:SI 5 "arm_add_operand" "rL")])
4591                          (match_operator:SI 7 "shiftable_operator"
4592                           [(match_operand:SI 2 "s_register_operand" "r")
4593                            (match_operand:SI 3 "arm_rhs_operand" "rI")])
4594                          (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
4595    (clobber (reg 24))]
4596   ""
4597   "*
4598   if (GET_CODE (operands[5]) == CONST_INT
4599       && !const_ok_for_arm (INTVAL (operands[5])))
4600     output_asm_insn (\"cmn\\t%4, #%n5\", operands);
4601   else
4602     output_asm_insn (\"cmp\\t%4, %5\", operands);
4603   return \"mvn%D6\\t%0, %1\;%I7%d6\\t%0, %2, %3\";
4605 [(set_attr "conds" "clob")
4606  (set_attr "length" "12")])
4608 (define_insn ""
4609   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4610         (if_then_else:SI (match_operator 5 "comparison_operator"
4611                           [(match_operand:SI 3 "s_register_operand" "r,r")
4612                            (match_operand:SI 4 "arm_add_operand" "rL,rL")])
4613                          (neg:SI
4614                           (match_operand:SI 2 "s_register_operand" "r,r"))
4615                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
4616    (clobber (reg:CC 24))]
4617   ""
4618   "*
4619   if (GET_CODE (operands[4]) == CONST_INT
4620       && !const_ok_for_arm (INTVAL (operands[4])))
4621     output_asm_insn (\"cmn\\t%3, #%n4\", operands);
4622   else
4623     output_asm_insn (\"cmp\\t%3, %4\", operands);
4624   if (which_alternative != 0)
4625     output_asm_insn (\"mov%D5\\t%0, %1\", operands);
4626   return \"rsb%d5\\t%0, %2, #0\";
4628 [(set_attr "conds" "clob")
4629  (set_attr "length" "8,12")])
4631 (define_insn ""
4632   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4633         (if_then_else:SI (match_operator 5 "comparison_operator"
4634                           [(match_operand:SI 3 "s_register_operand" "r,r")
4635                            (match_operand:SI 4 "arm_add_operand" "rL,rL")])
4636                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
4637                          (neg:SI
4638                           (match_operand:SI 2 "s_register_operand" "r,r"))))
4639    (clobber (reg:CC 24))]
4640   ""
4641   "*
4642   if (GET_CODE (operands[4]) == CONST_INT
4643       && !const_ok_for_arm (INTVAL (operands[4])))
4644     output_asm_insn (\"cmn\\t%3, #%n4\", operands);
4645   else
4646     output_asm_insn (\"cmp\\t%3, %4\", operands);
4647   if (which_alternative != 0)
4648     output_asm_insn (\"mov%d5\\t%0, %1\", operands);
4649   return \"rsb%D5\\t%0, %2, #0\";
4651 [(set_attr "conds" "clob")
4652  (set_attr "length" "8,12")])
4654 (define_insn ""
4655   [(set (match_operand:SI 0 "s_register_operand" "=r")
4656         (match_operator:SI 1 "shiftable_operator"
4657          [(match_operand:SI 2 "memory_operand" "m")
4658           (match_operand:SI 3 "memory_operand" "m")]))
4659    (clobber (match_scratch:SI 4 "=r"))]
4660   "adjacent_mem_locations (operands[2], operands[3])"
4661   "*
4663   rtx ldm[3];
4664   rtx arith[3];
4665   int val1 = 0, val2 = 0;
4667   if (REGNO (operands[0]) > REGNO (operands[4]))
4668     {
4669       ldm[1] = operands[4];
4670       ldm[2] = operands[0];
4671     }
4672   else
4673     {
4674       ldm[1] = operands[0];
4675       ldm[2] = operands[4];
4676     }
4677   if (GET_CODE (XEXP (operands[2], 0)) != REG)
4678     val1 = INTVAL (XEXP (XEXP (operands[2], 0), 1));
4679   if (GET_CODE (XEXP (operands[3], 0)) != REG)
4680     val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
4681   arith[0] = operands[0];
4682   if (val1 < val2)
4683     {
4684       arith[1] = ldm[1];
4685       arith[2] = ldm[2];
4686     }
4687   else
4688     {
4689       arith[1] = ldm[2];
4690       arith[2] = ldm[1];
4691     }
4692   if (val1 && val2)
4693     {
4694       rtx ops[3];
4695       ldm[0] = ops[0] = operands[4];
4696       ops[1] = XEXP (XEXP (operands[2], 0), 0);
4697       ops[2] = XEXP (XEXP (operands[2], 0), 1);
4698       output_add_immediate (ops);
4699       if (val1 < val2)
4700         output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
4701       else
4702         output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
4703     }
4704   else if (val1)
4705     {
4706       ldm[0] = XEXP (operands[3], 0);
4707       if (val1 < val2)
4708         output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
4709       else
4710         output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
4711     }
4712   else
4713     {
4714       ldm[0] = XEXP (operands[2], 0);
4715       if (val1 < val2)
4716         output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
4717       else
4718         output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
4719     }
4720   output_asm_insn (\"%I1%?\\t%0, %1, %2\", arith);
4721   return \"\";
4724 [(set_attr "length" "12")
4725  (set_attr "type" "load")])
4727 ;; the arm can support extended pre-inc instructions
4729 ;; In all these cases, we use operands 0 and 1 for the register being
4730 ;; incremented because those are the operands that local-alloc will
4731 ;; tie and these are the pair most likely to be tieable (and the ones
4732 ;; that will benefit the most).
4734 ;; We reject the frame pointer if it occurs anywhere in these patterns since
4735 ;; elimination will cause too many headaches.
4737 (define_insn ""
4738   [(set (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4739                          (match_operand:SI 2 "index_operand" "rJ")))
4740         (match_operand:QI 3 "s_register_operand" "r"))
4741    (set (match_operand:SI 0 "s_register_operand" "=r")
4742         (plus: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   "str%?b\\t%3, [%0, %2]!"
4748 [(set_attr "type" "store1")])
4750 (define_insn ""
4751   [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4752                           (match_operand:SI 2 "s_register_operand" "r")))
4753         (match_operand:QI 3 "s_register_operand" "r"))
4754    (set (match_operand:SI 0 "s_register_operand" "=r")
4755         (minus: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%?b\\t%3, [%0, -%2]!"
4761 [(set_attr "type" "store1")])
4763 (define_insn ""
4764   [(set (match_operand:QI 3 "s_register_operand" "=r")
4765         (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4766                          (match_operand:SI 2 "index_operand" "rJ"))))
4767    (set (match_operand:SI 0 "s_register_operand" "=r")
4768         (plus: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   "ldr%?b\\t%3, [%0, %2]!"
4774 [(set_attr "type" "load")])
4776 (define_insn ""
4777   [(set (match_operand:QI 3 "s_register_operand" "=r")
4778         (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4779                           (match_operand:SI 2 "s_register_operand" "r"))))
4780    (set (match_operand:SI 0 "s_register_operand" "=r")
4781         (minus: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%?b\\t%3, [%0, -%2]!"
4787 [(set_attr "type" "load")])
4789 (define_insn ""
4790   [(set (match_operand:SI 3 "s_register_operand" "=r")
4791         (zero_extend:SI
4792          (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4793                           (match_operand:SI 2 "index_operand" "rJ")))))
4794    (set (match_operand:SI 0 "s_register_operand" "=r")
4795         (plus:SI (match_dup 1) (match_dup 2)))]
4796   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4797    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4798    && (GET_CODE (operands[2]) != REG
4799        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4800   "ldr%?b\\t%3, [%0, %2]!\\t%@ z_extendqisi"
4801 [(set_attr "type" "load")])
4803 (define_insn ""
4804   [(set (match_operand:SI 3 "s_register_operand" "=r")
4805         (zero_extend:SI
4806          (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4807                            (match_operand:SI 2 "s_register_operand" "r")))))
4808    (set (match_operand:SI 0 "s_register_operand" "=r")
4809         (minus:SI (match_dup 1) (match_dup 2)))]
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%?b\\t%3, [%0, -%2]!\\t%@ z_extendqisi"
4815 [(set_attr "type" "load")])
4817 (define_insn ""
4818   [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4819                          (match_operand:SI 2 "index_operand" "rJ")))
4820         (match_operand:SI 3 "s_register_operand" "r"))
4821    (set (match_operand:SI 0 "s_register_operand" "=r")
4822         (plus:SI (match_dup 1) (match_dup 2)))]
4823   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4824    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4825    && (GET_CODE (operands[2]) != REG
4826        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4827   "str%?\\t%3, [%0, %2]!"
4828 [(set_attr "type" "store1")])
4830 (define_insn ""
4831   [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4832                           (match_operand:SI 2 "s_register_operand" "r")))
4833         (match_operand:SI 3 "s_register_operand" "r"))
4834    (set (match_operand:SI 0 "s_register_operand" "=r")
4835         (minus:SI (match_dup 1) (match_dup 2)))]
4836   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4837    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4838    && (GET_CODE (operands[2]) != REG
4839        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4840   "str%?\\t%3, [%0, -%2]!"
4841 [(set_attr "type" "store1")])
4843 (define_insn ""
4844   [(set (match_operand:SI 3 "s_register_operand" "=r")
4845         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4846                          (match_operand:SI 2 "index_operand" "rJ"))))
4847    (set (match_operand:SI 0 "s_register_operand" "=r")
4848         (plus:SI (match_dup 1) (match_dup 2)))]
4849   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4850    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4851    && (GET_CODE (operands[2]) != REG
4852        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4853   "ldr%?\\t%3, [%0, %2]!"
4854 [(set_attr "type" "load")])
4856 (define_insn ""
4857   [(set (match_operand:SI 3 "s_register_operand" "=r")
4858         (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4859                           (match_operand:SI 2 "s_register_operand" "r"))))
4860    (set (match_operand:SI 0 "s_register_operand" "=r")
4861         (minus:SI (match_dup 1) (match_dup 2)))]
4862   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4863    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4864    && (GET_CODE (operands[2]) != REG
4865        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4866   "ldr%?\\t%3, [%0, -%2]!"
4867 [(set_attr "type" "load")])
4869 (define_insn ""
4870   [(set (match_operand:HI 3 "s_register_operand" "=r")
4871         (mem:HI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4872                          (match_operand:SI 2 "index_operand" "rJ"))))
4873    (set (match_operand:SI 0 "s_register_operand" "=r")
4874         (plus:SI (match_dup 1) (match_dup 2)))]
4875   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4876    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4877    && (GET_CODE (operands[2]) != REG
4878        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4879   "ldr%?\\t%3, [%0, %2]!\\t%@ loadhi"
4880 [(set_attr "type" "load")])
4882 (define_insn ""
4883   [(set (match_operand:HI 3 "s_register_operand" "=r")
4884         (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4885                           (match_operand:SI 2 "s_register_operand" "r"))))
4886    (set (match_operand:SI 0 "s_register_operand" "=r")
4887         (minus:SI (match_dup 1) (match_dup 2)))]
4888   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4889    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4890    && (GET_CODE (operands[2]) != REG
4891        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4892   "ldr%?\\t%3, [%0, -%2]!\\t%@ loadhi"
4893 [(set_attr "type" "load")])
4895 (define_insn ""
4896   [(set (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
4897                           [(match_operand:SI 3 "s_register_operand" "r")
4898                            (match_operand:SI 4 "const_shift_operand" "n")])
4899                          (match_operand:SI 1 "s_register_operand" "0")))
4900         (match_operand:QI 5 "s_register_operand" "r"))
4901    (set (match_operand:SI 0 "s_register_operand" "=r")
4902         (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
4903                  (match_dup 1)))]
4904   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4905    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4906    && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4907   "str%?b\\t%5, [%0, %3, %S2]!"
4908 [(set_attr "type" "store1")])
4910 (define_insn ""
4911   [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4912                           (match_operator:SI 2 "shift_operator"
4913                            [(match_operand:SI 3 "s_register_operand" "r")
4914                             (match_operand:SI 4 "const_shift_operand" "n")])))
4915         (match_operand:QI 5 "s_register_operand" "r"))
4916    (set (match_operand:SI 0 "s_register_operand" "=r")
4917         (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4918                                                  (match_dup 4)])))]
4919   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4920    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4921    && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4922   "str%?b\\t%5, [%0, -%3, %S2]!"
4923 [(set_attr "type" "store1")])
4925 (define_insn ""
4926   [(set (match_operand:QI 5 "s_register_operand" "=r")
4927         (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
4928                           [(match_operand:SI 3 "s_register_operand" "r")
4929                            (match_operand:SI 4 "const_shift_operand" "n")])
4930                          (match_operand:SI 1 "s_register_operand" "0"))))
4931    (set (match_operand:SI 0 "s_register_operand" "=r")
4932         (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
4933                  (match_dup 1)))]
4934   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4935    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4936    && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4937   "ldr%?b\\t%5, [%0, %3, %S2]!"
4938 [(set_attr "type" "load")])
4940 (define_insn ""
4941   [(set (match_operand:QI 5 "s_register_operand" "=r")
4942         (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4943                           (match_operator:SI 2 "shift_operator"
4944                            [(match_operand:SI 3 "s_register_operand" "r")
4945                             (match_operand:SI 4 "const_shift_operand" "n")]))))
4946    (set (match_operand:SI 0 "s_register_operand" "=r")
4947         (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4948                                                  (match_dup 4)])))]
4949   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4950    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4951    && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4952   "ldr%?b\\t%5, [%0, -%3, %S2]!"
4953 [(set_attr "type" "load")])
4955 (define_insn ""
4956   [(set (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
4957                           [(match_operand:SI 3 "s_register_operand" "r")
4958                            (match_operand:SI 4 "const_shift_operand" "n")])
4959                          (match_operand:SI 1 "s_register_operand" "0")))
4960         (match_operand:SI 5 "s_register_operand" "r"))
4961    (set (match_operand:SI 0 "s_register_operand" "=r")
4962         (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
4963                  (match_dup 1)))]
4964   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4965    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4966    && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4967   "str%?\\t%5, [%0, %3, %S2]!"
4968 [(set_attr "type" "store1")])
4970 (define_insn ""
4971   [(set (mem:SI (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         (match_operand:SI 5 "s_register_operand" "r"))
4976    (set (match_operand:SI 0 "s_register_operand" "=r")
4977         (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4978                                                  (match_dup 4)])))]
4979   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4980    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4981    && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4982   "str%?\\t%5, [%0, -%3, %S2]!"
4983 [(set_attr "type" "store1")])
4985 (define_insn ""
4986   [(set (match_operand:SI 5 "s_register_operand" "=r")
4987         (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
4988                           [(match_operand:SI 3 "s_register_operand" "r")
4989                            (match_operand:SI 4 "const_shift_operand" "n")])
4990                          (match_operand:SI 1 "s_register_operand" "0"))))
4991    (set (match_operand:SI 0 "s_register_operand" "=r")
4992         (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
4993                  (match_dup 1)))]
4994   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4995    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4996    && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4997   "ldr%?\\t%5, [%0, %3, %S2]!"
4998 [(set_attr "type" "load")])
5000 (define_insn ""
5001   [(set (match_operand:SI 5 "s_register_operand" "=r")
5002         (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5003                           (match_operator:SI 2 "shift_operator"
5004                            [(match_operand:SI 3 "s_register_operand" "r")
5005                             (match_operand:SI 4 "const_shift_operand" "n")]))))
5006    (set (match_operand:SI 0 "s_register_operand" "=r")
5007         (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
5008                                                  (match_dup 4)])))]
5009   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5010    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5011    && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5012   "ldr%?\\t%5, [%0, -%3, %S2]!"
5013 [(set_attr "type" "load")])
5015 (define_insn ""
5016   [(set (match_operand:HI 5 "s_register_operand" "=r")
5017         (mem:HI (plus:SI (match_operator:SI 2 "shift_operator"
5018                           [(match_operand:SI 3 "s_register_operand" "r")
5019                            (match_operand:SI 4 "const_shift_operand" "n")])
5020                          (match_operand:SI 1 "s_register_operand" "0"))))
5021    (set (match_operand:SI 0 "s_register_operand" "=r")
5022         (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
5023                  (match_dup 1)))]
5024   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5025    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5026    && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5027   "ldr%?\\t%5, [%0, %3, %S2]!\\t%@ loadhi"
5028 [(set_attr "type" "load")])
5030 (define_insn ""
5031   [(set (match_operand:HI 5 "s_register_operand" "=r")
5032         (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5033                           (match_operator:SI 2 "shift_operator"
5034                            [(match_operand:SI 3 "s_register_operand" "r")
5035                             (match_operand:SI 4 "const_shift_operand" "n")]))))
5036    (set (match_operand:SI 0 "s_register_operand" "=r")
5037         (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
5038                                                  (match_dup 4)])))]
5039   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5040    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5041    && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5042   "ldr%?\\t%5, [%0, -%3, %S2]!\\t%@ loadhi"
5043 [(set_attr "type" "load")])
5045 ; It can also support extended post-inc expressions, but combine doesn't
5046 ; try these....
5047 ; It doesn't seem worth adding peepholes for anything but the most common
5048 ; cases since, unlike combine, the increment must immediately follow the load
5049 ; for this pattern to match.
5050 ; When loading we must watch to see that the base register isn't trampled by
5051 ; the load.  In such cases this isn't a post-inc expression.
5053 (define_peephole
5054   [(set (mem:QI (match_operand:SI 0 "s_register_operand" "+r"))
5055         (match_operand:QI 2 "s_register_operand" "r"))
5056    (set (match_dup 0)
5057         (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
5058   ""
5059   "strb\\t%2, [%0], %1")
5061 (define_peephole
5062   [(set (match_operand:QI 0 "s_register_operand" "=r")
5063         (mem:QI (match_operand:SI 1 "s_register_operand" "+r")))
5064    (set (match_dup 1)
5065         (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
5066   "REGNO(operands[0]) != REGNO(operands[1])
5067    && (GET_CODE (operands[2]) != REG
5068        || REGNO(operands[0]) != REGNO (operands[2]))"
5069   "ldr%?b\\t%0, [%1], %2")
5071 (define_peephole
5072   [(set (mem:SI (match_operand:SI 0 "s_register_operand" "+r"))
5073         (match_operand:SI 2 "s_register_operand" "r"))
5074    (set (match_dup 0)
5075         (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
5076   ""
5077   "str%?\\t%2, [%0], %1")
5079 (define_peephole
5080   [(set (match_operand:HI 0 "s_register_operand" "=r")
5081         (mem:HI (match_operand:SI 1 "s_register_operand" "+r")))
5082    (set (match_dup 1)
5083         (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
5084   "REGNO(operands[0]) != REGNO(operands[1])
5085    && (GET_CODE (operands[2]) != REG
5086        || REGNO(operands[0]) != REGNO (operands[2]))"
5087   "ldr%?\\t%0, [%1], %2\\t%@ loadhi")
5089 (define_peephole
5090   [(set (match_operand:SI 0 "s_register_operand" "=r")
5091         (mem:SI (match_operand:SI 1 "s_register_operand" "+r")))
5092    (set (match_dup 1)
5093         (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
5094   "REGNO(operands[0]) != REGNO(operands[1])
5095    && (GET_CODE (operands[2]) != REG
5096        || REGNO(operands[0]) != REGNO (operands[2]))"
5097   "ldr%?\\t%0, [%1], %2")
5099 ; This pattern is never tried by combine, so do it as a peephole
5101 (define_peephole
5102   [(set (match_operand:SI 0 "s_register_operand" "=r")
5103         (match_operand:SI 1 "s_register_operand" "r"))
5104    (set (match_operand 2 "cc_register" "")
5105         (compare (match_dup 1) (const_int 0)))]
5106   ""
5107   "sub%?s\\t%0, %1, #0"
5108 [(set_attr "conds" "set")])
5110 ; Peepholes to spot possible load- and store-multiples, if the ordering is
5111 ; reversed, check that the memory references aren't volatile.
5113 (define_peephole
5114   [(set (match_operand:SI 0 "s_register_operand" "=r")
5115         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5116                          (const_int 12))))
5117    (set (match_operand:SI 2 "s_register_operand" "=r")
5118         (mem:SI (plus:SI (match_dup 1) (const_int 8))))
5119    (set (match_operand:SI 3 "s_register_operand" "=r")
5120         (mem:SI (plus:SI (match_dup 1) (const_int 4))))
5121    (set (match_operand:SI 4 "s_register_operand" "=r")
5122         (mem:SI (match_dup 1)))]
5123   "REGNO (operands[0]) > REGNO (operands[2])
5124    && REGNO (operands[2]) > REGNO (operands[3])
5125    && REGNO (operands[3]) > REGNO (operands[4])
5126    && !(REGNO (operands[1]) == REGNO (operands[0])
5127        || REGNO (operands[1]) == REGNO (operands[2])
5128        || REGNO (operands[1]) == REGNO (operands[3])
5129        || REGNO (operands[1]) == REGNO (operands[4]))
5130    && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn)))
5131    && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))
5132    && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn
5133                                          (prev_nonnote_insn (insn)))))
5134    && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn
5135                                          (prev_nonnote_insn 
5136                                           (prev_nonnote_insn (insn))))))"
5137   "ldm%?ia\\t%1, {%4, %3, %2, %0}\\t%@ phole ldm")
5139 (define_peephole
5140   [(set (match_operand:SI 0 "s_register_operand" "=r")
5141         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5142                          (const_int 8))))
5143    (set (match_operand:SI 2 "s_register_operand" "=r")
5144         (mem:SI (plus:SI (match_dup 1) (const_int 4))))
5145    (set (match_operand:SI 3 "s_register_operand" "=r")
5146         (mem:SI (match_dup 1)))]
5147   "REGNO (operands[0]) >  REGNO (operands[2])
5148    && REGNO (operands[2]) > REGNO (operands[3])
5149    && !(REGNO (operands[1]) == REGNO (operands[0])
5150        || REGNO (operands[1]) == REGNO (operands[2])
5151        || REGNO (operands[1]) == REGNO (operands[3]))
5152    && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn)))
5153    && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))
5154    && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn
5155                                          (prev_nonnote_insn (insn)))))"
5156   "ldm%?ia\\t%1, {%3, %2, %0}\\t%@ phole ldm")
5158 (define_peephole
5159   [(set (match_operand:SI 0 "s_register_operand" "=r")
5160         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5161                          (const_int 4))))
5162    (set (match_operand:SI 2 "s_register_operand" "=r")
5163         (mem:SI (match_dup 1)))]
5164   "REGNO (operands[0]) > REGNO (operands[2])
5165    && !(REGNO (operands[1]) == REGNO (operands[0])
5166        || REGNO (operands[1]) == REGNO (operands[2]))
5167    && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn)))
5168    && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))"
5169   "ldm%?ia\\t%1, {%2, %0}\\t%@ phole ldm")
5171 (define_peephole
5172   [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5173                          (const_int 12)))
5174         (match_operand:SI 0 "s_register_operand" "r"))
5175    (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
5176         (match_operand:SI 2 "s_register_operand" "r"))
5177    (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5178         (match_operand:SI 3 "s_register_operand" "r"))
5179    (set (mem:SI (match_dup 1))
5180         (match_operand:SI 4 "s_register_operand" "r"))]
5181   "REGNO (operands[0]) >  REGNO (operands[2])
5182    && REGNO (operands[2]) > REGNO (operands[3])
5183    && REGNO (operands[3]) > REGNO (operands[4])
5184    && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn)))
5185    && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))
5186    && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn
5187                                           (prev_nonnote_insn (insn)))))
5188    && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn
5189                                           (prev_nonnote_insn 
5190                                            (prev_nonnote_insn (insn))))))"
5191   "stm%?ia\\t%1, {%4, %3, %2, %0}\\t%@ phole stm")
5193 (define_peephole
5194   [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5195                          (const_int 8)))
5196         (match_operand:SI 0 "s_register_operand" "r"))
5197    (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5198         (match_operand:SI 2 "s_register_operand" "r"))
5199    (set (mem:SI (match_dup 1))
5200         (match_operand:SI 3 "s_register_operand" "r"))]
5201   "REGNO (operands[0]) >  REGNO (operands[2])
5202    && REGNO (operands[2]) > REGNO (operands[3])
5203    && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn)))
5204    && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))
5205    && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn
5206                                           (prev_nonnote_insn (insn)))))"
5207   "stm%?ia\\t%1, {%3, %2, %0}\\t%@ phole stm")
5209 (define_peephole
5210   [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5211                          (const_int 4)))
5212         (match_operand:SI 0 "s_register_operand" "r"))
5213    (set (mem:SI (match_dup 1))
5214         (match_operand:SI 2 "s_register_operand" "r"))]
5215   "REGNO (operands[0]) >  REGNO (operands[2])
5216    && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn)))
5217    && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))"
5218   "stm%?ia\\t%1, {%2, %0}\\t%@ phole stm")
5220 ;; A call followed by return can be replaced by restoring the regs and
5221 ;; jumping to the subroutine, provided we aren't passing the address of
5222 ;; any of our local variables.  If we call alloca then this is unsafe
5223 ;; since restoring the frame frees the memory, which is not what we want.
5224 ;; Sometimes the return might have been targeted by the final prescan:
5225 ;; if so then emit a propper return insn as well.
5226 ;; Unfortunately, if the frame pointer is required, we don't know if the
5227 ;; current function has any implicit stack pointer adjustments that will 
5228 ;; be restored by the return: we can't therefore do a tail call.
5229 ;; Another unfortunate that we can't handle is if current_function_args_size
5230 ;; is non-zero: in this case elimination of the argument pointer assumed
5231 ;; that lr was pushed onto the stack, so eliminating upsets the offset
5232 ;; calculations.
5234 (define_peephole
5235   [(parallel [(call (mem:SI (match_operand:SI 0 "" "i"))
5236                           (match_operand:SI 1 "general_operand" "g"))
5237                     (clobber (reg:SI 14))])
5238    (return)]
5239   "(GET_CODE (operands[0]) == SYMBOL_REF && USE_RETURN_INSN
5240     && !get_frame_size () && !current_function_calls_alloca
5241     && !frame_pointer_needed && !current_function_args_size)"
5242   "*
5244   extern rtx arm_target_insn;
5245   extern int arm_ccfsm_state, arm_current_cc;
5247   if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
5248   {
5249     arm_current_cc ^= 1;
5250     output_return_instruction (NULL, TRUE);
5251     arm_ccfsm_state = 0;
5252     arm_target_insn = NULL;
5253   }
5255   output_return_instruction (NULL, FALSE);
5256   return \"b%?\\t%a0\";
5258 [(set (attr "conds")
5259       (if_then_else (eq_attr "cpu" "arm6")
5260                     (const_string "clob")
5261                     (const_string "nocond")))
5262  (set_attr "length" "8")])
5264 (define_peephole
5265   [(parallel [(set (match_operand 0 "s_register_operand" "=rf")
5266                    (call (mem:SI (match_operand:SI 1 "" "i"))
5267                          (match_operand:SI 2 "general_operand" "g")))
5268               (clobber (reg:SI 14))])
5269    (return)]
5270   "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN
5271     && !get_frame_size () && !current_function_calls_alloca
5272     && !frame_pointer_needed && !current_function_args_size)"
5273   "*
5275   extern rtx arm_target_insn;
5276   extern int arm_ccfsm_state, arm_current_cc;
5278   if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
5279   {
5280     arm_current_cc ^= 1;
5281     output_return_instruction (NULL, TRUE);
5282     arm_ccfsm_state = 0;
5283     arm_target_insn = NULL;
5284   }
5286   output_return_instruction (NULL, FALSE);
5287   return \"b%?\\t%a1\";
5289 [(set (attr "conds")
5290       (if_then_else (eq_attr "cpu" "arm6")
5291                     (const_string "clob")
5292                     (const_string "nocond")))
5293  (set_attr "length" "8")])
5295 ;; As above but when this function is not void, we must be returning the
5296 ;; result of the called subroutine.
5298 (define_peephole
5299   [(parallel [(set (match_operand 0 "s_register_operand" "=rf")
5300                    (call (mem:SI (match_operand:SI 1 "" "i"))
5301                          (match_operand:SI 2 "general_operand" "g")))
5302               (clobber (reg:SI 14))])
5303    (use (match_dup 0))
5304    (return)]
5305   "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN
5306     && !get_frame_size () && !current_function_calls_alloca
5307     && !frame_pointer_needed && !current_function_args_size)"
5308   "*
5310   extern rtx arm_target_insn;
5311   extern int arm_ccfsm_state, arm_current_cc;
5313   if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
5314   {
5315     arm_current_cc ^= 1;
5316     output_return_instruction (NULL, TRUE);
5317     arm_ccfsm_state = 0;
5318     arm_target_insn = NULL;
5319   }
5321   output_return_instruction (NULL, FALSE);
5322   return \"b%?\\t%a1\";
5324 [(set (attr "conds")
5325       (if_then_else (eq_attr "cpu" "arm6")
5326                     (const_string "clob")
5327                     (const_string "nocond")))
5328  (set_attr "length" "8")])
5330 ;; If calling a subroutine and then jumping back to somewhere else, but not
5331 ;; too far away, then we can set the link register with the branch address
5332 ;; and jump direct to the subroutine.  On return from the subroutine
5333 ;; execution continues at the branch; this avoids a prefetch stall.
5334 ;; We use the length attribute (via short_branch ()) to establish whether or
5335 ;; not this is possible, this is the same asthe sparc does.
5337 (define_peephole
5338   [(parallel[(call (mem:SI (match_operand:SI 0 "" "i"))
5339                    (match_operand:SI 1 "general_operand" "g"))
5340              (clobber (reg:SI 14))])
5341    (set (pc)
5342         (label_ref (match_operand 2 "" "")))]
5343   "GET_CODE (operands[0]) == SYMBOL_REF 
5344    && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
5345    && arm_insn_not_targeted (insn)"
5346   "*
5348   int backward = arm_backwards_branch (INSN_UID (insn),
5349                                        INSN_UID (operands[2]));
5351 #if 0
5352   /* Putting this in means that TARGET_6 code will ONLY run on an arm6 or
5353    * above, leaving it out means that the code will still run on an arm 2 or 3
5354    */
5355   if (TARGET_6)
5356     {
5357       if (backward)
5358         output_asm_insn (\"sub%?\\tlr, pc, #(8 + . -%l2)\", operands);
5359       else
5360         output_asm_insn (\"add%?\\tlr, pc, #(%l2 - . -8)\", operands);
5361     }
5362   else
5363 #endif
5364     {
5365       output_asm_insn (\"mov%?\\tlr, pc\\t%@ protect cc\", operands);
5366       if (backward)
5367         output_asm_insn (\"sub%?\\tlr, lr, #(4 + . -%l2)\", operands);
5368       else
5369         output_asm_insn (\"add%?\\tlr, lr, #(%l2 - . -4)\", operands);
5370     }
5371   return \"b%?\\t%a0\";
5373 [(set (attr "conds")
5374       (if_then_else (eq_attr "cpu" "arm6")
5375                     (const_string "clob")
5376                     (const_string "nocond")))
5377  (set (attr "length")
5378       (if_then_else (eq_attr "cpu" "arm6")
5379                     (const_int 8)
5380                     (const_int 12)))])
5382 (define_peephole
5383   [(parallel[(set (match_operand:SI 0 "s_register_operand" "=r")
5384                   (call (mem:SI (match_operand:SI 1 "" "i"))
5385                         (match_operand:SI 2 "general_operand" "g")))
5386              (clobber (reg:SI 14))])
5387    (set (pc)
5388         (label_ref (match_operand 3 "" "")))]
5389   "GET_CODE (operands[0]) == SYMBOL_REF
5390    && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
5391    && arm_insn_not_targeted (insn)"
5392   "*
5394   int backward = arm_backwards_branch (INSN_UID (insn),
5395                                        INSN_UID (operands[3]));
5397 #if 0
5398   /* Putting this in means that TARGET_6 code will ONLY run on an arm6 or
5399    * above, leaving it out means that the code will still run on an arm 2 or 3
5400    */
5401   if (TARGET_6)
5402     {
5403       if (backward)
5404         output_asm_insn (\"sub%?\\tlr, pc, #(8 + . -%l3)\", operands);
5405       else
5406         output_asm_insn (\"add%?\\tlr, pc, #(%l3 - . -8)\", operands);
5407     }
5408   else
5409 #endif
5410     {
5411       output_asm_insn (\"mov%?\\tlr, pc\\t%@ protect cc\", operands);
5412       if (backward)
5413         output_asm_insn (\"sub%?\\tlr, lr, #(4 + . -%l3)\", operands);
5414       else
5415         output_asm_insn (\"add%?\\tlr, lr, #(%l3 - . -4)\", operands);
5416     }
5417   return \"b%?\\t%a1\";
5419 [(set (attr "conds")
5420       (if_then_else (eq_attr "cpu" "arm6")
5421                     (const_string "clob")
5422                     (const_string "nocond")))
5423  (set (attr "length")
5424       (if_then_else (eq_attr "cpu" "arm6")
5425                     (const_int 8)
5426                     (const_int 12)))])
5428 (define_split
5429   [(set (pc)
5430         (if_then_else (match_operator 0 "comparison_operator"
5431                        [(match_operator:SI 1 "shift_operator"
5432                          [(match_operand:SI 2 "s_register_operand" "r")
5433                           (match_operand:SI 3 "nonmemory_operand" "rn")])
5434                         (match_operand:SI 4 "s_register_operand" "r")])
5435                       (label_ref (match_operand 5 "" ""))
5436                       (pc)))
5437    (clobber (reg 24))]
5438   ""
5439   [(set (reg:CC 24)
5440         (compare:CC (match_dup 4)
5441                     (match_op_dup 1 [(match_dup 2) (match_dup 3)])))
5442    (set (pc)
5443         (if_then_else (match_op_dup 0 [(reg 24) (const_int 0)])
5444                       (label_ref (match_dup 5))
5445                       (pc)))]
5446   "
5447   operands[0] = gen_rtx (swap_condition (GET_CODE (operands[0])), VOIDmode,
5448                          operands[1], operands[2]);
5451 (define_split
5452   [(set (match_operand:SI 0 "s_register_operand" "")
5453         (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
5454                        (const_int 0))
5455                 (neg:SI (match_operator:SI 2 "comparison_operator"
5456                          [(match_operand:SI 3 "s_register_operand" "")
5457                           (match_operand:SI 4 "arm_rhs_operand" "")]))))
5458    (clobber (match_operand:SI 5 "s_register_operand" ""))]
5459   ""
5460   [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
5461    (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
5462                               (match_dup 5)))]
5463   "")
5465 ;; This pattern can be used because cc_noov mode implies that the following
5466 ;; branch will be an equality (EQ or NE), so the sign extension is not
5467 ;; needed.  Combine doesn't eliminate these because by the time it sees the
5468 ;; branch it no-longer knows that the data came from memory.
5470 (define_insn ""
5471   [(set (reg:CC_NOOV 24)
5472         (compare:CC_NOOV
5473          (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "m") 0)
5474                     (const_int 24))
5475          (match_operand 1 "immediate_operand" "I")))
5476    (clobber (match_scratch:SI 2 "=r"))]
5477   "((unsigned long) INTVAL (operands[1]))
5478    == (((unsigned long) INTVAL (operands[1])) >> 24) << 24"
5479   "*
5480   operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
5481   output_asm_insn (\"ldr%?b\\t%2, %0\", operands);
5482   output_asm_insn (\"cmp%?\\t%2, %1\", operands);
5483   return \"\";
5485 [(set_attr "conds" "set")
5486  (set_attr "length" "8")
5487  (set_attr "type" "load")])
5489 (define_expand "save_stack_nonlocal"
5490   [(match_operand:DI 0 "memory_operand" "")
5491    (match_operand:SI 1 "s_register_operand" "")]
5492   ""
5493   "
5495   /* We also need to save the frame pointer for non-local gotos */
5496   emit_move_insn (operand_subword (operands[0], 0, 0, DImode),
5497                   hard_frame_pointer_rtx);
5498   emit_move_insn (operand_subword (operands[0], 1, 0, DImode), operands[1]);
5499   DONE;
5502 (define_expand "restore_stack_nonlocal"
5503   [(match_operand:SI 0 "s_register_operand" "")
5504    (match_operand:DI 1 "memory_operand" "")]
5505   ""
5506   "
5508   /* Restore the frame pointer first, the stack pointer second. */
5509   emit_move_insn (operands[0], operand_subword (operands[1], 1, 0, DImode));
5510   emit_move_insn (hard_frame_pointer_rtx, operand_subword (operands[1], 0, 0,
5511                                                            DImode));
5512   DONE;
5515 ;; This split is only used during output to reduce the number of patterns
5516 ;; that need assembler instructions adding to them.  We allowed the setting
5517 ;; of the conditions to be implicit during rtl generation so that
5518 ;; the conditional compare patterns would work.  However this conflicts to
5519 ;; some extend with the conditional data operations, so we have to split them
5520 ;; up again here.
5522 (define_split
5523   [(set (match_operand:SI 0 "s_register_operand" "")
5524         (if_then_else:SI (match_operator 1 "comparison_operator"
5525                           [(match_operand 2 "" "") (match_operand 3 "" "")])
5526                          (match_operand 4 "" "")
5527                          (match_operand 5 "" "")))
5528    (clobber (reg 24))]
5529   "reload_completed"
5530   [(set (match_dup 6) (match_dup 7))
5531    (set (match_dup 0) 
5532         (if_then_else:SI (match_op_dup 1 [(match_dup 6) (const_int 0)])
5533                          (match_dup 4)
5534                          (match_dup 5)))]
5535   "
5537   enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), operands[2],
5538                                            operands[3]);
5540   operands[6] = gen_rtx (REG, mode, 24);
5541   operands[7] = gen_rtx (COMPARE, mode, operands[2], operands[3]);
5546 (define_insn ""
5547   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5548         (if_then_else:SI (match_operator 4 "comparison_operator"
5549                           [(match_operand 3 "cc_register" "") (const_int 0)])
5550                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
5551                          (not:SI
5552                           (match_operand:SI 2 "s_register_operand" "r,r"))))]
5553   ""
5554   "@
5555   mvn%D4\\t%0, %2
5556   mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
5557 [(set_attr "conds" "use")
5558  (set_attr "length" "4,8")])
5560 ;; The next two patterns occur when an AND operation is followed by a
5561 ;; scc insn sequence 
5563 (define_insn ""
5564   [(set (match_operand:SI 0 "s_register_operand" "=r")
5565         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
5566                          (const_int 1)
5567                          (match_operand:SI 2 "immediate_operand" "n")))]
5568   ""
5569   "*
5570   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
5571   output_asm_insn (\"ands\\t%0, %1, %2\", operands);
5572   return \"mvnne\\t%0, #0\";
5574 [(set_attr "conds" "clob")
5575  (set_attr "length" "8")])
5577 (define_insn ""
5578   [(set (match_operand:SI 0 "s_register_operand" "=r")
5579         (not:SI
5580          (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
5581                           (const_int 1)
5582                           (match_operand:SI 2 "immediate_operand" "n"))))]
5583   ""
5584   "*
5585   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
5586   output_asm_insn (\"tst\\t%1, %2\", operands);
5587   output_asm_insn (\"mvneq\\t%0, #0\", operands);
5588   return \"movne\\t%0, #0\";
5590 [(set_attr "conds" "clob")
5591  (set_attr "length" "12")])