Clean up indentation.
[platform/upstream/gcc.git] / gcc / config / arm / arm.md
1 ;;- Machine description Acorn RISC Machine for GNU compiler
2 ;;  Copyright (C) 1991 Free Software Foundation, Inc.
3 ;;  Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
4 ;;             and Martin Simmons (@harleqn.co.uk).
5
6 ;; This file is part of GNU CC.
7
8 ;; GNU CC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 2, or (at your option)
11 ;; any later version.
12
13 ;; GNU CC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
17
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GNU CC; see the file COPYING.  If not, write to
20 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
21
22 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
23
24 ;; Every template must be output by arm_output_asm_insn, since this keeps
25 ;; track of the offset of labels within the text segment.  This is needed to
26 ;; to be able to (correctly) output instructions for loading a value from a
27 ;; function's constant pool, since different instructions are needed when the
28 ;; constant pool is more than 4095 bytes away from the PC.
29 \f
30 ;; Addition insns.
31
32 (define_insn "adddi3"
33   [(set (match_operand:DI 0 "di_operand" "=r")
34         (plus:DI (match_operand:DI 1 "di_operand" "%r")
35                  (match_operand:DI 2 "di_operand" "r")))]
36   ""
37   "*
38   arm_output_asm_insn (\"adds\\t%0, %1, %2\", operands);
39   return (arm_output_asm_insn (\"adc\\t%R0, %R1, %R2\", operands));
40 ")
41
42 (define_insn "addsi3"
43   [(set (match_operand:SI 0 "register_operand" "=r,r")
44         (plus:SI (match_operand:SI 1 "register_operand" "r,r")
45                  (match_operand:SI 2 "general_operand" "r,n")))]
46   ""
47   "*
48   switch (which_alternative)
49     {
50     case 0:
51       return (arm_output_asm_insn (\"add\\t%0, %1, %2\", operands));
52     case 1:
53       return (output_add_immediate (operands));
54     }
55 ")
56
57 (define_insn "addsf3"
58   [(set (match_operand:SF 0 "register_operand" "=f")
59         (plus:SF (match_operand:SF 1 "register_operand" "f")
60                  (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
61   ""
62   "*
63   return (arm_output_asm_insn (\"adfs\\t%0, %1, %2\", operands));
64 ")
65
66 (define_insn "adddf3"
67   [(set (match_operand:DF 0 "register_operand" "=f")
68         (plus:DF (match_operand:DF 1 "register_operand" "f")
69                  (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
70   ""
71   "*
72   return (arm_output_asm_insn (\"adfd\\t%0, %1, %2\", operands));
73 ")
74
75 (define_insn "subdi3"
76   [(set (match_operand:DI 0 "di_operand" "=r")
77         (minus:DI (match_operand:DI 1 "di_operand" "%r")
78                   (match_operand:DI 2 "di_operand" "r")))]
79   ""
80   "*
81   arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands);
82   return (arm_output_asm_insn (\"sbc\\t%R0, %R1, %R2\", operands));
83 ")
84
85 (define_insn "subsi3"
86   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
87         (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
88                   (match_operand:SI 2 "general_operand" "r,n,r")))]
89   ""
90   "*
91   switch (which_alternative)
92     {
93     case 0:
94       return (arm_output_asm_insn (\"sub\\t%0, %1, %2\", operands));
95     case 1:
96       operands[2] = gen_rtx (CONST_INT, VOIDmode, -INTVAL (operands[2]));
97       return (output_add_immediate (operands));
98     case 2:
99       return (arm_output_asm_insn (\"rsb\\t%0, %2, %1\", operands));
100     }
101 ")
102
103 (define_insn "subsf3"
104   [(set (match_operand:SF 0 "register_operand" "=f,f")
105         (minus:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
106                   (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
107   ""
108   "*
109   switch (which_alternative)
110     {
111     case 0:
112       return (arm_output_asm_insn (\"sufs\\t%0, %1, %2\", operands));
113     case 1:
114       return (arm_output_asm_insn (\"rsfs\\t%0, %2, %1\", operands));
115     }
116 ")
117
118 (define_insn "subdf3"
119   [(set (match_operand:DF 0 "register_operand" "=f,f")
120         (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
121       (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
122   ""
123   "*
124   switch (which_alternative)
125     {
126     case 0:
127       return (arm_output_asm_insn (\"sufd\\t%0, %1, %2\", operands));
128     case 2:
129       return (arm_output_asm_insn (\"rsfd\\t%0, %2, %1\", operands));
130     }
131 ")
132 \f
133 ;; Multiplication insns
134
135 ;; The `&' is too strict, but at least generates correct code.
136 (define_insn "mulsi3"
137   [(set (match_operand:SI 0 "register_operand" "=&r")
138         (mult:SI (match_operand:SI 1 "register_operand" "%r")
139                  (match_operand:SI 2 "register_operand" "r")))]
140   ""
141   "*
142   if (REGNO (operands[0]) == REGNO (operands[1]))
143     return (arm_output_asm_insn (\"mul\\t%0, %2, %1\", operands));
144   else
145     return (arm_output_asm_insn (\"mul\\t%0, %1, %2\", operands));
146 ")
147
148 ;; Unnamed templates to match MLA instruction.
149
150 (define_insn ""
151   [(set (match_operand:SI 0 "register_operand" "=&r")
152         (plus:SI
153           (mult:SI (match_operand:SI 1 "register_operand" "%r")
154                    (match_operand:SI 2 "register_operand" "r"))
155           (match_operand:SI 3 "register_operand" "r")))]
156   ""
157   "*
158   if (REGNO (operands[0]) == REGNO (operands[1]))
159     return (arm_output_asm_insn (\"mla\\t%0, %2, %1, %3\", operands));
160   else
161     return (arm_output_asm_insn (\"mla\\t%0, %1, %2, %3\", operands));
162 ")
163
164 (define_insn ""
165   [(set (match_operand:SI 0 "register_operand" "=&r")
166         (plus:SI
167           (match_operand:SI 3 "register_operand" "r")
168           (mult:SI (match_operand:SI 1 "register_operand" "%r")
169                    (match_operand:SI 2 "register_operand" "r"))))]
170   ""
171   "*
172   if (REGNO (operands[0]) == REGNO (operands[1]))
173     return (arm_output_asm_insn (\"mla\\t%0, %2, %1, %3\", operands));
174   else
175     return (arm_output_asm_insn (\"mla\\t%0, %1, %2, %3\", operands));
176 ")
177
178 (define_insn "mulsf3"
179   [(set (match_operand:SF 0 "register_operand" "=f")
180         (mult:SF (match_operand:SF 1 "register_operand" "f")
181                  (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
182   ""
183   "*return (arm_output_asm_insn (\"mufs\\t%0, %1, %2\", operands));")
184
185 (define_insn "muldf3"
186   [(set (match_operand:DF 0 "register_operand" "=f")
187         (mult:DF (match_operand:DF 1 "register_operand" "f")
188                  (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
189   ""
190   "*
191   return (arm_output_asm_insn (\"mufd\\t%0, %1, %2\", operands));
192 ")
193 \f
194 ;; Division insns
195
196 (define_insn "divsf3"
197   [(set (match_operand:SF 0 "register_operand" "=f,f")
198         (div:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
199                 (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
200   ""
201   "*
202   switch (which_alternative)
203     {
204     case 0:
205       return (arm_output_asm_insn (\"dvfs\\t%0, %1, %2\", operands));
206     case 1:
207       return (arm_output_asm_insn (\"rdfs\\t%0, %2, %1\", operands));
208     }
209 ")
210
211 (define_insn "divdf3"
212   [(set (match_operand:DF 0 "register_operand" "=f,f")
213         (div:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
214                 (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
215   ""
216   "*
217   switch (which_alternative)
218     {
219     case 0:
220       return (arm_output_asm_insn (\"dvfd\\t%0, %1, %2\", operands));
221     case 1:
222       return (arm_output_asm_insn (\"rdfd\\t%0, %2, %1\", operands));
223     }
224 ")
225 \f
226 ;; Modulo insns
227
228 (define_insn "modsf3"
229   [(set (match_operand:SF 0 "register_operand" "=f")
230         (mod:SF (match_operand:SF 1 "register_operand" "f")
231                 (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
232   ""
233   "*
234   return (arm_output_asm_insn (\"rmfs\\t%0, %1, %2\", operands));
235 ")
236
237 (define_insn "moddf3"
238   [(set (match_operand:DF 0 "register_operand" "=f")
239         (mod:DF (match_operand:DF 1 "register_operand" "f")
240                 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
241   ""
242   "*
243   return (arm_output_asm_insn (\"rmfd\\t%0, %1, %2\", operands));
244 ")
245 \f
246 ;; Boolean and,ior,xor insns
247
248 (define_insn "anddi3"
249   [(set (match_operand:DI 0 "di_operand" "=r")
250         (and:DI (match_operand:DI 1 "di_operand" "%r")
251                 (match_operand:DI 2 "di_operand" "r")))]
252   ""
253   "*
254   arm_output_asm_insn (\"and\\t%0, %1, %2\", operands);
255   return (arm_output_asm_insn (\"and\\t%R0, %R1, %R2\", operands));
256 ")
257
258 (define_insn "andsi3"
259   [(set (match_operand:SI 0 "register_operand" "=r")
260         (and:SI (match_operand:SI 1 "register_operand" "r")
261                 (match_operand:SI 2 "arm_rhs_operand" "rI")))]
262   ""
263   "*
264   return (arm_output_asm_insn (\"and\\t%0, %1, %2\", operands));
265 ")
266
267 (define_insn "andcbsi3"
268   [(set (match_operand:SI 0 "register_operand" "=r")
269         (and:SI (match_operand:SI 1 "register_operand" "r")
270                 (not:SI (match_operand:SI 2 "arm_rhs_operand" "rI"))))]
271   ""
272   "*
273   return (arm_output_asm_insn (\"bic\\t%0, %1, %2\", operands));
274 ")
275
276 (define_insn "iordi3"
277   [(set (match_operand:DI 0 "di_operand" "=r")
278         (ior:DI (match_operand:DI 1 "di_operand" "%r")
279                 (match_operand:DI 2 "di_operand" "r")))]
280   ""
281   "*
282   arm_output_asm_insn (\"orr\\t%0, %1, %2\", operands);
283   return (arm_output_asm_insn (\"orr\\t%R0, %R1, %R2\", operands));
284 ")
285
286 (define_insn "iorsi3"
287   [(set (match_operand:SI 0 "register_operand" "=r,r")
288         (ior:SI (match_operand:SI 1 "register_operand" "r,r")
289                 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
290   ""
291   "*
292   switch (which_alternative)
293     {
294     case 0:
295       return (arm_output_asm_insn (\"orr\\t%0, %1, %2\", operands));
296     case 1:
297       return (output_multi_immediate (operands,
298                                       \"orr\\t%0, %1, %2\", \"orr\\t%0, %0, %2\",
299                                       2, INTVAL (operands[2])));
300     }
301 ")
302
303 (define_insn "xorsi3"
304   [(set (match_operand:SI 0 "register_operand" "=r,r")
305         (xor:SI (match_operand:SI 1 "register_operand" "r,r")
306                 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
307   ""
308   "*
309   switch (which_alternative)
310     {
311     case 0:
312       return (arm_output_asm_insn (\"eor\\t%0, %1, %2\", operands));
313     case 1:
314       return (output_multi_immediate (operands,
315                                       \"eor\\t%0, %1, %2\", \"eor\\t%0, %0, %2\",
316                                       2, INTVAL (operands[2])));
317     }
318 ")
319 \f
320 ;; Shift and rotation insns
321
322 (define_insn "ashlsi3"
323   [(set (match_operand:SI 0 "register_operand" "=r")
324         (ashift:SI (match_operand:SI 1 "register_operand" "r")
325                    (match_operand:SI 2 "general_operand" "rn")))]
326   ""
327   "*
328   return (output_shifted_move (ASHIFT, operands));
329 ")
330
331 (define_insn "ashrsi3"
332   [(set (match_operand:SI 0 "register_operand" "=r")
333         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
334                      (match_operand:SI 2 "general_operand" "rn")))]
335   ""
336   "*
337   return (output_shifted_move (ASHIFTRT, operands));
338 ")
339
340 ;; lshlsi3 is not defined because shift counts cannot be negative
341 ;; An unnamed pattern is needed for expansion of zero_extend.
342
343 (define_insn ""
344   [(set (match_operand:SI 0 "register_operand" "=r")
345         (lshift:SI (match_operand:SI 1 "register_operand" "r")
346                    (match_operand:SI 2 "general_operand" "rn")))]
347   ""
348   "*
349   return (output_shifted_move (LSHIFT, operands));
350 ")
351
352 (define_insn "lshrsi3"
353   [(set (match_operand:SI 0 "register_operand" "=r")
354         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
355                      (match_operand:SI 2 "general_operand" "rn")))]
356   ""
357   "*
358   return (output_shifted_move (LSHIFTRT, operands));
359 ")
360
361 ;; rotlsi3 is not defined yet to see what happens
362
363 (define_insn "rotrsi3"
364   [(set (match_operand:SI 0 "register_operand" "=r,r")
365         (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
366                      (match_operand:SI 2 "general_operand" "r,n")))]
367   ""
368   "*
369   switch (which_alternative)
370     {
371     case 0:
372       return (arm_output_asm_insn (\"mov\\t%0, %1,ror %2\", operands));
373     case 1:
374       if (INTVAL(operands[2]) > 31)
375         operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) % 32);
376       return (arm_output_asm_insn (\"mov\\t%0, %1,ror%2\", operands));
377     }
378 ")
379 \f
380 ;; Unary arithmetic insns
381
382 (define_insn "negdi2"
383   [(set (match_operand:DI 0 "di_operand" "=r")
384         (neg:DI (match_operand:DI 1 "di_operand" "r")))]
385   ""
386   "*
387   arm_output_asm_insn (\"rsb\\t%0, %1, #0\", operands);
388   return (arm_output_asm_insn (\"rsc\\t%R0, %R1, #0\", operands));
389 ")
390
391 (define_insn "negsi2"
392   [(set (match_operand:SI 0 "register_operand" "=r")
393         (neg:SI (match_operand:SI 1 "register_operand" "r")))]
394   ""
395   "*
396   return (arm_output_asm_insn (\"rsb\\t%0, %1, #0\", operands));
397 ")
398
399 (define_insn "negsf2"
400   [(set (match_operand:SF 0 "register_operand" "=f")
401         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
402   ""
403   "*
404   return (arm_output_asm_insn (\"mnfs\\t%0, %1\", operands));
405 ")
406
407 (define_insn "negdf2"
408   [(set (match_operand:DF 0 "register_operand" "=f")
409         (neg:DF (match_operand:DF 1 "register_operand" "f")))]
410   ""
411   "*
412   return (arm_output_asm_insn (\"mnfd\\t%0, %1\", operands));
413 ")
414
415 (define_insn "abssf2"
416   [(set (match_operand:SF 0 "register_operand" "=f")
417          (abs:SF (match_operand:SF 1 "register_operand" "f")))]
418   ""
419   "*
420   return (arm_output_asm_insn (\"abss\\t%0, %1\", operands));
421 ")
422
423 (define_insn "absdf2"
424   [(set (match_operand:DF 0 "register_operand" "=f")
425         (abs:DF (match_operand:DF 1 "register_operand" "f")))]
426   ""
427   "*
428   return (arm_output_asm_insn (\"absd\\t%0, %1\", operands));
429 ")
430
431 (define_insn "sqrtsf2"
432   [(set (match_operand:SF 0 "register_operand" "=f")
433         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
434   ""
435   "*
436   return (arm_output_asm_insn (\"sqts\\t%0, %1\", operands));
437 ")
438
439 (define_insn "sqrtdf2"
440   [(set (match_operand:DF 0 "register_operand" "=f")
441         (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
442   ""
443   "*
444   return (arm_output_asm_insn (\"sqtd\\t%0, %1\", operands));
445 ")
446
447 (define_insn "one_cmplsi2"
448   [(set (match_operand:SI 0 "register_operand" "=r")
449         (not:SI (match_operand:SI 1 "register_operand" "r")))]
450   ""
451   "*
452   return (arm_output_asm_insn (\"mvn\\t%0, %1\", operands));
453 ")
454 \f
455 ;; Fixed <--> Floating conversion insns
456
457 (define_insn "floatsisf2"
458   [(set (match_operand:SF 0 "register_operand" "=f")
459         (float:SF (match_operand:SI 1 "register_operand" "r")))]
460   ""
461   "*
462   return (arm_output_asm_insn (\"flts\\t%0, %1\", operands));
463 ")
464
465 (define_insn "floatsidf2"
466   [(set (match_operand:DF 0 "register_operand" "=f")
467         (float:DF (match_operand:SI 1 "register_operand" "r")))]
468   ""
469   "*
470   return (arm_output_asm_insn (\"fltd\\t%0, %1\", operands));
471 ")
472
473 ;; Truncation insns
474
475 (define_insn "truncdfsf2"
476   [(set (match_operand:SF 0 "register_operand" "=f")
477         (float_truncate:SF
478             (match_operand:DF 1 "register_operand" "f")))]
479   ""
480   "*
481   return (arm_output_asm_insn (\"mvfs\\t%0, %1\", operands));
482 ")
483 \f
484 ;; Zero extension instructions.
485
486 (define_expand "zero_extendhisi2"
487   [(set (match_operand:SI 0 "register_operand" "")
488         (ashift:SI (match_operand:HI 1 "register_operand" "")
489                    (const_int 16)))
490    (set (match_dup 0)
491         (lshiftrt:SI (match_dup 0) (const_int 16)))]
492   ""
493   "
494   if (GET_CODE (operands[1]) == SUBREG)
495       operands[1] = gen_rtx (SUBREG, SImode, SUBREG_REG (operands[1]),
496                              SUBREG_WORD (operands[1]));
497   else
498       operands[1] = gen_rtx (SUBREG, SImode, operands[1], 0);
499 ")
500
501 (define_insn "zero_extendqihi2"
502   [(set (match_operand:HI 0 "register_operand" "=r")
503         (zero_extend:HI
504          (match_operand:QI 1 "register_operand" "r")))]
505   ""
506   "*
507   return (arm_output_asm_insn (\"and\\t%0, %1, #255\\t@ zero_extendqihi2\", operands));
508 ")
509
510 (define_insn "zero_extendqisi2"
511   [(set (match_operand:SI 0 "register_operand" "=r,r")
512         (zero_extend:SI
513          (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
514   ""
515   "*
516   switch (which_alternative)
517     {
518     case 0:
519       return (arm_output_asm_insn (\"and\\t%0, %1, #255\\t@ zero_extendqisi2\", operands));
520     case 1:
521       return (arm_output_asm_insn (\"ldrb\\t%0, %1\\t@ zero_extendqisi2\", operands));
522     }
523 ")
524
525 ;; Note that the ones starting from HImode come before those for QImode so
526 ;; that a constant operand will match HImode, not QImode.
527
528 (define_expand "extendhisi2"
529   [(set (match_operand:SI 0 "register_operand" "")
530         (ashift:SI (match_operand:HI 1 "register_operand" "")
531                    (const_int 16)))
532    (set (match_dup 0)
533         (ashiftrt:SI (match_dup 0) (const_int 16)))]
534   ""
535   "
536   if (GET_CODE (operands[1]) == SUBREG)
537       operands[1] = gen_rtx (SUBREG, SImode, SUBREG_REG (operands[1]),
538                              SUBREG_WORD (operands[1]));
539   else
540       operands[1] = gen_rtx (SUBREG, SImode, operands[1], 0);
541 ")
542
543 ;; XXX Is this ever used?
544
545 (define_insn "extendqihi2"
546   [(set (match_operand:HI 0 "register_operand" "=r")
547         (sign_extend:SI
548          (match_operand:QI 1 "register_operand" "r")))]
549   ""
550   "*
551   arm_output_asm_insn (\"mov\\t%0, %1, lsl#24\\t@ extendqihi\", operands);
552   return (arm_output_asm_insn (\"mov\\t%0, %0, asr#24\", operands));
553 ")
554
555
556 (define_expand "extendqisi2"
557   [(set (match_operand:SI 0 "register_operand" "")
558         (ashift:SI (match_operand:QI 1 "register_operand" "")
559                    (const_int 24)))
560    (set (match_dup 0)
561         (ashiftrt:SI (match_dup 0) (const_int 24)))]
562   ""
563   "
564   if (GET_CODE (operands[1]) == SUBREG)
565       operands[1] = gen_rtx (SUBREG, SImode, SUBREG_REG (operands[1]),
566                              SUBREG_WORD(operands[1]));
567   else
568       operands[1] = gen_rtx (SUBREG, SImode, operands[1], 0);
569 ")
570
571 (define_insn "extendsfdf2"
572   [(set (match_operand:DF 0 "register_operand" "=f")
573         (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
574   ""
575   "*
576   return (arm_output_asm_insn (\"mvfd\\t%0, %1\", operands));
577 ")
578 \f
579 ;; Move insns (including loads and stores)
580
581 ;; XXX Just some ideas about movti.
582
583 ;;(define_expand "loadti"
584 ;;  [(set (match_operand:TI 0 "register_operand" "")
585 ;;      (mem:TI (match_operand:SI 1 "address_operand" "")))]
586 ;;  "" "")
587
588 ;;(define_expand "storeti"
589 ;;  [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
590 ;;      (match_operand:TI 1 "register_operand" ""))]
591 ;;  "" "")
592
593 ;;(define_expand "movti"
594 ;;  [(set (match_operand:TI 0 "general_operand" "")
595 ;;      (match_operand:TI 1 "general_operand" ""))]
596 ;;  ""
597 ;;  "
598 ;;{
599 ;;  rtx insn;
600 ;;
601 ;;  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
602 ;;    operands[1] = copy_to_reg (operands[1]);
603 ;;  if (GET_CODE (operands[0]) == MEM)
604 ;;    insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
605 ;;  else if (GET_CODE (operands[1]) == MEM)
606 ;;    insn = gen_loadti (operands[0], XEXP (operands[1], 0));
607 ;;  else
608 ;;    FAIL;
609 ;;
610 ;;  emit_insn (insn);
611 ;;  DONE;
612 ;;}")
613
614 ;; Recognise garbage generated above.
615
616 ;;(define_insn ""
617 ;;  [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
618 ;;      (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
619 ;;  ""
620 ;;  "*
621 ;;  {
622 ;;    register mem = (which_alternative < 3);
623 ;;    register char *template;
624 ;;
625 ;;    operands[mem] = XEXP (operands[mem], 0);
626 ;;    switch (which_alternative)
627 ;;      {
628 ;;      case 0: template = \"ldmdb\\t%1!, %M0\"; break;
629 ;;      case 1: template = \"ldmia\\t%1!, %M0\"; break;
630 ;;      case 2: template = \"ldmia\\t%1, %M0\"; break;
631 ;;      case 3: template = \"stmdb\\t%0!, %M1\"; break;
632 ;;      case 4: template = \"stmia\\t%0!, %M1\"; break;
633 ;;      case 5: template = \"stmia\\t%0, %M1\"; break;
634 ;;      }
635 ;;    return (arm_output_asm_insn (template, operands));
636 ;;  }")
637
638
639 (define_insn "movdi"
640   [(set (match_operand:DI 0 "di_operand" "=r,r,r,o,r")
641         (match_operand:DI 1 "di_operand" "r,n,o,r,F"))]
642   ""
643   "*
644   return (output_move_double (operands));
645 ")
646
647 (define_insn "movsi"
648   [(set (match_operand:SI 0 "general_operand" "=r,r,r,m")
649         (match_operand:SI 1 "general_operand"  "r,n,m,r"))]
650   ""
651   "*
652   switch (which_alternative)
653     {
654     case 0:
655       return (arm_output_asm_insn (\"mov\\t%0, %1\", operands));
656     case 1:
657       return (output_mov_immediate (operands));
658     case 2:
659       if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
660           &&  CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0)))
661         return (arm_output_llc (operands));
662       else
663         return (arm_output_asm_insn (\"ldr\\t%0, %1\", operands));
664     case 3:
665       return (arm_output_asm_insn (\"str\\t%1, %0\", operands));
666     }
667 ")
668
669 ;; XXX The movhi stuff isn't as correct or as nice as it could be...
670
671 ;; Subroutine to load a half word into a register from memory.
672 ;; Operand 0 is the destination register (HImode).
673 ;; Operand 1 is the source address (SImode).
674 ;; Operand 2 is a temporary (SImode).
675
676 ;;(define_expand "loadhi"
677 ;;  [;; load the whole word (ARM realigns it if not on word boundary)
678 ;;   (set (match_operand:SI 2 "register_operand" "")
679 ;;        (mem:SI (match_operand:SI 1 "address_operand" "")))
680 ;;   ;; quietly forget the upper 16 bits
681 ;;   (set (match_operand:HI 0 "register_operand" "")
682 ;;        (subreg:HI (match_dup 2) 0))]
683 ;;  ""
684 ;;  ""
685 ;;)
686
687 ;; Load op0 from mem:op1.  Subroutine in case we're reloading and the normal
688 ;; loadhi is not allowed.
689
690 ;;(define_expand "reloadhi"
691 ;;  [(set (reg:SI 10)
692 ;;      (mem:SI (match_operand:SI 1 "address_operand" "")))
693 ;;   (set (match_operand:HI 0 "register_operand" "")
694 ;;      (subreg:HI (reg:SI 10) 0))]
695 ;;  "" "")
696
697 ;; Store op0 into mem:op1.  Subroutine in case we're reloading and the normal
698 ;; storehi is not allowed.
699
700 (define_expand "restorehi"
701   [(set (mem:QI (match_operand:SI 1 "address_operand" ""))
702         (truncate:QI (match_operand:HI 0 "register_operand" "")))
703    (set (reg:HI 10)
704         (ashiftrt:HI (match_dup 0) (const_int 8)))
705    (set (mem:QI (plus:SI (match_dup 1) (const_int 1)))
706         (truncate:QI (reg:HI 10)))]
707   "" "")
708
709 ;; Subroutine to store a half word from a register into memory.
710 ;; Operand 0 is the source register (HImode)
711 ;; Operand 1 is the destination address (SImode)
712 ;; Operand 2 is a temporary (SImode).
713 ;; Operand 3 is a temporary (SImode).
714 ;; Operand 4 is a temporary (SImode).
715
716 (define_expand "storehi"
717   [;; compute the address into a register
718    (set (match_operand:SI 2 "register_operand" "")
719         (match_operand:SI 1 "address_operand" ""))
720    ;; get the half word into a full word register
721    (set (match_operand:SI 3 "register_operand" "")
722         (match_operand:HI 0 "register_operand" ""))
723    ;; store the low byte
724    (set (mem:QI (match_dup 2))
725         (truncate:QI (match_dup 3)))
726    ;; extract the high byte
727    (set (match_operand:SI 4 "register_operand" "")
728         (ashiftrt:SI (match_dup 3) (const_int 8)))
729    ;; store the high byte
730    (set (mem:QI (plus (match_dup 2) (const_int 1)))
731         (truncate:QI (match_dup 4)))]
732   ""
733   "
734   operands[0] = gen_lowpart (SImode, operands[0]);
735 ")
736
737 ;; Subroutine to store a half word integer constant into memory.
738 ;; Operand 0 is the constant
739 ;; Operand 1 is the destination address (SImode)
740 ;; Operand 2 is a temporary (SImode).
741 ;; Operand 3 is a temporary (QImode).
742 ;; Operand 4 is a temporary (QImode).
743 ;; Operand 5 is a local CONST_INT.
744
745 (define_expand "storeinthi"
746   [;; compute the address into a register
747    (set (match_operand:SI 2 "register_operand" "")
748         (match_operand:SI 1 "address_operand" ""))
749    ;; load the low byte
750    (set (match_operand:QI 3 "register_operand" "")
751         (match_operand:SI 0 "" ""))
752    ;; store the low byte
753    (set (mem:QI (match_dup 2))
754         (match_dup 3))
755    ;; load the high byte
756    (set (match_operand:QI 4 "register_operand" "")
757         (match_dup 5))
758    ;; store the high byte
759    (set (mem:QI (plus (match_dup 2) (const_int 1)))
760         (match_dup 4))]
761   ""
762   "
763     {
764       int value = INTVAL(operands[0]);
765
766       operands[0] = gen_rtx(CONST_INT, VOIDmode, value & 255);
767       operands[5] = gen_rtx(CONST_INT, VOIDmode,(value>>8) & 255);
768     }
769 ")
770
771 (define_expand "movhi"
772   [(set (match_operand:HI 0 "general_operand" "")
773         (match_operand:HI 1 "general_operand" ""))]
774   ""
775   "
776 {
777   rtx insn;
778
779   if (reload_in_progress || reload_completed)
780     {
781       if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == REG)
782         insn = gen_restorehi (operands[1], XEXP (operands[0], 0));
783       else
784         insn = gen_rtx (SET, VOIDmode, operands[0], operands[1]);
785     }
786   else
787     {
788       if (GET_CODE (operands[0]) == MEM)
789         {
790           if (GET_CODE (operands[1]) == MEM)
791             operands[1] = copy_to_reg (operands[1]);
792
793           if (GET_CODE (operands[1]) == CONST_INT)
794             {
795               insn = gen_storeinthi (operands[1], XEXP (operands[0], 0),
796                                      gen_reg_rtx (SImode),
797                                      gen_reg_rtx (QImode),
798                                      gen_reg_rtx (QImode));
799             }
800           else
801             {
802               insn = gen_storehi (operands[1], XEXP (operands[0], 0),
803                                   gen_reg_rtx (SImode),
804                                   gen_reg_rtx (SImode),
805                                   gen_reg_rtx (SImode));
806             }
807         }
808 #if 0
809       else if (GET_CODE (operands[1]) == MEM)
810         {
811           insn = gen_loadhi (operands[0], XEXP (operands[1], 0),
812                              gen_reg_rtx (SImode));
813         }
814 #endif
815       else
816         insn = gen_rtx (SET, VOIDmode, operands[0], operands[1]);
817     }
818
819   emit_insn (insn);
820   DONE;
821 }")
822
823 ;; Pattern to recognise insn generated default case above
824
825 (define_insn ""
826   [(set (match_operand:HI 0 "general_operand" "=r,r,r,m")
827         (match_operand:HI 1 "general_operand"  "r,n,m,r"))]
828   ""
829   "*
830   switch (which_alternative)
831     {
832       case 0: return (arm_output_asm_insn (\"mov\\t%0, %1\\t@movhi\", operands));
833       case 1: return (output_mov_immediate (operands));
834       case 2: return (arm_output_asm_insn (\"ldr\\t%0, %1\\t@movhi\", operands));
835       case 3: return (arm_output_asm_insn (\"str\\t%1, %0\\t@movhi\", operands));
836     }
837 ")
838
839 (define_insn "movqi"
840   [(set (match_operand:QI 0 "general_operand" "=r,r,r,m")
841         (match_operand:QI 1 "general_operand" "r,n,m,r"))]
842   ""
843   "*
844   switch (which_alternative)
845     {
846     case 0:
847       return (arm_output_asm_insn (\"mov\\t%0, %1\", operands));
848     case 1:
849       return (output_mov_immediate (operands));
850     case 2:
851       return (arm_output_asm_insn (\"ldrb\\t%0, %1\", operands));
852     case 3:
853       return (arm_output_asm_insn (\"strb\\t%1, %0\", operands));
854     }
855   
856 ")
857
858 (define_insn "movsf"
859   [(set (match_operand:SF 0 "general_operand" "=f,f,m,f,r,r")
860         (match_operand:SF 1 "general_operand" "fG,m,f,r,f,r"))]
861   ""
862   "*
863   switch (which_alternative)
864     {
865     case 0:
866       return (arm_output_asm_insn (\"mvfs\\t%0, %1\", operands));
867     case 1:
868       return (arm_output_asm_insn (\"ldfs\\t%0, %1\", operands));
869     case 2:
870       return (arm_output_asm_insn (\"stfs\\t%1, %0\", operands));
871     case 3:
872       arm_output_asm_insn(\"stmfd\\tsp!, {%1}\", operands);
873       return (arm_output_asm_insn (\"ldfs\\t%0, [sp],#4\", operands));
874     case 4:
875       arm_output_asm_insn(\"stfs\\t%1, [sp,#-4]!\", operands);
876       return (arm_output_asm_insn (\"ldmfd\\tsp!, {%0}\", operands));
877     case 5:
878       return (arm_output_asm_insn (\"mov\\t%0, %1\", operands));
879   }
880 ")
881
882 (define_insn "movdf"
883   [(set (match_operand:DF 0 "general_operand" "=f,f,m,f,r,r")
884         (match_operand:DF 1 "general_operand" "fG,m,f,r,f,r"))]
885   ""
886   "*
887   switch (which_alternative)
888     {
889       case 0: return (arm_output_asm_insn (\"mvfd\\t%0, %1\", operands));
890       case 1: return (arm_output_asm_insn (\"ldfd\\t%0, %1\", operands));
891       case 2: return (arm_output_asm_insn (\"stfd\\t%1, %0\", operands));
892       case 3: return (output_mov_double_fpu_from_arm (operands));
893       case 4: return (output_mov_double_arm_from_fpu (operands));
894       case 5: return (output_move_double (operands));
895     }
896 ")
897 \f
898 ;; Comparison and test insns
899
900 (define_insn "cmpsi"
901   [(set (cc0)
902         (compare (match_operand:SI 0 "register_operand" "r")
903                  (match_operand:SI 1 "arm_rhs_operand" "rI")))]
904   ""
905   "*
906   return (arm_output_asm_insn (\"cmp\\t%0, %1\", operands));
907 ")
908
909 (define_insn "tstsi"
910   [(set (cc0) (match_operand:SI 0 "register_operand" "r"))]
911   ""
912   "*
913   return (arm_output_asm_insn (\"cmp\\t%0, #0\", operands));
914 ")
915
916 (define_insn ""
917   [(set (cc0)
918         (compare (match_operand:SI 0 "register_operand" "r")
919                  (neg:SI (match_operand:SI 1 "arm_rhs_operand" "rI"))))]
920   ""
921   "*
922   return (arm_output_asm_insn (\"cmn\\t%0, %1\", operands));
923 ")
924
925 (define_insn "cmpsf"
926   [(set (cc0)
927         (compare (match_operand:SF 0 "register_operand" "f")
928                  (match_operand:SF 1 "fpu_rhs_operand" "fG")))]
929   ""
930   "*
931   return (arm_output_asm_insn (\"cmf\\t%0, %1\", operands));
932 ")
933
934 (define_insn "cmpdf"
935   [(set (cc0)
936         (compare (match_operand:DF 0 "register_operand" "f")
937                  (match_operand:DF 1 "fpu_rhs_operand" "fG")))]
938   ""
939   "*
940   return (arm_output_asm_insn (\"cmf\\t%0, %1\", operands));
941 ")
942 \f
943 ;; Conditional branch insns
944
945 (define_insn "beq"
946   [(set (pc)
947         (if_then_else (eq (cc0) (const_int 0))
948                       (label_ref (match_operand 0 "" ""))
949                       (pc)))]
950   ""
951   "*
952   return (arm_output_asm_insn (\"beq\\t%l0\", operands));
953 ")
954
955 (define_insn "bne"
956   [(set (pc)
957         (if_then_else (ne (cc0) (const_int 0))
958                       (label_ref (match_operand 0 "" ""))
959                       (pc)))]
960   ""
961   "*
962   return (arm_output_asm_insn (\"bne\\t%l0\", operands));
963 ")
964
965 (define_insn "bgt"
966   [(set (pc)
967         (if_then_else (gt (cc0) (const_int 0))
968                       (label_ref (match_operand 0 "" ""))
969                       (pc)))]
970   ""
971   "*
972   return (arm_output_asm_insn (\"bgt\\t%l0\", operands));
973 ")
974
975 (define_insn "ble"
976   [(set (pc)
977         (if_then_else (le (cc0) (const_int 0))
978                       (label_ref (match_operand 0 "" ""))
979                       (pc)))]
980   ""
981   "*
982   return (arm_output_asm_insn (\"ble\\t%l0\", operands));
983 ")
984
985 (define_insn "bge"
986   [(set (pc)
987         (if_then_else (ge (cc0) (const_int 0))
988                       (label_ref (match_operand 0 "" ""))
989                       (pc)))]
990   ""
991   "*
992   return (arm_output_asm_insn (\"bge\\t%l0\", operands));
993 ")
994
995 (define_insn "blt"
996   [(set (pc)
997         (if_then_else (lt (cc0) (const_int 0))
998                       (label_ref (match_operand 0 "" ""))
999                       (pc)))]
1000   ""
1001   "*
1002   return (arm_output_asm_insn (\"blt\\t%l0\", operands));
1003 ")
1004
1005 (define_insn "bgtu"
1006   [(set (pc)
1007         (if_then_else (gtu (cc0) (const_int 0))
1008                       (label_ref (match_operand 0 "" ""))
1009                       (pc)))]
1010   ""
1011   "*
1012   return (arm_output_asm_insn (\"bhi\\t%l0\", operands));
1013 ")
1014
1015 (define_insn "bleu"
1016   [(set (pc)
1017         (if_then_else (leu (cc0) (const_int 0))
1018                       (label_ref (match_operand 0 "" ""))
1019                       (pc)))]
1020   ""
1021   "*
1022   return (arm_output_asm_insn (\"bls\\t%l0\", operands));
1023 ")
1024
1025 (define_insn "bgeu"
1026   [(set (pc)
1027         (if_then_else (geu (cc0) (const_int 0))
1028                       (label_ref (match_operand 0 "" ""))
1029                       (pc)))]
1030   ""
1031   "*
1032   return (arm_output_asm_insn (\"bhs\\t%l0\", operands));
1033 ")
1034
1035 (define_insn "bltu"
1036   [(set (pc)
1037         (if_then_else (ltu (cc0) (const_int 0))
1038                       (label_ref (match_operand 0 "" ""))
1039                       (pc)))]
1040   ""
1041   "*
1042   return (arm_output_asm_insn (\"blo\\t%l0\", operands));
1043 ")
1044 \f
1045 ;; Inverted conditional branch insns
1046
1047 (define_insn ""
1048   [(set (pc)
1049         (if_then_else (eq (cc0) (const_int 0))
1050                       (pc)
1051                       (label_ref (match_operand 0 "" ""))))]
1052   ""
1053   "*
1054   return (arm_output_asm_insn (\"bne\\t%l0\", operands));
1055 ")
1056
1057 (define_insn ""
1058   [(set (pc)
1059         (if_then_else (ne (cc0) (const_int 0))
1060                       (pc)
1061                       (label_ref (match_operand 0 "" ""))))]
1062   ""
1063   "*
1064   return (arm_output_asm_insn (\"beq\\t%l0\", operands));
1065 ")
1066
1067 (define_insn ""
1068   [(set (pc)
1069         (if_then_else (gt (cc0) (const_int 0))
1070                       (pc)
1071                       (label_ref (match_operand 0 "" ""))))]
1072   ""
1073   "*
1074   return (arm_output_asm_insn (\"ble\\t%l0\", operands));
1075 ")
1076
1077 (define_insn ""
1078   [(set (pc)
1079         (if_then_else (le (cc0) (const_int 0))
1080                       (pc)
1081                       (label_ref (match_operand 0 "" ""))))]
1082   ""
1083   "*
1084   return (arm_output_asm_insn (\"bgt\\t%l0\", operands));
1085 ")
1086
1087 (define_insn ""
1088   [(set (pc)
1089         (if_then_else (ge (cc0) (const_int 0))
1090                       (pc)
1091                       (label_ref (match_operand 0 "" ""))))]
1092   ""
1093   "*
1094   return (arm_output_asm_insn (\"blt\\t%l0\", operands));
1095 ")
1096
1097 (define_insn ""
1098   [(set (pc)
1099         (if_then_else (lt (cc0) (const_int 0))
1100                       (pc)
1101                       (label_ref (match_operand 0 "" ""))))]
1102   ""
1103   "*
1104   return (arm_output_asm_insn (\"bge\\t%l0\", operands));
1105 ")
1106
1107 (define_insn ""
1108   [(set (pc)
1109         (if_then_else (gtu (cc0) (const_int 0))
1110                       (pc)
1111                       (label_ref (match_operand 0 "" ""))))]
1112   ""
1113   "*
1114   return (arm_output_asm_insn (\"bls\\t%l0\", operands));
1115 ")
1116
1117 (define_insn ""
1118   [(set (pc)
1119         (if_then_else (leu (cc0) (const_int 0))
1120                       (pc)
1121                       (label_ref (match_operand 0 "" ""))))]
1122   ""
1123   "*
1124   return (arm_output_asm_insn (\"bhi\\t%l0\", operands));
1125 ")
1126
1127 (define_insn ""
1128   [(set (pc)
1129         (if_then_else (geu (cc0) (const_int 0))
1130                       (pc)
1131                       (label_ref (match_operand 0 "" ""))))]
1132   ""
1133   "*
1134   return (arm_output_asm_insn (\"blo\\t%l0\", operands));
1135 ")
1136
1137 (define_insn ""
1138   [(set (pc)
1139         (if_then_else (ltu (cc0) (const_int 0))
1140                       (pc)
1141                       (label_ref (match_operand 0 "" ""))))]
1142   ""
1143   "*
1144   return (arm_output_asm_insn (\"bhs\\t%l0\", operands));
1145 ")
1146 \f
1147 ;; Jump and linkage insns
1148 ;; `return' is still a jump-to-epilogue...
1149
1150 (define_insn "jump"
1151   [(set (pc)
1152         (label_ref (match_operand 0 "" "")))]
1153   ""
1154   "*
1155   return (arm_output_asm_insn (\"b\\t%l0\", operands));
1156 ")
1157
1158 (define_insn "call"
1159   [(call (match_operand 0 "memory_operand" "m")
1160          (match_operand 1 "general_operand" "g"))
1161    (clobber (reg:SI 14))]
1162   ""
1163   "*
1164   return (output_call (operands));
1165 ")
1166
1167 (define_insn "call_value"
1168   [(set (match_operand 0 "" "=rf")
1169         (call (match_operand 1 "memory_operand" "m")
1170         (match_operand 2 "general_operand" "g")))
1171    (clobber (reg:SI 14))]
1172   ""
1173   "*
1174   return (output_call (&operands[1]));
1175 ")
1176
1177 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
1178 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
1179
1180 (define_insn ""
1181   [(call (mem:SI (match_operand:SI 0 "" "i"))
1182          (match_operand:SI 1 "general_operand" "g"))
1183    (clobber (reg:SI 14))]
1184   "GET_CODE (operands[0]) == SYMBOL_REF"
1185   "*
1186   return (arm_output_asm_insn (\"bl\\t%a0\", operands));
1187 ")
1188
1189 (define_insn ""
1190   [(set (match_operand 0 "register_operand" "=rf")
1191         (call (mem:SI (match_operand:SI 1 "" "i"))
1192         (match_operand:SI 2 "general_operand" "g")))
1193    (clobber (reg:SI 14))]
1194   "GET_CODE(operands[1]) == SYMBOL_REF"
1195   "*
1196   return (arm_output_asm_insn (\"bl\\t%a1\", operands));
1197 ")
1198
1199 (define_insn "tablejump"
1200   [(set (pc)
1201         (match_operand:SI 0 "register_operand" "r"))
1202    (use (label_ref (match_operand 1 "" "")))]
1203   ""
1204   "*
1205   return (arm_output_asm_insn (\"mov\\tpc, %0\\t@ table jump, label %l1\", operands));
1206 ")
1207
1208 (define_insn "indirect_jump"
1209   [(set (pc)
1210         (match_operand:SI 0 "register_operand" "r"))]
1211   ""
1212   "*
1213   return (arm_output_asm_insn (\"mov\\tpc, %0\\t@ indirect jump\", operands));
1214 ")
1215 \f
1216 ;; Misc insns
1217
1218 (define_insn "nop"
1219   [(const_int 0)]
1220   ""
1221   "*
1222   return (arm_output_asm_insn (\"mov\\tr0, r0\\t@ nop\", operands));
1223 ")
1224 \f
1225 ;; Patterns to allow combination of arithmetic, cond code and shifts
1226
1227 ;(define_insn ""
1228 ;  [(set (match_operand:SI 0 "register_operand" "=r")
1229 ;        (match_operator:SI 1 "shiftable_operator"
1230 ;          [(match_operand:SI 2 "register_operand" "r")
1231 ;           (match_operator:SI 3 "shift_operator"
1232 ;             [(match_operand:SI 4 "register_operand" "r")
1233 ;             (match_operand:SI 5 "nonmemory_operand" "rn")])]))]
1234 ;  ""
1235 ;  "*
1236 ;  return (output_arithmetic_with_shift (operands, FALSE, FALSE));
1237 ;  "
1238 ;)
1239
1240 ;(define_insn ""
1241 ;  [(set (match_operand:SI 0 "register_operand" "=r")
1242 ;        (match_operator:SI 1 "shiftable_operator"
1243 ;          [(match_operator:SI 3 "shift_operator"
1244 ;             [(match_operand:SI 4 "register_operand" "r")
1245 ;              (match_operand:SI 5 "nonmemory_operand" "rI")])
1246 ;           (match_operand:SI 2 "register_operand" "r")]))]
1247 ;  ""
1248 ;  "*
1249 ;  return (output_arithmetic_with_shift (operands, TRUE, FALSE));
1250 ;")
1251 \f
1252 ;; Patterns to allow combination of arithmetic and multiplication
1253
1254 ;(define_insn ""
1255 ;  [(set (match_operand:SI 0 "register_operand" "=r")
1256 ;        (match_operator:SI 1 "shiftable_operator"
1257 ;          [(match_operand:SI 2 "register_operand" "r")
1258 ;             (mult:SI
1259 ;               (match_operand:SI 3 "register_operand" "r")
1260 ;               (match_operand:SI 4 "power_of_two_operand" "n"))]))]
1261 ;  ""
1262 ;  "*
1263 ;  return (output_arithmetic_with_immediate_multiply (operands, FALSE));
1264 ;")
1265
1266 ; Uncomment this to show combiner problem (see ../COMBINER-PROBLEM).
1267 ;(define_insn ""
1268 ;  [(set (match_operand:SI 0 "register_operand" "=r")
1269 ;        (match_operator:SI 1 "shiftable_operator"
1270 ;         [(mult:SI
1271 ;           (match_operand:SI 3 "register_operand" "r")
1272 ;           (match_operand:SI 4 "power_of_two_operand" "n"))
1273 ;          (match_operand:SI 2 "register_operand" "r")]))]
1274 ;  ""
1275 ;  "*
1276 ;  return (output_arithmetic_with_immediate_multiply (operands, TRUE));
1277 ;")
1278 \f
1279 ;; Peephole optimizations.
1280
1281 ;; When testing a bitset smaller than 9 bits for (un)equality, a
1282 ;; shift/and/cmp/b{eq,ne} sequence can be replaced by one tst and the same
1283 ;; branch sequence.
1284
1285 ;;(define_peephole
1286 ;;  [(set (match_operand:SI 0 "register_operand" "=r")
1287 ;;      (lshiftrt:SI (match_dup 0)
1288 ;;                   (match_operand 1 "immediate_operand" "")))
1289 ;;   (set (match_dup 0)
1290 ;;      (and:SI (match_dup 0)
1291 ;;              (match_operand 2 "immediate_operand" "")))
1292 ;;   (set (cc0) (match_dup 0))
1293 ;;   (set (pc)
1294 ;;      (if_then_else (ne (cc0) (const_int 0))
1295 ;;                    (label_ref (match_operand 3 "" ""))
1296 ;;                    (pc)))]
1297 ;;  "dead_or_set_p (PREV_INSN (insn), operands[0])
1298 ;;   && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[1]) == CONST_INT
1299 ;;   && const_ok_for_arm (INTVAL (operands[2]) << INTVAL (operands[1]))"
1300 ;;  "*
1301 ;;  operands[2] = gen_rtx (CONST_INT, VOIDmode,
1302 ;;                         INTVAL (operands[2]) << INTVAL (operands[1]));
1303 ;;  arm_output_asm_insn (\"tst\\t%0, %2\\t\\t@ ph test bitfield\", operands);
1304 ;;  return (arm_output_asm_insn (\"bne\\t%l3\", operands));
1305 ;;")
1306
1307 ;;(define_peephole
1308 ;;  [(set (match_operand:SI 0 "register_operand" "=r")
1309 ;;      (lshiftrt:SI (match_dup 0)
1310 ;;                   (match_operand 1 "immediate_operand" "")))
1311 ;;   (set (match_dup 0)
1312 ;;      (and:SI (match_dup 0)
1313 ;;              (match_operand 2 "immediate_operand" "")))
1314 ;;   (set (cc0) (match_dup 0))
1315 ;;   (set (pc)
1316 ;;      (if_then_else (ne (cc0) (const_int 0))
1317 ;;                    (pc)
1318 ;;                    (label_ref (match_operand 3 "" ""))))]
1319 ;;  "dead_or_set_p (prev_real_insn (insn), operands[0])
1320 ;;   && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[1]) == CONST_INT
1321 ;;   && const_ok_for_arm (INTVAL (operands[2]) << INTVAL (operands[1]))"
1322 ;;  "*
1323 ;;  operands[2] = gen_rtx (CONST_INT, VOIDmode,
1324 ;;                         INTVAL (operands[2]) << INTVAL (operands[1]));
1325 ;;  arm_output_asm_insn (\"tst\\t%0, %2\\t\\t@ ph test bitfield\", operands);
1326 ;;  return (arm_output_asm_insn (\"beq\\t%l3\", operands));
1327 ;;")
1328
1329 ;; This allows negative constants to be compared since GCC appears not to try
1330 ;; converting them with a NEG.
1331
1332 ;;(define_peephole
1333 ;;  [(set (match_operand:SI 2 "register_operand" "=r")
1334 ;;        (match_operand:SI 1 "immediate_operand" "n"))
1335 ;;   (set (cc0)
1336 ;;        (compare (match_operand:SI 0 "register_operand" "r")
1337 ;;                 (match_dup 1)))]
1338 ;;  "const_ok_for_arm (-INTVAL (operands[1]))
1339 ;;   && dead_or_set_p (prev_real_insn (insn), operands[0])"
1340 ;;  "*
1341 ;;  operands[1] = gen_rtx (CONST_INT, VOIDmode, -INTVAL (operands[1]));
1342 ;;  return (arm_output_asm_insn (\"cmn\\t%0, %1\\t\\t@ ph negate comparison\", operands));
1343 ;;")
1344 \f
1345 ;; Local variables:
1346 ;; mode:emacs-lisp
1347 ;; eval: (setq comment-start ";; ")
1348 ;; eval: (setq comment-end "")
1349 ;; eval: (setq comment-start-skip ";;+ *")
1350 ;; eval: (set-syntax-table (copy-sequence (syntax-table)))
1351 ;; eval: (modify-syntax-entry ?[ "(]")
1352 ;; eval: (modify-syntax-entry ?] ")[")
1353 ;; eval: (modify-syntax-entry ?{ "(}")
1354 ;; eval: (modify-syntax-entry ?} "){")
1355 ;; End: