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