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