OSDN Git Service

* config/h8300/h8300.h (MASK_*): New.
[pf3gnuchains/gcc-fork.git] / gcc / config / mn10300 / mn10300.md
1 ;; GCC machine description for Matsushita MN10300
2 ;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001
3 ;; Free Software Foundation, Inc.
4 ;; Contributed by Jeff Law (law@cygnus.com).
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, 59 Temple Place - Suite 330,
21 ;; Boston, MA 02111-1307, USA.
22
23 ;; The original PO technology requires these to be ordered by speed,
24 ;; so that assigner will pick the fastest.
25
26 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
27
28 ;; Condition code settings.
29 ;; none - insn does not affect cc
30 ;; none_0hit - insn does not affect cc but it does modify operand 0
31 ;;      This attribute is used to keep track of when operand 0 changes.
32 ;;      See the description of NOTICE_UPDATE_CC for more info.
33 ;; set_znv - insn sets z,n,v to usable values; c is unusable.
34 ;; set_zn  - insn sets z,n to usable values; v,c are unusable.
35 ;; compare - compare instruction
36 ;; invert -- like compare, but flags are inverted.
37 ;; clobber - value of cc is unknown
38 (define_attr "cc" "none,none_0hit,set_znv,set_zn,compare,clobber,invert"
39   (const_string "clobber"))
40 \f
41 ;; ----------------------------------------------------------------------
42 ;; MOVE INSTRUCTIONS
43 ;; ----------------------------------------------------------------------
44
45 ;; movqi
46
47 (define_expand "movqi"
48   [(set (match_operand:QI 0 "general_operand" "")
49         (match_operand:QI 1 "general_operand" ""))]
50   ""
51   "
52 {
53   /* One of the ops has to be in a register */
54   if (!register_operand (operand0, QImode)
55       && !register_operand (operand1, QImode))
56     operands[1] = copy_to_mode_reg (QImode, operand1);
57 }")
58
59 (define_insn ""
60   [(set (match_operand:QI 0 "nonimmediate_operand" "=d*x*a,d*x,d*x*a,d*x*a,m")
61         (match_operand:QI 1 "general_operand" "0,I,d*xai,m,d*xa"))]
62   "TARGET_AM33
63    && (register_operand (operands[0], QImode)
64        || register_operand (operands[1], QImode))"
65   "*
66 {
67   switch (which_alternative)
68     {
69     case 0:
70       return \"nop\";
71     case 1:
72       return \"clr %0\";
73     case 2:
74       if (GET_CODE (operands[1]) == CONST_DOUBLE)
75         {
76           rtx xoperands[2];
77           xoperands[0] = operands[0];
78           xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
79           output_asm_insn (\"mov %1,%0\", xoperands);
80           return \"\";
81         }
82
83       if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
84           && GET_CODE (operands[1]) == CONST_INT)
85         {
86           HOST_WIDE_INT val = INTVAL (operands[1]);
87
88           if (((val & 0x80) && ! (val & 0xffffff00))
89               || ((val & 0x800000) && ! (val & 0xff000000)))
90             return \"movu %1,%0\";
91         }
92       return \"mov %1,%0\";
93     case 3:
94     case 4:
95       return \"movbu %1,%0\";
96     default:
97       abort ();
98     }
99 }"
100   [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit")])
101
102 (define_insn ""
103   [(set (match_operand:QI 0 "nonimmediate_operand" "=d*a,d,d*a,d,m")
104         (match_operand:QI 1 "general_operand" "0,I,dai,m,d"))]
105   "register_operand (operands[0], QImode)
106    || register_operand (operands[1], QImode)"
107   "*
108 {
109   switch (which_alternative)
110     {
111     case 0:
112       return \"nop\";
113     case 1:
114       return \"clr %0\";
115     case 2:
116       if (GET_CODE (operands[1]) == CONST_DOUBLE)
117         {
118           rtx xoperands[2];
119           xoperands[0] = operands[0];
120           xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
121           output_asm_insn (\"mov %1,%0\", xoperands);
122           return \"\";
123         }
124
125       return \"mov %1,%0\";
126     case 3:
127     case 4:
128       return \"movbu %1,%0\";
129     default:
130       abort ();
131     }
132 }"
133   [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit")])
134
135 ;; movhi
136
137 (define_expand "movhi"
138   [(set (match_operand:HI 0 "general_operand" "")
139         (match_operand:HI 1 "general_operand" ""))]
140   ""
141   "
142 {
143   /* One of the ops has to be in a register */
144   if (!register_operand (operand1, HImode)
145       && !register_operand (operand0, HImode))
146     operands[1] = copy_to_mode_reg (HImode, operand1);
147 }")
148
149 (define_insn ""
150   [(set (match_operand:HI 0 "nonimmediate_operand" "=d*x*a,d*x,d*x*a,d*x*a,m")
151         (match_operand:HI 1 "general_operand" "0,I,d*x*ai,m,d*x*a"))]
152   "TARGET_AM33
153    && (register_operand (operands[0], HImode)
154        || register_operand (operands[1], HImode))"
155   "*
156 {
157   switch (which_alternative)
158     {
159     case 0:
160       return \"nop\";
161     case 1:
162       return \"clr %0\";
163     case 2:
164       if (GET_CODE (operands[1]) == CONST_DOUBLE)
165         {
166           rtx xoperands[2];
167           xoperands[0] = operands[0];
168           xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
169           output_asm_insn (\"mov %1,%0\", xoperands);
170           return \"\";
171         }
172
173       if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
174           && GET_CODE (operands[1]) == CONST_INT)
175         {
176           HOST_WIDE_INT val = INTVAL (operands[1]);
177
178           if (((val & 0x80) && ! (val & 0xffffff00))
179               || ((val & 0x800000) && ! (val & 0xff000000)))
180             return \"movu %1,%0\";
181         }
182       return \"mov %1,%0\";
183     case 3:
184     case 4:
185       return \"movhu %1,%0\";
186     default:
187       abort ();
188     }
189 }"
190   [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit")])
191
192 (define_insn ""
193   [(set (match_operand:HI 0 "nonimmediate_operand" "=d*a,d,d*a,d,m")
194         (match_operand:HI 1 "general_operand" "0,I,dai,m,d"))]
195   "register_operand (operands[0], HImode)
196    || register_operand (operands[1], HImode)"
197   "*
198 {
199   switch (which_alternative)
200     {
201     case 0:
202       return \"nop\";
203     case 1:
204       return \"clr %0\";
205     case 2:
206       if (GET_CODE (operands[1]) == CONST_DOUBLE)
207         {
208           rtx xoperands[2];
209           xoperands[0] = operands[0];
210           xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
211           output_asm_insn (\"mov %1,%0\", xoperands);
212           return \"\";
213         }
214       return \"mov %1,%0\";
215     case 3:
216     case 4:
217       return \"movhu %1,%0\";
218     default:
219       abort ();
220     }
221 }"
222   [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit")])
223
224 ;; movsi and helpers
225
226 ;; We use this to handle addition of two values when one operand is the
227 ;; stack pointer and the other is a memory reference of some kind.  Reload
228 ;; does not handle them correctly without this expander.
229 (define_expand "reload_insi"
230   [(set (match_operand:SI 0 "register_operand" "=a")
231         (match_operand:SI 1 "impossible_plus_operand" ""))
232    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
233   ""
234   "
235 {
236   if (XEXP (operands[1], 0) == stack_pointer_rtx)
237     {
238       if (GET_CODE (XEXP (operands[1], 1)) == SUBREG
239           && (GET_MODE_SIZE (GET_MODE (XEXP (operands[1], 1)))
240               > GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (operands[1], 1))))))
241         emit_move_insn (operands[2],
242                         gen_rtx_ZERO_EXTEND
243                         (GET_MODE (XEXP (operands[1], 1)),
244                          SUBREG_REG (XEXP (operands[1], 1))));
245       else
246         emit_move_insn (operands[2], XEXP (operands[1], 1));
247       emit_move_insn (operands[0], XEXP (operands[1], 0));
248     }
249   else
250     {
251       if (GET_CODE (XEXP (operands[1], 0)) == SUBREG
252           && (GET_MODE_SIZE (GET_MODE (XEXP (operands[1], 0)))
253               > GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (operands[1], 0))))))
254         emit_move_insn (operands[2],
255                         gen_rtx_ZERO_EXTEND
256                         (GET_MODE (XEXP (operands[1], 0)),
257                          SUBREG_REG (XEXP (operands[1], 0))));
258       else
259         emit_move_insn (operands[2], XEXP (operands[1], 0));
260       emit_move_insn (operands[0], XEXP (operands[1], 1));
261     }
262   emit_insn (gen_addsi3 (operands[0], operands[0], operands[2]));
263   DONE;
264 }")
265
266 (define_expand "movsi"
267   [(set (match_operand:SI 0 "general_operand" "")
268         (match_operand:SI 1 "general_operand" ""))]
269   ""
270   "
271 {
272   /* One of the ops has to be in a register */
273   if (!register_operand (operand1, SImode)
274       && !register_operand (operand0, SImode))
275     operands[1] = copy_to_mode_reg (SImode, operand1);
276 }")
277
278 (define_insn ""
279   [(set (match_operand:SI 0 "nonimmediate_operand"
280                                 "=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax,axR,!*y")
281         (match_operand:SI 1 "general_operand"
282                                 "0,0,I,I,dx,ax,dx,ax,dixm,aixm,dixm,aixm,!*y,axR"))]
283   "register_operand (operands[0], SImode)
284    || register_operand (operands[1], SImode)"
285   "*
286 {
287   switch (which_alternative)
288     {
289     case 0:
290     case 1:
291       return \"nop\";
292     case 2:
293       return \"clr %0\";
294     case 3:
295     case 4:
296     case 5:
297     case 6:
298     case 7:
299     case 8:
300     case 9:
301     case 10:
302     case 11:
303     case 12:
304     case 13:
305       if (GET_CODE (operands[1]) == CONST_DOUBLE)
306         {
307           rtx xoperands[2];
308           xoperands[0] = operands[0];
309           xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
310           output_asm_insn (\"mov %1,%0\", xoperands);
311           return \"\";
312         }
313
314       if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
315           && GET_CODE (operands[1]) == CONST_INT)
316         {
317           HOST_WIDE_INT val = INTVAL (operands[1]);
318
319           if (((val & 0x80) && ! (val & 0xffffff00))
320               || ((val & 0x800000) && ! (val & 0xff000000)))
321             return \"movu %1,%0\";
322         }
323       return \"mov %1,%0\";
324     default:
325       abort ();
326     }
327 }"
328   [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
329
330 (define_expand "movsf"
331   [(set (match_operand:SF 0 "general_operand" "")
332         (match_operand:SF 1 "general_operand" ""))]
333   ""
334   "
335 {
336   /* One of the ops has to be in a register */
337   if (!register_operand (operand1, SFmode)
338       && !register_operand (operand0, SFmode))
339     operands[1] = copy_to_mode_reg (SFmode, operand1);
340 }")
341
342 (define_insn ""
343   [(set (match_operand:SF 0 "nonimmediate_operand" "=dx,ax,dx,a,daxm,dax")
344         (match_operand:SF 1 "general_operand" "0,0,G,G,dax,daxFm"))]
345   "register_operand (operands[0], SFmode)
346    || register_operand (operands[1], SFmode)"
347   "*
348 {
349   switch (which_alternative)
350     {
351     case 0:
352     case 1:
353       return \"nop\";
354     case 2:
355       return \"clr %0\";
356     case 3:
357     case 4:
358     case 5:
359       if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
360           && GET_CODE (operands[1]) == CONST_INT)
361         {
362           HOST_WIDE_INT val = INTVAL (operands[1]);
363
364           if (((val & 0x80) && ! (val & 0xffffff00))
365               || ((val & 0x800000) && ! (val & 0xff000000)))
366             return \"movu %1,%0\";
367         }
368       return \"mov %1,%0\";
369     default:
370       abort ();
371     }
372 }"
373   [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit")])
374
375 (define_expand "movdi"
376   [(set (match_operand:DI 0 "general_operand" "")
377         (match_operand:DI 1 "general_operand" ""))]
378   ""
379   "
380 {
381   /* One of the ops has to be in a register */
382   if (!register_operand (operand1, DImode)
383       && !register_operand (operand0, DImode))
384     operands[1] = copy_to_mode_reg (DImode, operand1);
385 }")
386
387 (define_insn ""
388   [(set (match_operand:DI 0 "nonimmediate_operand"
389                                 "=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax")
390         (match_operand:DI 1 "general_operand"
391                                 "0,0,I,I,dx,ax,dx,ax,dxim,axim,dxim,axim"))]
392   "register_operand (operands[0], DImode)
393    || register_operand (operands[1], DImode)"
394   "*
395 {
396   long val[2];
397   REAL_VALUE_TYPE rv;
398
399   switch (which_alternative)
400     {
401       case 0:
402       case 1:
403         return \"nop\";
404
405       case 2:
406         return \"clr %L0\;clr %H0\";
407
408       case 3:
409         if (rtx_equal_p (operands[0], operands[1]))
410           return \"sub %L1,%L0\;mov %L0,%H0\";
411         else
412           return \"mov %1,%L0\;mov %L0,%H0\";
413       case 4:
414       case 5:
415       case 6:
416       case 7:
417       case 8:
418       case 9:
419       case 10:
420       case 11:
421         if (GET_CODE (operands[1]) == CONST_INT)
422           {
423             rtx low, high;
424             split_double (operands[1], &low, &high);
425             val[0] = INTVAL (low);
426             val[1] = INTVAL (high);
427           }
428         if (GET_CODE (operands[1]) == CONST_DOUBLE)
429           {
430             if (GET_MODE (operands[1]) == DFmode)
431               {
432                 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
433                 REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
434               }
435             else if (GET_MODE (operands[1]) == VOIDmode
436                      || GET_MODE (operands[1]) == DImode)
437               {
438                 val[0] = CONST_DOUBLE_LOW (operands[1]);
439                 val[1] = CONST_DOUBLE_HIGH (operands[1]);
440               }
441           }
442
443         if (GET_CODE (operands[1]) == MEM
444             && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
445           {
446             rtx temp = operands[0];
447
448             while (GET_CODE (temp) == SUBREG)
449               temp = SUBREG_REG (temp);
450
451             if (GET_CODE (temp) != REG)
452               abort ();
453
454             if (reg_overlap_mentioned_p (gen_rtx_REG (SImode, REGNO (temp)),
455                                          XEXP (operands[1], 0)))
456               return \"mov %H1,%H0\;mov %L1,%L0\";
457             else
458               return \"mov %L1,%L0\;mov %H1,%H0\";
459               
460           }
461         else if (GET_CODE (operands[1]) == MEM
462                  && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
463                  && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
464           {
465             rtx xoperands[2];
466
467             xoperands[0] = operands[0];
468             xoperands[1] = XEXP (operands[1], 0);
469
470             output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\",
471                              xoperands);
472             return \"\";
473           }
474         else
475           {
476             if ((GET_CODE (operands[1]) == CONST_INT
477                  || GET_CODE (operands[1]) == CONST_DOUBLE)
478                 && val[0] == 0)
479               {
480                 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
481                   output_asm_insn (\"clr %L0\", operands);
482                 else
483                   output_asm_insn (\"mov %L1,%L0\", operands);
484               }
485             else if ((GET_CODE (operands[1]) == CONST_INT
486                       || GET_CODE (operands[1]) == CONST_DOUBLE)
487                      && (REGNO_REG_CLASS (true_regnum (operands[0]))
488                          == EXTENDED_REGS)
489                      && (((val[0] & 0x80) && ! (val[0] & 0xffffff00))
490                          || ((val[0] & 0x800000) && ! (val[0] & 0xff000000))))
491               output_asm_insn (\"movu %1,%0\", operands);
492             else
493               output_asm_insn (\"mov %L1,%L0\", operands);
494
495             if ((GET_CODE (operands[1]) == CONST_INT
496                  || GET_CODE (operands[1]) == CONST_DOUBLE)
497                 && val[1] == 0)
498               {
499                 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
500                   output_asm_insn (\"clr %H0\", operands);
501                 else
502                   output_asm_insn (\"mov %H1,%H0\", operands);
503               }
504             else if ((GET_CODE (operands[1]) == CONST_INT
505                       || GET_CODE (operands[1]) == CONST_DOUBLE)
506                      && val[0] == val[1])
507               output_asm_insn (\"mov %L0,%H0\", operands);
508             else if ((GET_CODE (operands[1]) == CONST_INT
509                       || GET_CODE (operands[1]) == CONST_DOUBLE)
510                      && (REGNO_REG_CLASS (true_regnum (operands[0]))
511                          == EXTENDED_REGS)
512                      && (((val[1] & 0x80) && ! (val[1] & 0xffffff00))
513                          || ((val[1] & 0x800000) && ! (val[1] & 0xff000000))))
514               output_asm_insn (\"movu %1,%0\", operands);
515             else
516               output_asm_insn (\"mov %H1,%H0\", operands);
517             return \"\";
518           }
519     default:
520       abort ();
521     }
522 }"
523   [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
524
525 (define_expand "movdf"
526   [(set (match_operand:DF 0 "general_operand" "")
527         (match_operand:DF 1 "general_operand" ""))]
528   ""
529   "
530 {
531   /* One of the ops has to be in a register */
532   if (!register_operand (operand1, DFmode)
533       && !register_operand (operand0, DFmode))
534     operands[1] = copy_to_mode_reg (DFmode, operand1);
535 }")
536
537 (define_insn ""
538   [(set (match_operand:DF 0 "nonimmediate_operand"
539                                 "=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax")
540         (match_operand:DF 1 "general_operand"
541                                 "0,0,G,G,dx,ax,dx,ax,dxFm,axFm,dxFm,axFm"))]
542   "register_operand (operands[0], DFmode)
543    || register_operand (operands[1], DFmode)"
544   "*
545 {
546   long val[2];
547   REAL_VALUE_TYPE rv;
548
549   switch (which_alternative)
550     {
551       case 0:
552       case 1:
553         return \"nop\";
554
555       case 2:
556         return \"clr %L0\;clr %H0\";
557
558       case 3:
559          if (rtx_equal_p (operands[0], operands[1]))
560            return \"sub %L1,%L0\;mov %L0,%H0\";
561          else
562            return \"mov %1,%L0\;mov %L0,%H0\";
563       case 4:
564       case 5:
565       case 6:
566       case 7:
567       case 8:
568       case 9:
569       case 10:
570       case 11:
571         if (GET_CODE (operands[1]) == CONST_INT)
572           {
573             rtx low, high;
574             split_double (operands[1], &low, &high);
575             val[0] = INTVAL (low);
576             val[1] = INTVAL (high);
577           }
578         if (GET_CODE (operands[1]) == CONST_DOUBLE)
579           {
580             if (GET_MODE (operands[1]) == DFmode)
581               {
582                 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
583                 REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
584               }
585             else if (GET_MODE (operands[1]) == VOIDmode
586                      || GET_MODE (operands[1]) == DImode)
587               {
588                 val[0] = CONST_DOUBLE_LOW (operands[1]);
589                 val[1] = CONST_DOUBLE_HIGH (operands[1]);
590               }
591           }
592
593         if (GET_CODE (operands[1]) == MEM
594             && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
595           {
596             rtx temp = operands[0];
597
598             while (GET_CODE (temp) == SUBREG)
599               temp = SUBREG_REG (temp);
600
601             if (GET_CODE (temp) != REG)
602               abort ();
603
604             if (reg_overlap_mentioned_p (gen_rtx_REG (SImode, REGNO (temp)),
605                                          XEXP (operands[1], 0)))
606               return \"mov %H1,%H0\;mov %L1,%L0\";
607             else
608               return \"mov %L1,%L0\;mov %H1,%H0\";
609               
610           }
611         else if (GET_CODE (operands[1]) == MEM
612                  && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
613                  && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
614           {
615             rtx xoperands[2];
616
617             xoperands[0] = operands[0];
618             xoperands[1] = XEXP (operands[1], 0);
619
620             output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\",
621                              xoperands);
622             return \"\";
623           }
624         else
625           {
626             if ((GET_CODE (operands[1]) == CONST_INT
627                  || GET_CODE (operands[1]) == CONST_DOUBLE)
628                 && val[0] == 0)
629               {
630                 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
631                   output_asm_insn (\"clr %L0\", operands);
632                 else
633                   output_asm_insn (\"mov %L1,%L0\", operands);
634               }
635             else if ((GET_CODE (operands[1]) == CONST_INT
636                       || GET_CODE (operands[1]) == CONST_DOUBLE)
637                      && (REGNO_REG_CLASS (true_regnum (operands[0]))
638                          == EXTENDED_REGS)
639                      && (((val[0] & 0x80) && ! (val[0] & 0xffffff00))
640                          || ((val[0] & 0x800000) && ! (val[0] & 0xff000000))))
641               output_asm_insn (\"movu %1,%0\", operands);
642             else
643               output_asm_insn (\"mov %L1,%L0\", operands);
644
645             if ((GET_CODE (operands[1]) == CONST_INT
646                  || GET_CODE (operands[1]) == CONST_DOUBLE)
647                 && val[1] == 0)
648               {
649                 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
650                   output_asm_insn (\"clr %H0\", operands);
651                 else
652                   output_asm_insn (\"mov %H1,%H0\", operands);
653               }
654             else if ((GET_CODE (operands[1]) == CONST_INT
655                       || GET_CODE (operands[1]) == CONST_DOUBLE)
656                      && val[0] == val[1])
657               output_asm_insn (\"mov %L0,%H0\", operands);
658             else if ((GET_CODE (operands[1]) == CONST_INT
659                       || GET_CODE (operands[1]) == CONST_DOUBLE)
660                      && (REGNO_REG_CLASS (true_regnum (operands[0]))
661                          == EXTENDED_REGS)
662                      && (((val[1] & 0x80) && ! (val[1] & 0xffffff00))
663                          || ((val[1] & 0x800000) && ! (val[1] & 0xff000000))))
664               output_asm_insn (\"movu %1,%0\", operands);
665             else
666               output_asm_insn (\"mov %H1,%H0\", operands);
667             return \"\";
668           }
669     default:
670       abort ();
671     }
672 }"
673   [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
674
675
676 \f
677 ;; ----------------------------------------------------------------------
678 ;; TEST INSTRUCTIONS
679 ;; ----------------------------------------------------------------------
680
681 ;; Go ahead and define tstsi so we can eliminate redundant tst insns
682 ;; when we start trying to optimize this port.
683 (define_insn "tstsi"
684   [(set (cc0) (match_operand:SI 0 "register_operand" "dax"))]
685   ""
686   "* return output_tst (operands[0], insn);"
687   [(set_attr "cc" "set_znv")])
688
689 (define_insn ""
690   [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "dx,!a")))]
691   "TARGET_AM33"
692   "* return output_tst (operands[0], insn);"
693   [(set_attr "cc" "set_znv")])
694
695 (define_insn ""
696   [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "dx")))]
697   ""
698   "* return output_tst (operands[0], insn);"
699   [(set_attr "cc" "set_znv")])
700
701 (define_insn ""
702   [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "dx,!a")))]
703   "TARGET_AM33"
704   "* return output_tst (operands[0], insn);"
705   [(set_attr "cc" "set_znv")])
706
707 (define_insn ""
708   [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "dx")))]
709   ""
710   "* return output_tst (operands[0], insn);"
711   [(set_attr "cc" "set_znv")])
712
713 ;; Ordinarily, the cmp instruction will set the Z bit of cc0 to 1 if
714 ;; its operands hold equal values, but the operands of a cmp
715 ;; instruction must be distinct registers.  In the case where we'd
716 ;; like to compare a register to itself, we can achieve this effect
717 ;; with a btst 0,d0 instead.  (This will not alter the contents of d0
718 ;; but will have the proper effect on cc0.  Using d0 is arbitrary; any
719 ;; data register would work.)
720
721 ;; Even though the first alternative would be preferrable if it can
722 ;; possibly match, reload must not be given the opportunity to attempt
723 ;; to use it.  It assumes that such matches can only occur when one of
724 ;; the operands is used for input and the other for output.  Since
725 ;; this is not the case, it abort()s.  Indeed, such a reload cannot be
726 ;; possibly satisfied, so just mark the alternative with a `!', so
727 ;; that it is not considered by reload.
728
729 (define_insn "cmpsi"
730   [(set (cc0)
731         (compare (match_operand:SI 0 "register_operand" "!*d*a*x,dax")
732                  (match_operand:SI 1 "nonmemory_operand" "*0,daxi")))]
733   ""
734   "@
735   btst 0,d0
736   cmp %1,%0"
737   [(set_attr "cc" "compare,compare")])
738 \f
739 ;; ----------------------------------------------------------------------
740 ;; ADD INSTRUCTIONS
741 ;; ----------------------------------------------------------------------
742
743 (define_expand "addsi3"
744   [(set (match_operand:SI 0 "register_operand" "")
745         (plus:SI (match_operand:SI 1 "register_operand" "")
746                  (match_operand:SI 2 "nonmemory_operand" "")))]
747   ""
748   "")
749
750 (define_insn ""
751   [(set (match_operand:SI 0 "register_operand" "=dx,a,x,a,dax,!*y,!dax")
752         (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,dax")
753                  (match_operand:SI 2 "nonmemory_operand" "J,J,L,L,daxi,i,dax")))]
754   "TARGET_AM33"
755   "*
756 {
757   switch (which_alternative)
758     {
759     case 0:
760     case 1:
761       return \"inc %0\";
762     case 2:
763     case 3:
764       return \"inc4 %0\";
765     case 4:
766     case 5:
767       return \"add %2,%0\";
768     case 6:
769       {
770         enum reg_class src1_class, src2_class, dst_class;
771
772         src1_class = REGNO_REG_CLASS (true_regnum (operands[1]));
773         src2_class = REGNO_REG_CLASS (true_regnum (operands[2]));
774         dst_class = REGNO_REG_CLASS (true_regnum (operands[0]));
775         
776         /* I'm not sure if this can happen or not.  Might as well be prepared
777           and generate the best possible code if it does happen.  */
778         if (true_regnum (operands[0]) == true_regnum (operands[1]))
779           return \"add %2,%0\";
780         if (true_regnum (operands[0]) == true_regnum (operands[2]))
781           return \"add %1,%0\";
782
783         /* Catch cases where no extended register was used.  These should be
784            handled just like the mn10300.  */
785         if (src1_class != EXTENDED_REGS
786             && src2_class != EXTENDED_REGS
787             && dst_class != EXTENDED_REGS)
788           {
789             /* We have to copy one of the sources into the destination, then
790                add the other source to the destination.
791
792                Carefully select which source to copy to the destination; a naive
793                implementation will waste a byte when the source classes are 
794                different and the destination is an address register.  Selecting
795                the lowest cost register copy will optimize this sequence.  */
796             if (REGNO_REG_CLASS (true_regnum (operands[1]))
797                 == REGNO_REG_CLASS (true_regnum (operands[0])))
798               return \"mov %1,%0\;add %2,%0\";
799             return \"mov %2,%0\;add %1,%0\";
800           }
801
802         /* At least one register is an extended register.  */
803
804         /* The three operand add instruction on the am33 is a win iff the
805            output register is an extended register, or if both source
806            registers are extended registers.  */
807         if (dst_class == EXTENDED_REGS
808             || src1_class == src2_class)
809           return \"add %2,%1,%0\";
810
811       /* It is better to copy one of the sources to the destination, then
812          perform a 2 address add.  The destination in this case must be
813          an address or data register and one of the sources must be an
814          extended register and the remaining source must not be an extended
815          register.
816
817          The best code for this case is to copy the extended reg to the
818          destination, then emit a two address add.  */
819       if (src1_class == EXTENDED_REGS)
820         return \"mov %1,%0\;add %2,%0\";
821       return \"mov %2,%0\;add %1,%0\";
822       }
823     default:
824       abort ();
825     }
826 }"
827   [(set_attr "cc" "set_zn,none_0hit,set_zn,none_0hit,set_zn,none_0hit,set_zn")])
828
829 (define_insn ""
830   [(set (match_operand:SI 0 "register_operand" "=dx,a,a,dax,!*y,!dax")
831         (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,dax")
832                  (match_operand:SI 2 "nonmemory_operand" "J,J,L,daxi,i,dax")))]
833   ""
834   "*
835 {
836   switch (which_alternative)
837     {
838     case 0:
839     case 1:
840       return \"inc %0\";
841     case 2:
842       return \"inc4 %0\";
843     case 3:
844     case 4:
845       return \"add %2,%0\";
846     case 5:
847       /* I'm not sure if this can happen or not.  Might as well be prepared
848          and generate the best possible code if it does happen.  */
849       if (true_regnum (operands[0]) == true_regnum (operands[1]))
850         return \"add %2,%0\";
851       if (true_regnum (operands[0]) == true_regnum (operands[2]))
852         return \"add %1,%0\";
853
854       /* We have to copy one of the sources into the destination, then add
855          the other source to the destination.
856
857          Carefully select which source to copy to the destination; a naive
858          implementation will waste a byte when the source classes are different
859          and the destination is an address register.  Selecting the lowest
860          cost register copy will optimize this sequence.  */
861       if (REGNO_REG_CLASS (true_regnum (operands[1]))
862           == REGNO_REG_CLASS (true_regnum (operands[0])))
863         return \"mov %1,%0\;add %2,%0\";
864       return \"mov %2,%0\;add %1,%0\";
865     default:
866       abort ();
867     }
868 }"
869   [(set_attr "cc" "set_zn,none_0hit,none_0hit,set_zn,none_0hit,set_zn")])
870
871 ;; ----------------------------------------------------------------------
872 ;; SUBTRACT INSTRUCTIONS
873 ;; ----------------------------------------------------------------------
874
875 (define_expand "subsi3"
876   [(set (match_operand:SI 0 "register_operand" "")
877         (minus:SI (match_operand:SI 1 "register_operand" "")
878                   (match_operand:SI 2 "nonmemory_operand" "")))]
879   ""
880   "")
881
882 (define_insn ""
883   [(set (match_operand:SI 0 "register_operand" "=dax,!dax")
884         (minus:SI (match_operand:SI 1 "register_operand" "0,dax")
885                   (match_operand:SI 2 "nonmemory_operand" "daxi,dax")))]
886   "TARGET_AM33"
887   "*
888 {
889   if (true_regnum (operands[0]) == true_regnum (operands[1]))
890     return \"sub %2,%0\";
891   else
892     {
893       enum reg_class src1_class, src2_class, dst_class;
894
895       src1_class = REGNO_REG_CLASS (true_regnum (operands[1]));
896       src2_class = REGNO_REG_CLASS (true_regnum (operands[2]));
897       dst_class = REGNO_REG_CLASS (true_regnum (operands[0]));
898
899       /* If no extended registers are used, then the best way to handle
900          this is to copy the first source operand into the destination
901          and emit a two address subtraction.  */
902       if (src1_class != EXTENDED_REGS
903           && src2_class != EXTENDED_REGS
904           && dst_class != EXTENDED_REGS
905           && true_regnum (operands[0]) != true_regnum (operands[2]))
906         return \"mov %1,%0\;sub %2,%0\";
907       return \"sub %2,%1,%0\";
908     }
909 }"
910   [(set_attr "cc" "set_zn")])
911
912 (define_insn ""
913   [(set (match_operand:SI 0 "register_operand" "=dax")
914         (minus:SI (match_operand:SI 1 "register_operand" "0")
915                   (match_operand:SI 2 "nonmemory_operand" "daxi")))]
916   ""
917   "sub %2,%0"
918   [(set_attr "cc" "set_zn")])
919
920 (define_expand "negsi2"
921   [(set (match_operand:SI 0 "register_operand" "")
922         (neg:SI (match_operand:SI 1 "register_operand" "")))]
923   ""
924   "
925 {
926   rtx target = gen_reg_rtx (SImode);
927
928   emit_move_insn (target, GEN_INT (0));
929   emit_insn (gen_subsi3 (target, target, operands[1]));
930   emit_move_insn (operands[0], target);
931   DONE;
932 }")
933
934 ;; ----------------------------------------------------------------------
935 ;; MULTIPLY INSTRUCTIONS
936 ;; ----------------------------------------------------------------------
937
938 (define_insn "mulsidi3"
939   [(set (match_operand:DI 0 "register_operand" "=dax")
940         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "dax"))
941                  (sign_extend:DI (match_operand:SI 2 "register_operand" "dax"))))]
942   "TARGET_AM33"
943   "mul %1,%2,%H0,%L0"
944   [(set_attr "cc" "set_zn")])
945
946 (define_insn "umulsidi3"
947   [(set (match_operand:DI 0 "register_operand" "=dax")
948         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "dax"))
949                  (zero_extend:DI (match_operand:SI 2 "register_operand" "dax"))))]
950   "TARGET_AM33"
951   "mulu %1,%2,%H0,%L0"
952   [(set_attr "cc" "set_zn")])
953
954 (define_expand "mulsi3"
955   [(set (match_operand:SI 0 "register_operand" "")
956         (mult:SI (match_operand:SI 1 "register_operand" "")
957                  (match_operand:SI 2 "register_operand" "")))]
958   ""
959   "")
960
961 (define_insn ""
962   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
963         (mult:SI (match_operand:SI 1 "register_operand" "%0,0")
964                  (match_operand:SI 2 "nonmemory_operand" "dx,daxi")))]
965   "TARGET_AM33"
966   "*
967 {
968   if (TARGET_MULT_BUG)
969     return \"nop\;nop\;mul %2,%0\";
970   else
971     return \"mul %2,%0\";
972 }"
973   [(set_attr "cc" "set_zn")])
974   
975 (define_insn ""
976   [(set (match_operand:SI 0 "register_operand" "=dx")
977         (mult:SI (match_operand:SI 1 "register_operand" "%0")
978                  (match_operand:SI 2 "register_operand" "dx")))]
979   ""
980   "*
981 {
982   if (TARGET_MULT_BUG)
983     return \"nop\;nop\;mul %2,%0\";
984   else
985     return \"mul %2,%0\";
986 }"
987   [(set_attr "cc" "set_zn")])
988
989 (define_insn "udivmodsi4"
990   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx")
991         (udiv:SI (match_operand:SI 1 "general_operand" "0")
992                  (match_operand:SI 2 "general_operand" "dx")))
993    (set (match_operand:SI 3 "nonimmediate_operand" "=&d")
994         (umod:SI (match_dup 1) (match_dup 2)))]
995   ""
996   "*
997 {
998   output_asm_insn (\"sub %3,%3\;mov %3,mdr\", operands);
999
1000   if (find_reg_note (insn, REG_UNUSED, operands[3]))
1001     return \"divu %2,%0\";
1002   else
1003     return \"divu %2,%0\;mov mdr,%3\";
1004 }"
1005   [(set_attr "cc" "set_zn")])
1006
1007 (define_insn "divmodsi4"
1008   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx")
1009         (div:SI (match_operand:SI 1 "general_operand" "0")
1010                  (match_operand:SI 2 "general_operand" "dx")))
1011    (set (match_operand:SI 3 "nonimmediate_operand" "=d")
1012         (mod:SI (match_dup 1) (match_dup 2)))]
1013   ""
1014   "*
1015 {
1016   if (find_reg_note (insn, REG_UNUSED, operands[3]))
1017     return \"ext %0\;div %2,%0\";
1018   else
1019     return \"ext %0\;div %2,%0\;mov mdr,%3\";
1020 }"
1021   [(set_attr "cc" "set_zn")])
1022
1023 \f
1024 ;; ----------------------------------------------------------------------
1025 ;; AND INSTRUCTIONS
1026 ;; ----------------------------------------------------------------------
1027
1028 (define_expand "andsi3"
1029   [(set (match_operand:SI 0 "register_operand" "")
1030         (and:SI (match_operand:SI 1 "register_operand" "")
1031                 (match_operand:SI 2 "nonmemory_operand" "")))]
1032   ""
1033   "")
1034
1035 (define_insn ""
1036   [(set (match_operand:SI 0 "register_operand" "=dx,dx,!dax")
1037         (and:SI (match_operand:SI 1 "register_operand" "%0,0,dax")
1038                 (match_operand:SI 2 "nonmemory_operand" "N,dxi,dax")))]
1039   "TARGET_AM33"
1040   "*
1041 {
1042   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff)
1043     return \"extbu %0\";
1044   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xffff)
1045     return \"exthu %0\";
1046   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x7fffffff)
1047     return \"add %0,%0\;lsr 1,%0\";
1048   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x3fffffff)
1049     return \"asl2 %0\;lsr 2,%0\";
1050   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x1fffffff)
1051     return \"add %0,%0\;asl2 %0\;lsr 3,%0\";
1052   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x0fffffff)
1053     return \"asl2 %0\;asl2 %0\;lsr 4,%0\";
1054   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffe)
1055     return \"lsr 1,%0\;add %0,%0\";
1056   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffc)
1057     return \"lsr 2,%0\;asl2 %0\";
1058   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff8)
1059     return \"lsr 3,%0\;add %0,%0\;asl2 %0\";
1060   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff0)
1061     return \"lsr 4,%0\;asl2 %0\;asl2 %0\";
1062   if (REG_P (operands[2]) && REG_P (operands[1])
1063       && true_regnum (operands[0]) != true_regnum (operands[1])
1064       && true_regnum (operands[0]) != true_regnum (operands[2])
1065       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1066       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1067       && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
1068     return \"mov %1,%0\;and %2,%0\";
1069   if (REG_P (operands[2]) && REG_P (operands[1])
1070       && true_regnum (operands[0]) != true_regnum (operands[1])
1071       && true_regnum (operands[0]) != true_regnum (operands[2]))
1072     return \"and %1,%2,%0\";
1073   if (REG_P (operands[2]) && REG_P (operands[0])
1074       && true_regnum (operands[2]) == true_regnum (operands[0]))
1075     return \"and %1,%0\";
1076   return \"and %2,%0\";
1077 }"
1078   [(set_attr "cc" "none_0hit,set_znv,set_znv")])
1079
1080 (define_insn ""
1081   [(set (match_operand:SI 0 "register_operand" "=dx,dx")
1082         (and:SI (match_operand:SI 1 "register_operand" "%0,0")
1083                 (match_operand:SI 2 "nonmemory_operand" "N,dxi")))]
1084   ""
1085   "*
1086 {
1087   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff)
1088     return \"extbu %0\";
1089   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xffff)
1090     return \"exthu %0\";
1091   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x7fffffff)
1092     return \"add %0,%0\;lsr 1,%0\";
1093   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x3fffffff)
1094     return \"asl2 %0\;lsr 2,%0\";
1095   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x1fffffff)
1096     return \"add %0,%0\;asl2 %0\;lsr 3,%0\";
1097   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x0fffffff)
1098     return \"asl2 %0\;asl2 %0\;lsr 4,%0\";
1099   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffe)
1100     return \"lsr 1,%0\;add %0,%0\";
1101   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffc)
1102     return \"lsr 2,%0\;asl2 %0\";
1103   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff8)
1104     return \"lsr 3,%0\;add %0,%0\;asl2 %0\";
1105   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff0)
1106     return \"lsr 4,%0\;asl2 %0\;asl2 %0\";
1107   return \"and %2,%0\";
1108 }"
1109   [(set_attr "cc" "none_0hit,set_znv")])
1110
1111 ;; ----------------------------------------------------------------------
1112 ;; OR INSTRUCTIONS
1113 ;; ----------------------------------------------------------------------
1114
1115 (define_expand "iorsi3"
1116   [(set (match_operand:SI 0 "register_operand" "")
1117         (ior:SI (match_operand:SI 1 "register_operand" "")
1118                 (match_operand:SI 2 "nonmemory_operand" "")))]
1119   ""
1120   "")
1121
1122 (define_insn ""
1123   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1124         (ior:SI (match_operand:SI 1 "register_operand" "%0,dax")
1125                 (match_operand:SI 2 "nonmemory_operand" "dxi,dax")))]
1126   "TARGET_AM33"
1127   "*
1128 {
1129   if (REG_P (operands[2]) && REG_P (operands[1])
1130       && true_regnum (operands[0]) != true_regnum (operands[1])
1131       && true_regnum (operands[0]) != true_regnum (operands[2])
1132       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1133       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1134       && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
1135     return \"mov %1,%0\;or %2,%0\";
1136   if (REG_P (operands[2]) && REG_P (operands[1])
1137       && true_regnum (operands[0]) != true_regnum (operands[1])
1138       && true_regnum (operands[0]) != true_regnum (operands[2]))
1139     return \"or %1,%2,%0\";
1140   if (REG_P (operands[2]) && REG_P (operands[0])
1141       && true_regnum (operands[2]) == true_regnum (operands[0]))
1142     return \"or %1,%0\";
1143   return \"or %2,%0\";
1144 }"
1145   [(set_attr "cc" "set_znv")])
1146
1147 (define_insn ""
1148   [(set (match_operand:SI 0 "register_operand" "=dx")
1149         (ior:SI (match_operand:SI 1 "register_operand" "%0")
1150                 (match_operand:SI 2 "nonmemory_operand" "dxi")))]
1151   ""
1152   "or %2,%0"
1153   [(set_attr "cc" "set_znv")])
1154
1155 ;; ----------------------------------------------------------------------
1156 ;; XOR INSTRUCTIONS
1157 ;; ----------------------------------------------------------------------
1158
1159 (define_expand "xorsi3"
1160   [(set (match_operand:SI 0 "register_operand" "")
1161         (xor:SI (match_operand:SI 1 "register_operand" "")
1162                 (match_operand:SI 2 "nonmemory_operand" "")))]
1163   ""
1164   "")
1165
1166 (define_insn ""
1167   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1168         (xor:SI (match_operand:SI 1 "register_operand" "%0,dax")
1169                 (match_operand:SI 2 "nonmemory_operand" "dxi,dax")))]
1170   "TARGET_AM33"
1171   "*
1172 {
1173   if (REG_P (operands[2]) && REG_P (operands[1])
1174       && true_regnum (operands[0]) != true_regnum (operands[1])
1175       && true_regnum (operands[0]) != true_regnum (operands[2])
1176       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1177       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1178       && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
1179     return \"mov %1,%0\;xor %2,%0\";
1180   if (REG_P (operands[2]) && REG_P (operands[1])
1181       && true_regnum (operands[0]) != true_regnum (operands[1])
1182       && true_regnum (operands[0]) != true_regnum (operands[2]))
1183     return \"xor %1,%2,%0\";
1184   if (REG_P (operands[2]) && REG_P (operands[0])
1185       && true_regnum (operands[2]) == true_regnum (operands[0]))
1186     return \"xor %1,%0\";
1187   return \"xor %2,%0\";
1188 }"
1189   [(set_attr "cc" "set_znv")])
1190
1191 (define_insn ""
1192   [(set (match_operand:SI 0 "register_operand" "=dx")
1193         (xor:SI (match_operand:SI 1 "register_operand" "%0")
1194                 (match_operand:SI 2 "nonmemory_operand" "dxi")))]
1195   ""
1196   "xor %2,%0"
1197   [(set_attr "cc" "set_znv")])
1198
1199 ;; ----------------------------------------------------------------------
1200 ;; NOT INSTRUCTIONS
1201 ;; ----------------------------------------------------------------------
1202
1203 (define_expand "one_cmplsi2"
1204   [(set (match_operand:SI 0 "register_operand" "")
1205         (not:SI (match_operand:SI 1 "register_operand" "")))]
1206   ""
1207   "")
1208
1209 (define_insn ""
1210   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1211         (not:SI (match_operand:SI 1 "register_operand" "0,0")))]
1212   "TARGET_AM33"
1213   "not %0"
1214   [(set_attr "cc" "set_znv")])
1215
1216 (define_insn ""
1217   [(set (match_operand:SI 0 "register_operand" "=dx")
1218         (not:SI (match_operand:SI 1 "register_operand" "0")))]
1219   ""
1220   "not %0"
1221   [(set_attr "cc" "set_znv")])
1222 \f
1223 ;; -----------------------------------------------------------------
1224 ;; BIT FIELDS
1225 ;; -----------------------------------------------------------------
1226
1227
1228 ;; These set/clear memory in byte sized chunks.
1229 ;;
1230 ;; They are no smaller/faster than loading the value into a register
1231 ;; and storing the register, but they don't need a scratch register
1232 ;; which may allow for better code generation.
1233 (define_insn ""
1234   [(set (match_operand:QI 0 "nonimmediate_operand" "=R,d") (const_int 0))]
1235   ""
1236   "@
1237   bclr 255,%A0
1238   clr %0"
1239   [(set_attr "cc" "clobber")])
1240
1241 (define_insn ""
1242   [(set (match_operand:QI 0 "nonimmediate_operand" "=R,d") (const_int -1))]
1243   ""
1244   "@
1245   bset 255,%A0
1246   mov -1,%0"
1247   [(set_attr "cc" "clobber,none_0hit")])
1248
1249 (define_insn ""
1250   [(set (match_operand:QI 0 "nonimmediate_operand" "+R,d")
1251         (subreg:QI
1252           (and:SI (subreg:SI (match_dup 0) 0)
1253                   (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
1254   ""
1255   "@
1256   bclr %N1,%A0
1257   and %1,%0"
1258   [(set_attr "cc" "clobber,set_znv")])
1259
1260 (define_insn ""
1261   [(set (match_operand:QI 0 "nonimmediate_operand" "+R,d")
1262         (subreg:QI
1263           (ior:SI (subreg:SI (match_dup 0) 0)
1264                   (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
1265   ""
1266   "@
1267   bset %1,%A0
1268   or %1,%0"
1269   [(set_attr "cc" "clobber,set_znv")])
1270
1271 (define_insn ""
1272   [(set (cc0)
1273      (zero_extract:SI (match_operand:SI 0 "register_operand" "dx")
1274                       (match_operand 1 "const_int_operand" "")
1275                       (match_operand 2 "const_int_operand" "")))]
1276   ""
1277   "*
1278 {
1279   int len = INTVAL (operands[1]);
1280   int bit = INTVAL (operands[2]);
1281   int mask = 0;
1282   rtx xoperands[2];
1283
1284   while (len > 0)
1285     {
1286       mask |= (1 << bit);
1287       bit++;
1288       len--;
1289     }
1290
1291   xoperands[0] = operands[0];
1292   xoperands[1] = GEN_INT (trunc_int_for_mode (mask, SImode));
1293   output_asm_insn (\"btst %1,%0\", xoperands);
1294   return \"\";
1295 }"
1296   [(set_attr "cc" "clobber")])
1297
1298 (define_insn ""
1299   [(set (cc0)
1300      (zero_extract:SI (match_operand:QI 0 "general_operand" "R,dx")
1301                       (match_operand 1 "const_int_operand" "")
1302                       (match_operand 2 "const_int_operand" "")))]
1303   "mask_ok_for_mem_btst (INTVAL (operands[1]), INTVAL (operands[2]))"
1304   "*
1305 {
1306   int len = INTVAL (operands[1]);
1307   int bit = INTVAL (operands[2]);
1308   int mask = 0;
1309   rtx xoperands[2];
1310
1311   while (len > 0)
1312     {
1313       mask |= (1 << bit);
1314       bit++;
1315       len--;
1316     }
1317
1318   /* If the source operand is not a reg (ie it is memory), then extract the
1319      bits from mask that we actually want to test.  Note that the mask will
1320      never cross a byte boundary.  */
1321   if (!REG_P (operands[0]))
1322     {
1323       if (mask & 0xff)
1324         mask = mask & 0xff;
1325       else if (mask & 0xff00)
1326         mask = (mask >> 8) & 0xff;
1327       else if (mask & 0xff0000)
1328         mask = (mask >> 16) & 0xff;
1329       else if (mask & 0xff000000)
1330         mask = (mask >> 24) & 0xff;
1331     }
1332   
1333   xoperands[0] = operands[0];
1334   xoperands[1] = GEN_INT (trunc_int_for_mode (mask, SImode));
1335   if (GET_CODE (operands[0]) == REG)
1336     output_asm_insn (\"btst %1,%0\", xoperands);
1337   else
1338     output_asm_insn (\"btst %1,%A0\", xoperands);
1339   return \"\";
1340 }"
1341   [(set_attr "cc" "clobber")])
1342
1343 (define_insn ""
1344   [(set (cc0) (and:SI (match_operand:SI 0 "register_operand" "dx")
1345                       (match_operand:SI 1 "const_int_operand" "")))]
1346   ""
1347   "btst %1,%0"
1348   [(set_attr "cc" "clobber")])
1349
1350 (define_insn ""
1351   [(set (cc0)
1352      (and:SI
1353        (subreg:SI (match_operand:QI 0 "general_operand" "R,dx") 0)
1354        (match_operand:SI 1 "const_8bit_operand" "")))]
1355   ""
1356   "@
1357   btst %1,%A0
1358   btst %1,%0"
1359   [(set_attr "cc" "clobber")])
1360
1361 \f
1362 ;; ----------------------------------------------------------------------
1363 ;; JUMP INSTRUCTIONS
1364 ;; ----------------------------------------------------------------------
1365
1366 ;; Conditional jump instructions
1367
1368 (define_expand "ble"
1369   [(set (pc)
1370         (if_then_else (le (cc0)
1371                           (const_int 0))
1372                       (label_ref (match_operand 0 "" ""))
1373                       (pc)))]
1374   ""
1375   "")
1376
1377 (define_expand "bleu"
1378   [(set (pc)
1379         (if_then_else (leu (cc0)
1380                            (const_int 0))
1381                       (label_ref (match_operand 0 "" ""))
1382                       (pc)))]
1383   ""
1384   "")
1385
1386 (define_expand "bge"
1387   [(set (pc)
1388         (if_then_else (ge (cc0)
1389                           (const_int 0))
1390                       (label_ref (match_operand 0 "" ""))
1391                       (pc)))]
1392   ""
1393   "")
1394
1395 (define_expand "bgeu"
1396   [(set (pc)
1397         (if_then_else (geu (cc0)
1398                            (const_int 0))
1399                       (label_ref (match_operand 0 "" ""))
1400                       (pc)))]
1401   ""
1402   "")
1403
1404 (define_expand "blt"
1405   [(set (pc)
1406         (if_then_else (lt (cc0)
1407                           (const_int 0))
1408                       (label_ref (match_operand 0 "" ""))
1409                       (pc)))]
1410   ""
1411   "")
1412
1413 (define_expand "bltu"
1414   [(set (pc)
1415         (if_then_else (ltu (cc0)
1416                            (const_int 0))
1417                       (label_ref (match_operand 0 "" ""))
1418                       (pc)))]
1419   ""
1420   "")
1421
1422 (define_expand "bgt"
1423   [(set (pc)
1424         (if_then_else (gt (cc0)
1425                           (const_int 0))
1426                       (label_ref (match_operand 0 "" ""))
1427                       (pc)))]
1428   ""
1429   "")
1430
1431 (define_expand "bgtu"
1432   [(set (pc)
1433         (if_then_else (gtu (cc0)
1434                            (const_int 0))
1435                       (label_ref (match_operand 0 "" ""))
1436                       (pc)))]
1437   ""
1438   "")
1439
1440 (define_expand "beq"
1441   [(set (pc)
1442         (if_then_else (eq (cc0)
1443                           (const_int 0))
1444                       (label_ref (match_operand 0 "" ""))
1445                       (pc)))]
1446   ""
1447   "")
1448
1449 (define_expand "bne"
1450   [(set (pc)
1451         (if_then_else (ne (cc0)
1452                           (const_int 0))
1453                       (label_ref (match_operand 0 "" ""))
1454                       (pc)))]
1455   ""
1456   "")
1457
1458 (define_insn ""
1459   [(set (pc)
1460         (if_then_else (match_operator 1 "comparison_operator"
1461                                       [(cc0) (const_int 0)])
1462                       (label_ref (match_operand 0 "" ""))
1463                       (pc)))]
1464   ""
1465   "*
1466 {
1467   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1468       && (GET_CODE (operands[1]) == GT
1469           || GET_CODE (operands[1]) == GE
1470           || GET_CODE (operands[1]) == LE
1471           || GET_CODE (operands[1]) == LT))
1472     return 0;
1473   return \"b%b1 %0\";
1474 }"
1475  [(set_attr "cc" "none")])
1476
1477 (define_insn ""
1478   [(set (pc)
1479         (if_then_else (match_operator 1 "comparison_operator"
1480                                       [(cc0) (const_int 0)])
1481                       (pc)
1482                       (label_ref (match_operand 0 "" ""))))]
1483   ""
1484   "*
1485 {
1486   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1487       && (GET_CODE (operands[1]) == GT
1488           || GET_CODE (operands[1]) == GE
1489           || GET_CODE (operands[1]) == LE
1490           || GET_CODE (operands[1]) == LT))
1491     return 0;
1492   return \"b%B1 %0\";
1493 }"
1494  [(set_attr "cc" "none")])
1495
1496 ;; Unconditional and other jump instructions.
1497
1498 (define_insn "jump"
1499   [(set (pc)
1500         (label_ref (match_operand 0 "" "")))]
1501   ""
1502   "jmp %l0"
1503  [(set_attr "cc" "none")])
1504
1505 (define_insn "indirect_jump"
1506   [(set (pc) (match_operand:SI 0 "register_operand" "a"))]
1507   ""
1508   "jmp (%0)"
1509   [(set_attr "cc" "none")])
1510
1511 (define_insn "tablejump"
1512   [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1513    (use (label_ref (match_operand 1 "" "")))]
1514   ""
1515   "jmp (%0)"
1516   [(set_attr "cc" "none")])
1517
1518 ;; Call subroutine with no return value.
1519
1520 (define_expand "call"
1521   [(call (match_operand:QI 0 "general_operand" "")
1522          (match_operand:SI 1 "general_operand" ""))]
1523   ""
1524   "
1525 {
1526   if (! call_address_operand (XEXP (operands[0], 0), VOIDmode))
1527     XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
1528   emit_call_insn (gen_call_internal (XEXP (operands[0], 0), operands[1]));
1529   DONE;
1530 }")
1531
1532 (define_insn "call_internal"
1533   [(call (mem:QI (match_operand:SI 0 "call_address_operand" "aS"))
1534          (match_operand:SI 1 "general_operand" "g"))]
1535   ""
1536   "*
1537 {
1538   if (REG_P (operands[0]))
1539     return \"calls %C0\";
1540   else
1541     return \"call %C0,[],0\";
1542 }"
1543   [(set_attr "cc" "clobber")])
1544
1545 ;; Call subroutine, returning value in operand 0
1546 ;; (which must be a hard register).
1547
1548 (define_expand "call_value"
1549   [(set (match_operand 0 "" "")
1550         (call (match_operand:QI 1 "general_operand" "")
1551               (match_operand:SI 2 "general_operand" "")))]
1552   ""
1553   "
1554 {
1555   if (! call_address_operand (XEXP (operands[1], 0), VOIDmode))
1556     XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
1557   emit_call_insn (gen_call_value_internal (operands[0],
1558                                            XEXP (operands[1], 0),
1559                                            operands[2]));
1560   DONE;
1561 }")
1562
1563 (define_insn "call_value_internal"
1564   [(set (match_operand 0 "" "=dax")
1565         (call (mem:QI (match_operand:SI 1 "call_address_operand" "aS"))
1566               (match_operand:SI 2 "general_operand" "g")))]
1567   ""
1568   "*
1569 {
1570   if (REG_P (operands[1]))
1571     return \"calls %C1\";
1572   else
1573     return \"call %C1,[],0\";
1574 }"
1575   [(set_attr "cc" "clobber")])
1576
1577 (define_expand "untyped_call"
1578   [(parallel [(call (match_operand 0 "" "")
1579                     (const_int 0))
1580               (match_operand 1 "" "")
1581               (match_operand 2 "" "")])]
1582   ""
1583   "
1584 {
1585   int i;
1586
1587   emit_call_insn (gen_call (operands[0], const0_rtx));
1588
1589   for (i = 0; i < XVECLEN (operands[2], 0); i++)
1590     {
1591       rtx set = XVECEXP (operands[2], 0, i);
1592       emit_move_insn (SET_DEST (set), SET_SRC (set));
1593     }
1594   DONE;
1595 }")
1596
1597 (define_insn "nop"
1598   [(const_int 0)]
1599   ""
1600   "nop"
1601   [(set_attr "cc" "none")])
1602 \f
1603 ;; ----------------------------------------------------------------------
1604 ;; EXTEND INSTRUCTIONS
1605 ;; ----------------------------------------------------------------------
1606
1607 (define_expand "zero_extendqisi2"
1608   [(set (match_operand:SI 0 "general_operand" "")
1609         (zero_extend:SI
1610          (match_operand:QI 1 "general_operand" "")))]
1611   ""
1612   "")
1613
1614 (define_insn ""
1615   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx,!dax,!dax,!dax")
1616         (zero_extend:SI
1617          (match_operand:QI 1 "general_operand" "0,dax,m,0,dax,m")))]
1618   "TARGET_AM33"
1619   "@
1620   extbu %0
1621   mov %1,%0\;extbu %0
1622   movbu %1,%0
1623   extbu %0
1624   mov %1,%0\;extbu %0
1625   movbu %1,%0"
1626   [(set_attr "cc" "none_0hit")])
1627
1628 (define_insn ""
1629   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx")
1630         (zero_extend:SI
1631          (match_operand:QI 1 "general_operand" "0,d,m")))]
1632   ""
1633   "@
1634   extbu %0
1635   mov %1,%0\;extbu %0
1636   movbu %1,%0"
1637   [(set_attr "cc" "none_0hit")])
1638
1639 (define_expand "zero_extendhisi2"
1640   [(set (match_operand:SI 0 "general_operand" "")
1641         (zero_extend:SI
1642          (match_operand:HI 1 "general_operand" "")))]
1643   ""
1644   "")
1645
1646 (define_insn ""
1647   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx,!dax,!dax,!dax")
1648         (zero_extend:SI
1649          (match_operand:HI 1 "general_operand" "0,dax,m,0,dax,m")))]
1650   "TARGET_AM33"
1651   "@
1652   exthu %0
1653   mov %1,%0\;exthu %0
1654   movhu %1,%0
1655   exthu %0
1656   mov %1,%0\;exthu %0
1657   movhu %1,%0"
1658   [(set_attr "cc" "none_0hit")])
1659
1660 (define_insn ""
1661   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx")
1662         (zero_extend:SI
1663          (match_operand:HI 1 "general_operand" "0,dx,m")))]
1664   ""
1665   "@
1666   exthu %0
1667   mov %1,%0\;exthu %0
1668   movhu %1,%0"
1669   [(set_attr "cc" "none_0hit")])
1670
1671 ;;- sign extension instructions
1672
1673 (define_expand "extendqisi2"
1674   [(set (match_operand:SI 0 "general_operand" "")
1675         (sign_extend:SI
1676          (match_operand:QI 1 "general_operand" "")))]
1677   ""
1678   "")
1679
1680 (define_insn ""
1681   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,!dax,!dax")
1682         (sign_extend:SI
1683          (match_operand:QI 1 "general_operand" "0,dx,0,dax")))]
1684   "TARGET_AM33"
1685   "@
1686   extb %0
1687   mov %1,%0\;extb %0
1688   extb %0
1689   mov %1,%0\;extb %0"
1690   [(set_attr "cc" "none_0hit")])
1691
1692 (define_insn ""
1693   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx")
1694         (sign_extend:SI
1695          (match_operand:QI 1 "general_operand" "0,dx")))]
1696   ""
1697   "@
1698   extb %0
1699   mov %1,%0\;extb %0"
1700   [(set_attr "cc" "none_0hit")])
1701
1702 (define_expand "extendhisi2"
1703   [(set (match_operand:SI 0 "general_operand" "")
1704         (sign_extend:SI
1705          (match_operand:HI 1 "general_operand" "")))]
1706   ""
1707   "")
1708
1709 (define_insn ""
1710   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,!dax,!dax")
1711         (sign_extend:SI
1712          (match_operand:HI 1 "general_operand" "0,dax,0,dax")))]
1713   "TARGET_AM33"
1714   "@
1715   exth %0
1716   mov %1,%0\;exth %0
1717   exth %0
1718   mov %1,%0\;exth %0"
1719   [(set_attr "cc" "none_0hit")])
1720
1721 (define_insn ""
1722   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx")
1723         (sign_extend:SI
1724          (match_operand:HI 1 "general_operand" "0,dx")))]
1725   ""
1726   "@
1727   exth %0
1728   mov %1,%0\;exth %0"
1729   [(set_attr "cc" "none_0hit")])
1730 \f
1731 ;; ----------------------------------------------------------------------
1732 ;; SHIFTS
1733 ;; ----------------------------------------------------------------------
1734
1735 (define_expand "ashlsi3"
1736   [(set (match_operand:SI 0 "register_operand" "")
1737         (ashift:SI
1738          (match_operand:SI 1 "register_operand" "")
1739          (match_operand:QI 2 "nonmemory_operand" "")))]
1740   ""
1741   "")
1742
1743 (define_insn ""
1744   [(set (match_operand:SI 0 "register_operand" "=dax,dx,!dax")
1745         (ashift:SI
1746          (match_operand:SI 1 "register_operand" "0,0,dax")
1747          (match_operand:QI 2 "nonmemory_operand" "J,dxi,dax")))]
1748   "TARGET_AM33"
1749   "*
1750 {
1751   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 1)
1752     return \"add %0,%0\";
1753
1754   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 2)
1755     return \"asl2 %0\";
1756
1757   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 3
1758       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS)
1759     return \"asl2 %0\;add %0,%0\";
1760
1761   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 4
1762       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS)
1763     return \"asl2 %0\;asl2 %0\";
1764
1765   if (true_regnum (operands[1]) == true_regnum (operands[0]))
1766     return \"asl %S2,%0\";
1767
1768   if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1769       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1770       && true_regnum (operands[0]) != true_regnum (operands[2]))
1771     return \"mov %1,%0\;asl %S2,%0\";
1772   return \"asl %2,%1,%0\";
1773 }"
1774   [(set_attr "cc" "set_zn")])
1775
1776 (define_insn ""
1777   [(set (match_operand:SI 0 "register_operand" "=dax,dx,dx,dx,dx")
1778         (ashift:SI
1779          (match_operand:SI 1 "register_operand" "0,0,0,0,0")
1780          (match_operand:QI 2 "nonmemory_operand" "J,K,M,L,dxi")))]
1781   ""
1782   "@
1783   add %0,%0
1784   asl2 %0
1785   asl2 %0\;add %0,%0
1786   asl2 %0\;asl2 %0
1787   asl %S2,%0"
1788   [(set_attr "cc" "set_zn")])
1789
1790 (define_expand "lshrsi3"
1791   [(set (match_operand:SI 0 "register_operand" "")
1792         (lshiftrt:SI
1793          (match_operand:SI 1 "register_operand" "")
1794          (match_operand:QI 2 "nonmemory_operand" "")))]
1795   ""
1796   "")
1797
1798 (define_insn ""
1799   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1800         (lshiftrt:SI
1801          (match_operand:SI 1 "register_operand" "0,dax")
1802          (match_operand:QI 2 "nonmemory_operand" "dxi,dax")))]
1803   "TARGET_AM33"
1804   "*
1805 {
1806   if (true_regnum (operands[1]) == true_regnum (operands[0]))
1807     return \"lsr %S2,%0\";
1808
1809   if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1810       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1811       && true_regnum (operands[0]) != true_regnum (operands[2]))
1812     return \"mov %1,%0\;lsr %S2,%0\";
1813   return \"lsr %2,%1,%0\";
1814 }"
1815   [(set_attr "cc" "set_zn")])
1816
1817 (define_insn ""
1818   [(set (match_operand:SI 0 "register_operand" "=dx")
1819         (lshiftrt:SI
1820          (match_operand:SI 1 "register_operand" "0")
1821          (match_operand:QI 2 "nonmemory_operand" "dxi")))]
1822   ""
1823   "lsr %S2,%0"
1824   [(set_attr "cc" "set_zn")])
1825
1826 (define_expand "ashrsi3"
1827   [(set (match_operand:SI 0 "register_operand" "")
1828         (ashiftrt:SI
1829          (match_operand:SI 1 "register_operand" "")
1830          (match_operand:QI 2 "nonmemory_operand" "")))]
1831   ""
1832   "")
1833
1834 (define_insn ""
1835   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1836         (ashiftrt:SI
1837          (match_operand:SI 1 "register_operand" "0,dax")
1838          (match_operand:QI 2 "nonmemory_operand" "dxi,dax")))]
1839   "TARGET_AM33"
1840   "*
1841 {
1842   if (true_regnum (operands[1]) == true_regnum (operands[0]))
1843     return \"asr %S2,%0\";
1844
1845   if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1846       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1847       && true_regnum (operands[0]) != true_regnum (operands[2]))
1848     return \"mov %1,%0\;asr %S2,%0\";
1849   return \"asr %2,%1,%0\";
1850 }"
1851   [(set_attr "cc" "set_zn")])
1852
1853 (define_insn ""
1854   [(set (match_operand:SI 0 "register_operand" "=dx")
1855         (ashiftrt:SI
1856          (match_operand:SI 1 "register_operand" "0")
1857          (match_operand:QI 2 "nonmemory_operand" "dxi")))]
1858   ""
1859   "asr %S2,%0"
1860   [(set_attr "cc" "set_zn")])
1861
1862 ;; ----------------------------------------------------------------------
1863 ;; FP INSTRUCTIONS
1864 ;; ----------------------------------------------------------------------
1865 ;;
1866 ;; The mn103 series does not have floating point instructions, but since
1867 ;; FP values are held in integer regs, we can clear the high bit easily
1868 ;; which gives us an efficient inline floating point absolute value.
1869 ;;
1870 ;; Similarly for negation of a FP value.
1871 ;;
1872
1873 (define_expand "absdf2"
1874   [(set (match_operand:DF 0 "register_operand" "")
1875         (abs:DF (match_operand:DF 1 "register_operand" "")))]
1876   ""
1877   "
1878 {
1879   rtx target, result, insns;
1880
1881   start_sequence ();
1882   target = operand_subword (operands[0], 1, 1, DFmode);
1883   result = expand_binop (SImode, and_optab,
1884                          operand_subword_force (operands[1], 1, DFmode),
1885                          GEN_INT (0x7fffffff), target, 0, OPTAB_WIDEN);
1886
1887   if (result == 0)
1888     abort ();
1889
1890   if (result != target)
1891     emit_move_insn (result, target);
1892
1893   emit_move_insn (operand_subword (operands[0], 0, 1, DFmode),
1894                   operand_subword_force (operands[1], 0, DFmode));
1895
1896   insns = get_insns ();
1897   end_sequence ();
1898
1899   emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
1900   DONE;
1901 }")
1902
1903 (define_expand "abssf2"
1904   [(set (match_operand:SF 0 "register_operand" "")
1905         (abs:SF (match_operand:SF 1 "register_operand" "")))]
1906   ""
1907   "
1908 {
1909   rtx result;
1910   rtx target;
1911
1912   target = operand_subword_force (operands[0], 0, SFmode);
1913   result = expand_binop (SImode, and_optab,
1914                          operand_subword_force (operands[1], 0, SFmode),
1915                          GEN_INT (0x7fffffff), target, 0, OPTAB_WIDEN);
1916   if (result == 0)
1917     abort ();
1918
1919   if (result != target)
1920     emit_move_insn (result, target);
1921
1922   /* Make a place for REG_EQUAL.  */
1923   emit_move_insn (operands[0], operands[0]);
1924   DONE;
1925 }")
1926
1927
1928 (define_expand "negdf2"
1929   [(set (match_operand:DF 0 "register_operand" "")
1930         (neg:DF (match_operand:DF 1 "register_operand" "")))]
1931   ""
1932   "
1933 {
1934   rtx target, result, insns;
1935
1936   start_sequence ();
1937   target = operand_subword (operands[0], 1, 1, DFmode);
1938   result = expand_binop (SImode, xor_optab,
1939                          operand_subword_force (operands[1], 1, DFmode),
1940                          GEN_INT (trunc_int_for_mode (0x80000000, SImode)),
1941                          target, 0, OPTAB_WIDEN);
1942
1943   if (result == 0)
1944     abort ();
1945
1946   if (result != target)
1947     emit_move_insn (result, target);
1948
1949   emit_move_insn (operand_subword (operands[0], 0, 1, DFmode),
1950                   operand_subword_force (operands[1], 0, DFmode));
1951
1952   insns = get_insns ();
1953   end_sequence ();
1954
1955   emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
1956   DONE;
1957 }")
1958
1959 (define_expand "negsf2"
1960   [(set (match_operand:SF 0 "register_operand" "")
1961         (neg:SF (match_operand:SF 1 "register_operand" "")))]
1962   ""
1963   "
1964 {
1965   rtx result;
1966   rtx target;
1967
1968   target = operand_subword_force (operands[0], 0, SFmode);
1969   result = expand_binop (SImode, xor_optab,
1970                          operand_subword_force (operands[1], 0, SFmode),
1971                          GEN_INT (trunc_int_for_mode (0x80000000, SImode)),
1972                          target, 0, OPTAB_WIDEN);
1973   if (result == 0)
1974     abort ();
1975
1976   if (result != target)
1977     emit_move_insn (result, target);
1978
1979   /* Make a place for REG_EQUAL.  */
1980   emit_move_insn (operands[0], operands[0]);
1981   DONE;
1982 }")
1983
1984
1985 ;; ----------------------------------------------------------------------
1986 ;; PROLOGUE/EPILOGUE
1987 ;; ----------------------------------------------------------------------
1988 (define_expand "prologue"
1989   [(const_int 0)]
1990   ""
1991   "expand_prologue (); DONE;")
1992
1993 (define_expand "epilogue"
1994   [(return)]
1995   ""
1996   "
1997 {
1998   expand_epilogue ();
1999   DONE;
2000 }")
2001
2002 (define_insn "return_internal"
2003   [(const_int 2)
2004    (return)]
2005   ""
2006   "rets"
2007   [(set_attr "cc" "clobber")])
2008
2009 ;; This insn restores the callee saved registers and does a return, it
2010 ;; can also deallocate stack space.
2011 (define_insn "return_internal_regs"
2012   [(const_int 0)
2013    (match_operand:SI 0  "const_int_operand" "i")
2014    (return)]
2015   ""
2016   "*
2017 {
2018   fputs (\"\\tret \", asm_out_file);
2019   mn10300_print_reg_list (asm_out_file, mn10300_get_live_callee_saved_regs ());
2020   fprintf (asm_out_file, \",%d\\n\", (int) INTVAL (operands[0]));
2021   return \"\";
2022 }"
2023   [(set_attr "cc" "clobber")])
2024
2025 ;; This instruction matches one generated by mn10300_gen_multiple_store()
2026 (define_insn "store_movm"
2027   [(match_parallel 0 "store_multiple_operation"
2028     [(set (reg:SI 9) (plus:SI (reg:SI 9) (match_operand 1 "" "")))])]
2029   ""
2030   "*
2031 {
2032   fputs (\"\\tmovm \", asm_out_file);
2033   mn10300_print_reg_list (asm_out_file,
2034                           store_multiple_operation (operands[0], VOIDmode));
2035   fprintf (asm_out_file, \",(sp)\\n\");
2036   return \"\";
2037 }"
2038   [(set_attr "cc" "clobber")])
2039   
2040 (define_insn "return"
2041   [(return)]
2042   "can_use_return_insn ()"
2043   "*
2044 {
2045   rtx next = next_active_insn (insn);
2046
2047   if (next
2048       && GET_CODE (next) == JUMP_INSN
2049       && GET_CODE (PATTERN (next)) == RETURN)
2050     return \"\";
2051   else
2052     return \"rets\";
2053 }"
2054   [(set_attr "cc" "clobber")])
2055
2056 ;; Try to combine consecutive updates of the stack pointer (or any
2057 ;; other register for that matter).
2058 (define_peephole
2059   [(set (match_operand:SI 0 "register_operand" "=dxay")
2060         (plus:SI (match_dup 0)
2061                  (match_operand 1 "const_int_operand" "")))
2062    (set (match_dup 0)
2063         (plus:SI (match_dup 0)
2064                  (match_operand 2 "const_int_operand" "")))]
2065   ""
2066   "*
2067 {
2068   operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]));
2069   return \"add %1,%0\";
2070 }"
2071   [(set_attr "cc" "clobber")])
2072
2073 ;;
2074 ;; We had patterns to check eq/ne, but the they don't work because
2075 ;; 0x80000000 + 0x80000000 = 0x0 with a carry out.
2076 ;;
2077 ;; The Z flag and C flag would be set, and we have no way to
2078 ;; check for the Z flag set and C flag clear.
2079 ;;
2080 ;; This will work on the mn10200 because we can check the ZX flag
2081 ;; if the comparison is in HImode.
2082 (define_peephole
2083   [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2084    (set (pc) (if_then_else (ge (cc0) (const_int 0))
2085                            (match_operand 1 "" "")
2086                            (pc)))]
2087   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2088   "add %0,%0\;bcc %1"
2089   [(set_attr "cc" "clobber")])
2090
2091 (define_peephole
2092   [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2093    (set (pc) (if_then_else (lt (cc0) (const_int 0))
2094                            (match_operand 1 "" "")
2095                            (pc)))]
2096   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2097   "add %0,%0\;bcs %1"
2098   [(set_attr "cc" "clobber")])
2099
2100 (define_peephole
2101   [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2102    (set (pc) (if_then_else (ge (cc0) (const_int 0))
2103                            (pc)
2104                            (match_operand 1 "" "")))]
2105   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2106   "add %0,%0\;bcs %1"
2107   [(set_attr "cc" "clobber")])
2108
2109 (define_peephole
2110   [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2111    (set (pc) (if_then_else (lt (cc0) (const_int 0))
2112                            (pc)
2113                            (match_operand 1 "" "")))]
2114   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2115   "add %0,%0\;bcc %1"
2116   [(set_attr "cc" "clobber")])
2117