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