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