OSDN Git Service

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