OSDN Git Service

770f7c5428e189a4f3009b212b4eec9ee97429b4
[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, 2002
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 "memory_operand" "=R,T")
1262         (and:QI
1263          (match_dup 0)
1264          (not:QI (match_operand:QI 1 "nonmemory_operand" "i,d"))))]
1265   ""
1266   "@
1267   bclr %U1,%A0
1268   bclr %1,%0"
1269   [(set_attr "cc" "clobber,clobber")])
1270
1271 (define_insn ""
1272   [(set (match_operand:QI 0 "nonimmediate_operand" "+R,d")
1273         (subreg:QI
1274           (ior:SI (subreg:SI (match_dup 0) 0)
1275                   (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
1276   ""
1277   "@
1278   bset %U1,%A0
1279   or %1,%0"
1280   [(set_attr "cc" "clobber,set_znv")])
1281
1282 (define_expand "iorqi3"
1283   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1284         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
1285                 (match_operand:QI 2 "nonmemory_operand" "")))]
1286   ""
1287   "")
1288
1289 (define_insn ""
1290   [(set (match_operand:QI 0 "nonimmediate_operand" "=R,T,r")
1291         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
1292                 ;; This constraint should really be nonmemory_operand,
1293                 ;; but making it general_operand, along with the
1294                 ;; condition that not both input operands are MEMs, it
1295                 ;; here helps combine do a better job.
1296                 (match_operand:QI 2 "general_operand" "i,d,ir")))]
1297   "TARGET_AM33 &&
1298    (GET_CODE (operands[2]) != MEM || GET_CODE (operands[1]) != MEM)"
1299   "@
1300   bset %U2,%A0
1301   bset %2,%0
1302   or %2,%0"
1303   [(set_attr "cc" "clobber,clobber,set_znv")])
1304
1305 (define_insn ""
1306   [(set (match_operand:QI 0 "nonimmediate_operand" "=R,T,d")
1307         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
1308                 ;; This constraint should really be nonmemory_operand,
1309                 ;; but making it general_operand, along with the
1310                 ;; condition that not both input operands are MEMs, it
1311                 ;; here helps combine do a better job.
1312                 (match_operand:QI 2 "general_operand" "i,d,id")))]
1313   "GET_CODE (operands[2]) != MEM || GET_CODE (operands[1]) != MEM"
1314   "@
1315   bset %U2,%A0
1316   bset %2,%0
1317   or %2,%0"
1318   [(set_attr "cc" "clobber,clobber,set_znv")])
1319
1320 (define_insn ""
1321   [(set (cc0)
1322      (zero_extract:SI (match_operand:SI 0 "register_operand" "dx")
1323                       (match_operand 1 "const_int_operand" "")
1324                       (match_operand 2 "const_int_operand" "")))]
1325   ""
1326   "*
1327 {
1328   int len = INTVAL (operands[1]);
1329   int bit = INTVAL (operands[2]);
1330   int mask = 0;
1331   rtx xoperands[2];
1332
1333   while (len > 0)
1334     {
1335       mask |= (1 << bit);
1336       bit++;
1337       len--;
1338     }
1339
1340   xoperands[0] = operands[0];
1341   xoperands[1] = GEN_INT (trunc_int_for_mode (mask, SImode));
1342   output_asm_insn (\"btst %1,%0\", xoperands);
1343   return \"\";
1344 }"
1345   [(set_attr "cc" "clobber")])
1346
1347 (define_insn ""
1348   [(set (cc0)
1349      (zero_extract:SI (match_operand:QI 0 "general_operand" "R,dx")
1350                       (match_operand 1 "const_int_operand" "")
1351                       (match_operand 2 "const_int_operand" "")))]
1352   "mask_ok_for_mem_btst (INTVAL (operands[1]), INTVAL (operands[2]))"
1353   "*
1354 {
1355   int len = INTVAL (operands[1]);
1356   int bit = INTVAL (operands[2]);
1357   int mask = 0;
1358   rtx xoperands[2];
1359
1360   while (len > 0)
1361     {
1362       mask |= (1 << bit);
1363       bit++;
1364       len--;
1365     }
1366
1367   /* If the source operand is not a reg (ie it is memory), then extract the
1368      bits from mask that we actually want to test.  Note that the mask will
1369      never cross a byte boundary.  */
1370   if (!REG_P (operands[0]))
1371     {
1372       if (mask & 0xff)
1373         mask = mask & 0xff;
1374       else if (mask & 0xff00)
1375         mask = (mask >> 8) & 0xff;
1376       else if (mask & 0xff0000)
1377         mask = (mask >> 16) & 0xff;
1378       else if (mask & 0xff000000)
1379         mask = (mask >> 24) & 0xff;
1380     }
1381   
1382   xoperands[0] = operands[0];
1383   xoperands[1] = GEN_INT (trunc_int_for_mode (mask, SImode));
1384   if (GET_CODE (operands[0]) == REG)
1385     output_asm_insn (\"btst %1,%0\", xoperands);
1386   else
1387     output_asm_insn (\"btst %U1,%A0\", xoperands);
1388   return \"\";
1389 }"
1390   [(set_attr "cc" "clobber")])
1391
1392 (define_insn ""
1393   [(set (cc0) (and:SI (match_operand:SI 0 "register_operand" "dx")
1394                       (match_operand:SI 1 "const_int_operand" "")))]
1395   ""
1396   "btst %1,%0"
1397   [(set_attr "cc" "clobber")])
1398
1399 (define_insn ""
1400   [(set (cc0)
1401      (and:SI
1402        (subreg:SI (match_operand:QI 0 "general_operand" "R,dx") 0)
1403        (match_operand:SI 1 "const_8bit_operand" "")))]
1404   ""
1405   "@
1406   btst %U1,%A0
1407   btst %1,%0"
1408   [(set_attr "cc" "clobber")])
1409
1410 \f
1411 ;; ----------------------------------------------------------------------
1412 ;; JUMP INSTRUCTIONS
1413 ;; ----------------------------------------------------------------------
1414
1415 ;; Conditional jump instructions
1416
1417 (define_expand "ble"
1418   [(set (pc)
1419         (if_then_else (le (cc0)
1420                           (const_int 0))
1421                       (label_ref (match_operand 0 "" ""))
1422                       (pc)))]
1423   ""
1424   "")
1425
1426 (define_expand "bleu"
1427   [(set (pc)
1428         (if_then_else (leu (cc0)
1429                            (const_int 0))
1430                       (label_ref (match_operand 0 "" ""))
1431                       (pc)))]
1432   ""
1433   "")
1434
1435 (define_expand "bge"
1436   [(set (pc)
1437         (if_then_else (ge (cc0)
1438                           (const_int 0))
1439                       (label_ref (match_operand 0 "" ""))
1440                       (pc)))]
1441   ""
1442   "")
1443
1444 (define_expand "bgeu"
1445   [(set (pc)
1446         (if_then_else (geu (cc0)
1447                            (const_int 0))
1448                       (label_ref (match_operand 0 "" ""))
1449                       (pc)))]
1450   ""
1451   "")
1452
1453 (define_expand "blt"
1454   [(set (pc)
1455         (if_then_else (lt (cc0)
1456                           (const_int 0))
1457                       (label_ref (match_operand 0 "" ""))
1458                       (pc)))]
1459   ""
1460   "")
1461
1462 (define_expand "bltu"
1463   [(set (pc)
1464         (if_then_else (ltu (cc0)
1465                            (const_int 0))
1466                       (label_ref (match_operand 0 "" ""))
1467                       (pc)))]
1468   ""
1469   "")
1470
1471 (define_expand "bgt"
1472   [(set (pc)
1473         (if_then_else (gt (cc0)
1474                           (const_int 0))
1475                       (label_ref (match_operand 0 "" ""))
1476                       (pc)))]
1477   ""
1478   "")
1479
1480 (define_expand "bgtu"
1481   [(set (pc)
1482         (if_then_else (gtu (cc0)
1483                            (const_int 0))
1484                       (label_ref (match_operand 0 "" ""))
1485                       (pc)))]
1486   ""
1487   "")
1488
1489 (define_expand "beq"
1490   [(set (pc)
1491         (if_then_else (eq (cc0)
1492                           (const_int 0))
1493                       (label_ref (match_operand 0 "" ""))
1494                       (pc)))]
1495   ""
1496   "")
1497
1498 (define_expand "bne"
1499   [(set (pc)
1500         (if_then_else (ne (cc0)
1501                           (const_int 0))
1502                       (label_ref (match_operand 0 "" ""))
1503                       (pc)))]
1504   ""
1505   "")
1506
1507 (define_insn ""
1508   [(set (pc)
1509         (if_then_else (match_operator 1 "comparison_operator"
1510                                       [(cc0) (const_int 0)])
1511                       (label_ref (match_operand 0 "" ""))
1512                       (pc)))]
1513   ""
1514   "*
1515 {
1516   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1517       && (GET_CODE (operands[1]) == GT
1518           || GET_CODE (operands[1]) == GE
1519           || GET_CODE (operands[1]) == LE
1520           || GET_CODE (operands[1]) == LT))
1521     return 0;
1522   return \"b%b1 %0\";
1523 }"
1524  [(set_attr "cc" "none")])
1525
1526 (define_insn ""
1527   [(set (pc)
1528         (if_then_else (match_operator 1 "comparison_operator"
1529                                       [(cc0) (const_int 0)])
1530                       (pc)
1531                       (label_ref (match_operand 0 "" ""))))]
1532   ""
1533   "*
1534 {
1535   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1536       && (GET_CODE (operands[1]) == GT
1537           || GET_CODE (operands[1]) == GE
1538           || GET_CODE (operands[1]) == LE
1539           || GET_CODE (operands[1]) == LT))
1540     return 0;
1541   return \"b%B1 %0\";
1542 }"
1543  [(set_attr "cc" "none")])
1544
1545 ;; Unconditional and other jump instructions.
1546
1547 (define_insn "jump"
1548   [(set (pc)
1549         (label_ref (match_operand 0 "" "")))]
1550   ""
1551   "jmp %l0"
1552  [(set_attr "cc" "none")])
1553
1554 (define_insn "indirect_jump"
1555   [(set (pc) (match_operand:SI 0 "register_operand" "a"))]
1556   ""
1557   "jmp (%0)"
1558   [(set_attr "cc" "none")])
1559
1560 (define_insn "tablejump"
1561   [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1562    (use (label_ref (match_operand 1 "" "")))]
1563   ""
1564   "jmp (%0)"
1565   [(set_attr "cc" "none")])
1566
1567 ;; Call subroutine with no return value.
1568
1569 (define_expand "call"
1570   [(call (match_operand:QI 0 "general_operand" "")
1571          (match_operand:SI 1 "general_operand" ""))]
1572   ""
1573   "
1574 {
1575   if (! call_address_operand (XEXP (operands[0], 0), VOIDmode))
1576     XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
1577   emit_call_insn (gen_call_internal (XEXP (operands[0], 0), operands[1]));
1578   DONE;
1579 }")
1580
1581 (define_insn "call_internal"
1582   [(call (mem:QI (match_operand:SI 0 "call_address_operand" "aS"))
1583          (match_operand:SI 1 "general_operand" "g"))]
1584   ""
1585   "*
1586 {
1587   if (REG_P (operands[0]))
1588     return \"calls %C0\";
1589   else
1590     return \"call %C0,[],0\";
1591 }"
1592   [(set_attr "cc" "clobber")])
1593
1594 ;; Call subroutine, returning value in operand 0
1595 ;; (which must be a hard register).
1596
1597 (define_expand "call_value"
1598   [(set (match_operand 0 "" "")
1599         (call (match_operand:QI 1 "general_operand" "")
1600               (match_operand:SI 2 "general_operand" "")))]
1601   ""
1602   "
1603 {
1604   if (! call_address_operand (XEXP (operands[1], 0), VOIDmode))
1605     XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
1606   emit_call_insn (gen_call_value_internal (operands[0],
1607                                            XEXP (operands[1], 0),
1608                                            operands[2]));
1609   DONE;
1610 }")
1611
1612 (define_insn "call_value_internal"
1613   [(set (match_operand 0 "" "=dax")
1614         (call (mem:QI (match_operand:SI 1 "call_address_operand" "aS"))
1615               (match_operand:SI 2 "general_operand" "g")))]
1616   ""
1617   "*
1618 {
1619   if (REG_P (operands[1]))
1620     return \"calls %C1\";
1621   else
1622     return \"call %C1,[],0\";
1623 }"
1624   [(set_attr "cc" "clobber")])
1625
1626 (define_expand "untyped_call"
1627   [(parallel [(call (match_operand 0 "" "")
1628                     (const_int 0))
1629               (match_operand 1 "" "")
1630               (match_operand 2 "" "")])]
1631   ""
1632   "
1633 {
1634   int i;
1635
1636   emit_call_insn (gen_call (operands[0], const0_rtx));
1637
1638   for (i = 0; i < XVECLEN (operands[2], 0); i++)
1639     {
1640       rtx set = XVECEXP (operands[2], 0, i);
1641       emit_move_insn (SET_DEST (set), SET_SRC (set));
1642     }
1643   DONE;
1644 }")
1645
1646 (define_insn "nop"
1647   [(const_int 0)]
1648   ""
1649   "nop"
1650   [(set_attr "cc" "none")])
1651 \f
1652 ;; ----------------------------------------------------------------------
1653 ;; EXTEND INSTRUCTIONS
1654 ;; ----------------------------------------------------------------------
1655
1656 (define_expand "zero_extendqisi2"
1657   [(set (match_operand:SI 0 "general_operand" "")
1658         (zero_extend:SI
1659          (match_operand:QI 1 "general_operand" "")))]
1660   ""
1661   "")
1662
1663 (define_insn ""
1664   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx,!dax,!dax,!dax")
1665         (zero_extend:SI
1666          (match_operand:QI 1 "general_operand" "0,dax,m,0,dax,m")))]
1667   "TARGET_AM33"
1668   "@
1669   extbu %0
1670   mov %1,%0\;extbu %0
1671   movbu %1,%0
1672   extbu %0
1673   mov %1,%0\;extbu %0
1674   movbu %1,%0"
1675   [(set_attr "cc" "none_0hit")])
1676
1677 (define_insn ""
1678   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx")
1679         (zero_extend:SI
1680          (match_operand:QI 1 "general_operand" "0,d,m")))]
1681   ""
1682   "@
1683   extbu %0
1684   mov %1,%0\;extbu %0
1685   movbu %1,%0"
1686   [(set_attr "cc" "none_0hit")])
1687
1688 (define_expand "zero_extendhisi2"
1689   [(set (match_operand:SI 0 "general_operand" "")
1690         (zero_extend:SI
1691          (match_operand:HI 1 "general_operand" "")))]
1692   ""
1693   "")
1694
1695 (define_insn ""
1696   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx,!dax,!dax,!dax")
1697         (zero_extend:SI
1698          (match_operand:HI 1 "general_operand" "0,dax,m,0,dax,m")))]
1699   "TARGET_AM33"
1700   "@
1701   exthu %0
1702   mov %1,%0\;exthu %0
1703   movhu %1,%0
1704   exthu %0
1705   mov %1,%0\;exthu %0
1706   movhu %1,%0"
1707   [(set_attr "cc" "none_0hit")])
1708
1709 (define_insn ""
1710   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx")
1711         (zero_extend:SI
1712          (match_operand:HI 1 "general_operand" "0,dx,m")))]
1713   ""
1714   "@
1715   exthu %0
1716   mov %1,%0\;exthu %0
1717   movhu %1,%0"
1718   [(set_attr "cc" "none_0hit")])
1719
1720 ;;- sign extension instructions
1721
1722 (define_expand "extendqisi2"
1723   [(set (match_operand:SI 0 "general_operand" "")
1724         (sign_extend:SI
1725          (match_operand:QI 1 "general_operand" "")))]
1726   ""
1727   "")
1728
1729 (define_insn ""
1730   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,!dax,!dax")
1731         (sign_extend:SI
1732          (match_operand:QI 1 "general_operand" "0,dx,0,dax")))]
1733   "TARGET_AM33"
1734   "@
1735   extb %0
1736   mov %1,%0\;extb %0
1737   extb %0
1738   mov %1,%0\;extb %0"
1739   [(set_attr "cc" "none_0hit")])
1740
1741 (define_insn ""
1742   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx")
1743         (sign_extend:SI
1744          (match_operand:QI 1 "general_operand" "0,dx")))]
1745   ""
1746   "@
1747   extb %0
1748   mov %1,%0\;extb %0"
1749   [(set_attr "cc" "none_0hit")])
1750
1751 (define_expand "extendhisi2"
1752   [(set (match_operand:SI 0 "general_operand" "")
1753         (sign_extend:SI
1754          (match_operand:HI 1 "general_operand" "")))]
1755   ""
1756   "")
1757
1758 (define_insn ""
1759   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,!dax,!dax")
1760         (sign_extend:SI
1761          (match_operand:HI 1 "general_operand" "0,dax,0,dax")))]
1762   "TARGET_AM33"
1763   "@
1764   exth %0
1765   mov %1,%0\;exth %0
1766   exth %0
1767   mov %1,%0\;exth %0"
1768   [(set_attr "cc" "none_0hit")])
1769
1770 (define_insn ""
1771   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx")
1772         (sign_extend:SI
1773          (match_operand:HI 1 "general_operand" "0,dx")))]
1774   ""
1775   "@
1776   exth %0
1777   mov %1,%0\;exth %0"
1778   [(set_attr "cc" "none_0hit")])
1779 \f
1780 ;; ----------------------------------------------------------------------
1781 ;; SHIFTS
1782 ;; ----------------------------------------------------------------------
1783
1784 (define_expand "ashlsi3"
1785   [(set (match_operand:SI 0 "register_operand" "")
1786         (ashift:SI
1787          (match_operand:SI 1 "register_operand" "")
1788          (match_operand:QI 2 "nonmemory_operand" "")))]
1789   ""
1790   "")
1791
1792 (define_insn ""
1793   [(set (match_operand:SI 0 "register_operand" "=dax,dx,!dax")
1794         (ashift:SI
1795          (match_operand:SI 1 "register_operand" "0,0,dax")
1796          (match_operand:QI 2 "nonmemory_operand" "J,dxi,dax")))]
1797   "TARGET_AM33"
1798   "*
1799 {
1800   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 1)
1801     return \"add %0,%0\";
1802
1803   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 2)
1804     return \"asl2 %0\";
1805
1806   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 3
1807       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS)
1808     return \"asl2 %0\;add %0,%0\";
1809
1810   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 4
1811       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS)
1812     return \"asl2 %0\;asl2 %0\";
1813
1814   if (true_regnum (operands[1]) == true_regnum (operands[0]))
1815     return \"asl %S2,%0\";
1816
1817   if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1818       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1819       && true_regnum (operands[0]) != true_regnum (operands[2]))
1820     return \"mov %1,%0\;asl %S2,%0\";
1821   return \"asl %2,%1,%0\";
1822 }"
1823   [(set_attr "cc" "set_zn")])
1824
1825 (define_insn ""
1826   [(set (match_operand:SI 0 "register_operand" "=dax,dx,dx,dx,dx")
1827         (ashift:SI
1828          (match_operand:SI 1 "register_operand" "0,0,0,0,0")
1829          (match_operand:QI 2 "nonmemory_operand" "J,K,M,L,dxi")))]
1830   ""
1831   "@
1832   add %0,%0
1833   asl2 %0
1834   asl2 %0\;add %0,%0
1835   asl2 %0\;asl2 %0
1836   asl %S2,%0"
1837   [(set_attr "cc" "set_zn")])
1838
1839 (define_expand "lshrsi3"
1840   [(set (match_operand:SI 0 "register_operand" "")
1841         (lshiftrt:SI
1842          (match_operand:SI 1 "register_operand" "")
1843          (match_operand:QI 2 "nonmemory_operand" "")))]
1844   ""
1845   "")
1846
1847 (define_insn ""
1848   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1849         (lshiftrt:SI
1850          (match_operand:SI 1 "register_operand" "0,dax")
1851          (match_operand:QI 2 "nonmemory_operand" "dxi,dax")))]
1852   "TARGET_AM33"
1853   "*
1854 {
1855   if (true_regnum (operands[1]) == true_regnum (operands[0]))
1856     return \"lsr %S2,%0\";
1857
1858   if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1859       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1860       && true_regnum (operands[0]) != true_regnum (operands[2]))
1861     return \"mov %1,%0\;lsr %S2,%0\";
1862   return \"lsr %2,%1,%0\";
1863 }"
1864   [(set_attr "cc" "set_zn")])
1865
1866 (define_insn ""
1867   [(set (match_operand:SI 0 "register_operand" "=dx")
1868         (lshiftrt:SI
1869          (match_operand:SI 1 "register_operand" "0")
1870          (match_operand:QI 2 "nonmemory_operand" "dxi")))]
1871   ""
1872   "lsr %S2,%0"
1873   [(set_attr "cc" "set_zn")])
1874
1875 (define_expand "ashrsi3"
1876   [(set (match_operand:SI 0 "register_operand" "")
1877         (ashiftrt:SI
1878          (match_operand:SI 1 "register_operand" "")
1879          (match_operand:QI 2 "nonmemory_operand" "")))]
1880   ""
1881   "")
1882
1883 (define_insn ""
1884   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1885         (ashiftrt:SI
1886          (match_operand:SI 1 "register_operand" "0,dax")
1887          (match_operand:QI 2 "nonmemory_operand" "dxi,dax")))]
1888   "TARGET_AM33"
1889   "*
1890 {
1891   if (true_regnum (operands[1]) == true_regnum (operands[0]))
1892     return \"asr %S2,%0\";
1893
1894   if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1895       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1896       && true_regnum (operands[0]) != true_regnum (operands[2]))
1897     return \"mov %1,%0\;asr %S2,%0\";
1898   return \"asr %2,%1,%0\";
1899 }"
1900   [(set_attr "cc" "set_zn")])
1901
1902 (define_insn ""
1903   [(set (match_operand:SI 0 "register_operand" "=dx")
1904         (ashiftrt:SI
1905          (match_operand:SI 1 "register_operand" "0")
1906          (match_operand:QI 2 "nonmemory_operand" "dxi")))]
1907   ""
1908   "asr %S2,%0"
1909   [(set_attr "cc" "set_zn")])
1910
1911 ;; ----------------------------------------------------------------------
1912 ;; FP INSTRUCTIONS
1913 ;; ----------------------------------------------------------------------
1914 ;;
1915 ;; The mn103 series does not have floating point instructions, but since
1916 ;; FP values are held in integer regs, we can clear the high bit easily
1917 ;; which gives us an efficient inline floating point absolute value.
1918 ;;
1919 ;; Similarly for negation of a FP value.
1920 ;;
1921
1922 (define_expand "absdf2"
1923   [(set (match_operand:DF 0 "register_operand" "")
1924         (abs:DF (match_operand:DF 1 "register_operand" "")))]
1925   ""
1926   "
1927 {
1928   rtx target, result, insns;
1929
1930   start_sequence ();
1931   target = operand_subword (operands[0], 1, 1, DFmode);
1932   result = expand_binop (SImode, and_optab,
1933                          operand_subword_force (operands[1], 1, DFmode),
1934                          GEN_INT (0x7fffffff), target, 0, OPTAB_WIDEN);
1935
1936   if (result == 0)
1937     abort ();
1938
1939   if (result != target)
1940     emit_move_insn (result, target);
1941
1942   emit_move_insn (operand_subword (operands[0], 0, 1, DFmode),
1943                   operand_subword_force (operands[1], 0, DFmode));
1944
1945   insns = get_insns ();
1946   end_sequence ();
1947
1948   emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
1949   DONE;
1950 }")
1951
1952 (define_expand "abssf2"
1953   [(set (match_operand:SF 0 "register_operand" "")
1954         (abs:SF (match_operand:SF 1 "register_operand" "")))]
1955   ""
1956   "
1957 {
1958   rtx result;
1959   rtx target;
1960
1961   target = operand_subword_force (operands[0], 0, SFmode);
1962   result = expand_binop (SImode, and_optab,
1963                          operand_subword_force (operands[1], 0, SFmode),
1964                          GEN_INT (0x7fffffff), target, 0, OPTAB_WIDEN);
1965   if (result == 0)
1966     abort ();
1967
1968   if (result != target)
1969     emit_move_insn (result, target);
1970
1971   /* Make a place for REG_EQUAL.  */
1972   emit_move_insn (operands[0], operands[0]);
1973   DONE;
1974 }")
1975
1976
1977 (define_expand "negdf2"
1978   [(set (match_operand:DF 0 "register_operand" "")
1979         (neg:DF (match_operand:DF 1 "register_operand" "")))]
1980   ""
1981   "
1982 {
1983   rtx target, result, insns;
1984
1985   start_sequence ();
1986   target = operand_subword (operands[0], 1, 1, DFmode);
1987   result = expand_binop (SImode, xor_optab,
1988                          operand_subword_force (operands[1], 1, DFmode),
1989                          GEN_INT (trunc_int_for_mode (0x80000000, SImode)),
1990                          target, 0, OPTAB_WIDEN);
1991
1992   if (result == 0)
1993     abort ();
1994
1995   if (result != target)
1996     emit_move_insn (result, target);
1997
1998   emit_move_insn (operand_subword (operands[0], 0, 1, DFmode),
1999                   operand_subword_force (operands[1], 0, DFmode));
2000
2001   insns = get_insns ();
2002   end_sequence ();
2003
2004   emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
2005   DONE;
2006 }")
2007
2008 (define_expand "negsf2"
2009   [(set (match_operand:SF 0 "register_operand" "")
2010         (neg:SF (match_operand:SF 1 "register_operand" "")))]
2011   ""
2012   "
2013 {
2014   rtx result;
2015   rtx target;
2016
2017   target = operand_subword_force (operands[0], 0, SFmode);
2018   result = expand_binop (SImode, xor_optab,
2019                          operand_subword_force (operands[1], 0, SFmode),
2020                          GEN_INT (trunc_int_for_mode (0x80000000, SImode)),
2021                          target, 0, OPTAB_WIDEN);
2022   if (result == 0)
2023     abort ();
2024
2025   if (result != target)
2026     emit_move_insn (result, target);
2027
2028   /* Make a place for REG_EQUAL.  */
2029   emit_move_insn (operands[0], operands[0]);
2030   DONE;
2031 }")
2032
2033
2034 ;; ----------------------------------------------------------------------
2035 ;; PROLOGUE/EPILOGUE
2036 ;; ----------------------------------------------------------------------
2037 (define_expand "prologue"
2038   [(const_int 0)]
2039   ""
2040   "expand_prologue (); DONE;")
2041
2042 (define_expand "epilogue"
2043   [(return)]
2044   ""
2045   "
2046 {
2047   expand_epilogue ();
2048   DONE;
2049 }")
2050
2051 (define_insn "return_internal"
2052   [(const_int 2)
2053    (return)]
2054   ""
2055   "rets"
2056   [(set_attr "cc" "clobber")])
2057
2058 ;; This insn restores the callee saved registers and does a return, it
2059 ;; can also deallocate stack space.
2060 (define_insn "return_internal_regs"
2061   [(const_int 0)
2062    (match_operand:SI 0  "const_int_operand" "i")
2063    (return)]
2064   ""
2065   "*
2066 {
2067   fputs (\"\\tret \", asm_out_file);
2068   mn10300_print_reg_list (asm_out_file, mn10300_get_live_callee_saved_regs ());
2069   fprintf (asm_out_file, \",%d\\n\", (int) INTVAL (operands[0]));
2070   return \"\";
2071 }"
2072   [(set_attr "cc" "clobber")])
2073
2074 ;; This instruction matches one generated by mn10300_gen_multiple_store()
2075 (define_insn "store_movm"
2076   [(match_parallel 0 "store_multiple_operation"
2077     [(set (reg:SI 9) (plus:SI (reg:SI 9) (match_operand 1 "" "")))])]
2078   ""
2079   "*
2080 {
2081   fputs (\"\\tmovm \", asm_out_file);
2082   mn10300_print_reg_list (asm_out_file,
2083                           store_multiple_operation (operands[0], VOIDmode));
2084   fprintf (asm_out_file, \",(sp)\\n\");
2085   return \"\";
2086 }"
2087   [(set_attr "cc" "clobber")])
2088   
2089 (define_insn "return"
2090   [(return)]
2091   "can_use_return_insn ()"
2092   "*
2093 {
2094   rtx next = next_active_insn (insn);
2095
2096   if (next
2097       && GET_CODE (next) == JUMP_INSN
2098       && GET_CODE (PATTERN (next)) == RETURN)
2099     return \"\";
2100   else
2101     return \"rets\";
2102 }"
2103   [(set_attr "cc" "clobber")])
2104
2105 ;; Try to combine consecutive updates of the stack pointer (or any
2106 ;; other register for that matter).
2107 (define_peephole
2108   [(set (match_operand:SI 0 "register_operand" "=dxay")
2109         (plus:SI (match_dup 0)
2110                  (match_operand 1 "const_int_operand" "")))
2111    (set (match_dup 0)
2112         (plus:SI (match_dup 0)
2113                  (match_operand 2 "const_int_operand" "")))]
2114   ""
2115   "*
2116 {
2117   operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]));
2118   return \"add %1,%0\";
2119 }"
2120   [(set_attr "cc" "clobber")])
2121
2122 ;;
2123 ;; We had patterns to check eq/ne, but the they don't work because
2124 ;; 0x80000000 + 0x80000000 = 0x0 with a carry out.
2125 ;;
2126 ;; The Z flag and C flag would be set, and we have no way to
2127 ;; check for the Z flag set and C flag clear.
2128 ;;
2129 ;; This will work on the mn10200 because we can check the ZX flag
2130 ;; if the comparison is in HImode.
2131 (define_peephole
2132   [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2133    (set (pc) (if_then_else (ge (cc0) (const_int 0))
2134                            (match_operand 1 "" "")
2135                            (pc)))]
2136   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2137   "add %0,%0\;bcc %1"
2138   [(set_attr "cc" "clobber")])
2139
2140 (define_peephole
2141   [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2142    (set (pc) (if_then_else (lt (cc0) (const_int 0))
2143                            (match_operand 1 "" "")
2144                            (pc)))]
2145   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2146   "add %0,%0\;bcs %1"
2147   [(set_attr "cc" "clobber")])
2148
2149 (define_peephole
2150   [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2151    (set (pc) (if_then_else (ge (cc0) (const_int 0))
2152                            (pc)
2153                            (match_operand 1 "" "")))]
2154   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2155   "add %0,%0\;bcs %1"
2156   [(set_attr "cc" "clobber")])
2157
2158 (define_peephole
2159   [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2160    (set (pc) (if_then_else (lt (cc0) (const_int 0))
2161                            (pc)
2162                            (match_operand 1 "" "")))]
2163   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2164   "add %0,%0\;bcc %1"
2165   [(set_attr "cc" "clobber")])
2166