* config/mn10300/mn10300.h (PREDICATE_CODES): Define.
[official-gcc.git] / gcc / config / mn10300 / mn10300.md
bloba615f6b97eaf392f094b396e828e4d1928b79c03
1 ;; GCC machine description for Matsushita MN10300
2 ;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
3 ;; Free Software Foundation, Inc.
4 ;; Contributed by Jeff Law (law@cygnus.com).
6 ;; This file is part of GNU CC.
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.
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.
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.
23 ;; The original PO technology requires these to be ordered by speed,
24 ;; so that assigner will pick the fastest.
26 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
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"))
41 ;; ----------------------------------------------------------------------
42 ;; MOVE INSTRUCTIONS
43 ;; ----------------------------------------------------------------------
45 ;; movqi
47 (define_expand "movqi"
48   [(set (match_operand:QI 0 "general_operand" "")
49         (match_operand:QI 1 "general_operand" ""))]
50   ""
51   "
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 }")
59 (define_insn ""
60   [(set (match_operand:QI 0 "nonimmediate_operand" "=d*x*a*f,d*x,d*x*a,d*x*a,m,*f,d*x*a")
61         (match_operand:QI 1 "general_operand" "0,I,d*xai,m,d*xa,d*xa*f,*f"))]
62   "TARGET_AM33
63    && (register_operand (operands[0], QImode)
64        || register_operand (operands[1], QImode))"
65   "*
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         }
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]);
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     case 5:
97     case 6:
98       return \"fmov %1,%0\";
99     default:
100       abort ();
101     }
103   [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
105 (define_insn ""
106   [(set (match_operand:QI 0 "nonimmediate_operand" "=d*a,d,d*a,d,m")
107         (match_operand:QI 1 "general_operand" "0,I,dai,m,d"))]
108   "register_operand (operands[0], QImode)
109    || register_operand (operands[1], QImode)"
110   "*
112   switch (which_alternative)
113     {
114     case 0:
115       return \"nop\";
116     case 1:
117       return \"clr %0\";
118     case 2:
119       if (GET_CODE (operands[1]) == CONST_DOUBLE)
120         {
121           rtx xoperands[2];
122           xoperands[0] = operands[0];
123           xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
124           output_asm_insn (\"mov %1,%0\", xoperands);
125           return \"\";
126         }
128       return \"mov %1,%0\";
129     case 3:
130     case 4:
131       return \"movbu %1,%0\";
132     default:
133       abort ();
134     }
136   [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit")])
138 ;; movhi
140 (define_expand "movhi"
141   [(set (match_operand:HI 0 "general_operand" "")
142         (match_operand:HI 1 "general_operand" ""))]
143   ""
144   "
146   /* One of the ops has to be in a register */
147   if (!register_operand (operand1, HImode)
148       && !register_operand (operand0, HImode))
149     operands[1] = copy_to_mode_reg (HImode, operand1);
152 (define_insn ""
153   [(set (match_operand:HI 0 "nonimmediate_operand" "=d*x*a*f,d*x,d*x*a,d*x*a,m,*f,d*x*a")
154         (match_operand:HI 1 "general_operand" "0,I,d*x*ai,m,d*x*a,d*x*a*f,*f"))]
155   "TARGET_AM33
156    && (register_operand (operands[0], HImode)
157        || register_operand (operands[1], HImode))"
158   "*
160   switch (which_alternative)
161     {
162     case 0:
163       return \"nop\";
164     case 1:
165       return \"clr %0\";
166     case 2:
167       if (GET_CODE (operands[1]) == CONST_DOUBLE)
168         {
169           rtx xoperands[2];
170           xoperands[0] = operands[0];
171           xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
172           output_asm_insn (\"mov %1,%0\", xoperands);
173           return \"\";
174         }
176       if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
177           && GET_CODE (operands[1]) == CONST_INT)
178         {
179           HOST_WIDE_INT val = INTVAL (operands[1]);
181           if (((val & 0x80) && ! (val & 0xffffff00))
182               || ((val & 0x800000) && ! (val & 0xff000000)))
183             return \"movu %1,%0\";
184         }
185       return \"mov %1,%0\";
186     case 3:
187     case 4:
188       return \"movhu %1,%0\";
189     case 5:
190     case 6:
191       return \"fmov %1,%0\";
192     default:
193       abort ();
194     }
196   [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
198 (define_insn ""
199   [(set (match_operand:HI 0 "nonimmediate_operand" "=d*a,d,d*a,d,m")
200         (match_operand:HI 1 "general_operand" "0,I,dai,m,d"))]
201   "register_operand (operands[0], HImode)
202    || register_operand (operands[1], HImode)"
203   "*
205   switch (which_alternative)
206     {
207     case 0:
208       return \"nop\";
209     case 1:
210       return \"clr %0\";
211     case 2:
212       if (GET_CODE (operands[1]) == CONST_DOUBLE)
213         {
214           rtx xoperands[2];
215           xoperands[0] = operands[0];
216           xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
217           output_asm_insn (\"mov %1,%0\", xoperands);
218           return \"\";
219         }
220       return \"mov %1,%0\";
221     case 3:
222     case 4:
223       return \"movhu %1,%0\";
224     default:
225       abort ();
226     }
228   [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit")])
230 ;; movsi and helpers
232 ;; We use this to handle addition of two values when one operand is the
233 ;; stack pointer and the other is a memory reference of some kind.  Reload
234 ;; does not handle them correctly without this expander.
235 (define_expand "reload_insi"
236   [(set (match_operand:SI 0 "register_operand" "=a")
237         (match_operand:SI 1 "impossible_plus_operand" ""))
238    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
239   ""
240   "
242   if (XEXP (operands[1], 0) == stack_pointer_rtx)
243     {
244       if (GET_CODE (XEXP (operands[1], 1)) == SUBREG
245           && (GET_MODE_SIZE (GET_MODE (XEXP (operands[1], 1)))
246               > GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (operands[1], 1))))))
247         emit_move_insn (operands[2],
248                         gen_rtx_ZERO_EXTEND
249                         (GET_MODE (XEXP (operands[1], 1)),
250                          SUBREG_REG (XEXP (operands[1], 1))));
251       else
252         emit_move_insn (operands[2], XEXP (operands[1], 1));
253       emit_move_insn (operands[0], XEXP (operands[1], 0));
254     }
255   else
256     {
257       if (GET_CODE (XEXP (operands[1], 0)) == SUBREG
258           && (GET_MODE_SIZE (GET_MODE (XEXP (operands[1], 0)))
259               > GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (operands[1], 0))))))
260         emit_move_insn (operands[2],
261                         gen_rtx_ZERO_EXTEND
262                         (GET_MODE (XEXP (operands[1], 0)),
263                          SUBREG_REG (XEXP (operands[1], 0))));
264       else
265         emit_move_insn (operands[2], XEXP (operands[1], 0));
266       emit_move_insn (operands[0], XEXP (operands[1], 1));
267     }
268   emit_insn (gen_addsi3 (operands[0], operands[0], operands[2]));
269   DONE;
272 (define_expand "movsi"
273   [(set (match_operand:SI 0 "general_operand" "")
274         (match_operand:SI 1 "general_operand" ""))]
275   ""
276   "
278   /* One of the ops has to be in a register */
279   if (!register_operand (operand1, SImode)
280       && !register_operand (operand0, SImode))
281     operands[1] = copy_to_mode_reg (SImode, operand1);
284 (define_insn ""
285   [(set (match_operand:SI 0 "nonimmediate_operand"
286                                 "=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax,axR,!*y,*f,*f,dxaQ")
287         (match_operand:SI 1 "general_operand"
288                                 "0,0,I,I,dx,ax,dx,ax,dixm,aixm,dixm,aixm,!*y,axR,0,dxaQi*f,*f"))]
289   "register_operand (operands[0], SImode)
290    || register_operand (operands[1], SImode)"
291   "*
293   switch (which_alternative)
294     {
295     case 0:
296     case 1:
297       return \"nop\";
298     case 2:
299       return \"clr %0\";
300     case 3:
301     case 4:
302     case 5:
303     case 6:
304     case 7:
305     case 8:
306     case 9:
307     case 10:
308     case 11:
309     case 12:
310     case 13:
311       if (GET_CODE (operands[1]) == CONST_DOUBLE)
312         {
313           rtx xoperands[2];
314           xoperands[0] = operands[0];
315           xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
316           output_asm_insn (\"mov %1,%0\", xoperands);
317           return \"\";
318         }
320       if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
321           && GET_CODE (operands[1]) == CONST_INT)
322         {
323           HOST_WIDE_INT val = INTVAL (operands[1]);
325           if (((val & 0x80) && ! (val & 0xffffff00))
326               || ((val & 0x800000) && ! (val & 0xff000000)))
327             return \"movu %1,%0\";
328         }
329       return \"mov %1,%0\";
330     case 14:
331       return \"nop\";
332     case 15:
333     case 16:
334       return \"fmov %1,%0\";
335     default:
336       abort ();
337     }
339   [(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,none,none_0hit,none_0hit")])
341 (define_expand "movsf"
342   [(set (match_operand:SF 0 "general_operand" "")
343         (match_operand:SF 1 "general_operand" ""))]
344   ""
345   "
347   /* One of the ops has to be in a register */
348   if (!register_operand (operand1, SFmode)
349       && !register_operand (operand0, SFmode))
350     operands[1] = copy_to_mode_reg (SFmode, operand1);
353 (define_insn ""
354   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,dx,ax,dx,a,f,dxaQ,daxm,dax")
355         (match_operand:SF 1 "general_operand" "0,0,0,G,G,fdxaQF,f,dax,daxFm"))]
356   "register_operand (operands[0], SFmode)
357    || register_operand (operands[1], SFmode)"
358   "*
360   switch (which_alternative)
361     {
362     case 0:
363     case 1:
364     case 2:
365       return \"nop\";
366     case 3:
367       return \"clr %0\";
368     /* case 4: below */
369     case 5:
370     case 6:
371       return \"fmov %1, %0\";
372     case 4:
373     case 7:
374     case 8:
375       if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
376           && GET_CODE (operands[1]) == CONST_INT)
377         {
378           HOST_WIDE_INT val = INTVAL (operands[1]);
380           if (((val & 0x80) && ! (val & 0xffffff00))
381               || ((val & 0x800000) && ! (val & 0xff000000)))
382             return \"movu %1,%0\";
383         }
384       return \"mov %1,%0\";
385     default:
386       abort ();
387     }
389   [(set_attr "cc" "none,none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
391 (define_expand "movdi"
392   [(set (match_operand:DI 0 "general_operand" "")
393         (match_operand:DI 1 "general_operand" ""))]
394   ""
395   "
397   /* One of the ops has to be in a register */
398   if (!register_operand (operand1, DImode)
399       && !register_operand (operand0, DImode))
400     operands[1] = copy_to_mode_reg (DImode, operand1);
403 (define_insn ""
404   [(set (match_operand:DI 0 "nonimmediate_operand"
405                                 "=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax,*f,*f,*f,dxa,*f,Q")
406         (match_operand:DI 1 "general_operand"
407                                 "0,0,I,I,dx,ax,dx,ax,dxim,axim,dxim,axim,0,*f,dxai,*f,Q,*f"))]
408   "register_operand (operands[0], DImode)
409    || register_operand (operands[1], DImode)"
410   "*
412   long val[2];
413   REAL_VALUE_TYPE rv;
415   switch (which_alternative)
416     {
417       case 0:
418       case 1:
419         return \"nop\";
421       case 2:
422         return \"clr %L0\;clr %H0\";
424       case 3:
425         if (rtx_equal_p (operands[0], operands[1]))
426           return \"sub %L1,%L0\;mov %L0,%H0\";
427         else
428           return \"mov %1,%L0\;mov %L0,%H0\";
429       case 4:
430       case 5:
431       case 6:
432       case 7:
433       case 8:
434       case 9:
435       case 10:
436       case 11:
437         if (GET_CODE (operands[1]) == CONST_INT)
438           {
439             rtx low, high;
440             split_double (operands[1], &low, &high);
441             val[0] = INTVAL (low);
442             val[1] = INTVAL (high);
443           }
444         if (GET_CODE (operands[1]) == CONST_DOUBLE)
445           {
446             if (GET_MODE (operands[1]) == DFmode)
447               {
448                 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
449                 REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
450               }
451             else if (GET_MODE (operands[1]) == VOIDmode
452                      || GET_MODE (operands[1]) == DImode)
453               {
454                 val[0] = CONST_DOUBLE_LOW (operands[1]);
455                 val[1] = CONST_DOUBLE_HIGH (operands[1]);
456               }
457           }
459         if (GET_CODE (operands[1]) == MEM
460             && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
461           {
462             rtx temp = operands[0];
464             while (GET_CODE (temp) == SUBREG)
465               temp = SUBREG_REG (temp);
467             if (GET_CODE (temp) != REG)
468               abort ();
470             if (reg_overlap_mentioned_p (gen_rtx_REG (SImode, REGNO (temp)),
471                                          XEXP (operands[1], 0)))
472               return \"mov %H1,%H0\;mov %L1,%L0\";
473             else
474               return \"mov %L1,%L0\;mov %H1,%H0\";
475               
476           }
477         else if (GET_CODE (operands[1]) == MEM
478                  && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
479                  && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
480           {
481             rtx xoperands[2];
483             xoperands[0] = operands[0];
484             xoperands[1] = XEXP (operands[1], 0);
486             output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\",
487                              xoperands);
488             return \"\";
489           }
490         else
491           {
492             if ((GET_CODE (operands[1]) == CONST_INT
493                  || GET_CODE (operands[1]) == CONST_DOUBLE)
494                 && val[0] == 0)
495               {
496                 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
497                   output_asm_insn (\"clr %L0\", operands);
498                 else
499                   output_asm_insn (\"mov %L1,%L0\", operands);
500               }
501             else if ((GET_CODE (operands[1]) == CONST_INT
502                       || GET_CODE (operands[1]) == CONST_DOUBLE)
503                      && (REGNO_REG_CLASS (true_regnum (operands[0]))
504                          == EXTENDED_REGS)
505                      && (((val[0] & 0x80) && ! (val[0] & 0xffffff00))
506                          || ((val[0] & 0x800000) && ! (val[0] & 0xff000000))))
507               output_asm_insn (\"movu %1,%0\", operands);
508             else
509               output_asm_insn (\"mov %L1,%L0\", operands);
511             if ((GET_CODE (operands[1]) == CONST_INT
512                  || GET_CODE (operands[1]) == CONST_DOUBLE)
513                 && val[1] == 0)
514               {
515                 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
516                   output_asm_insn (\"clr %H0\", operands);
517                 else
518                   output_asm_insn (\"mov %H1,%H0\", operands);
519               }
520             else if ((GET_CODE (operands[1]) == CONST_INT
521                       || GET_CODE (operands[1]) == CONST_DOUBLE)
522                      && val[0] == val[1])
523               output_asm_insn (\"mov %L0,%H0\", operands);
524             else if ((GET_CODE (operands[1]) == CONST_INT
525                       || GET_CODE (operands[1]) == CONST_DOUBLE)
526                      && (REGNO_REG_CLASS (true_regnum (operands[0]))
527                          == EXTENDED_REGS)
528                      && (((val[1] & 0x80) && ! (val[1] & 0xffffff00))
529                          || ((val[1] & 0x800000) && ! (val[1] & 0xff000000))))
530               output_asm_insn (\"movu %1,%0\", operands);
531             else
532               output_asm_insn (\"mov %H1,%H0\", operands);
533             return \"\";
534           }
535       case 12:
536         return \"nop\";
537       case 13:
538       case 14:
539       case 15:
540         return \"fmov %L1, %L0\;fmov %H1, %H0\";
541       case 16:
542         if (GET_CODE (operands[1]) == MEM
543             && GET_CODE (XEXP (operands[1], 0)) == CONST_INT
544             && (INTVAL (XEXP (operands[1], 0)) & 7) == 0)
545           return \"fmov %D1, %D0\";
546         else
547           return \"fmov %L1, %L0\;fmov %H1, %H0\";
548       case 17:
549         if (GET_CODE (operands[0]) == MEM
550             && GET_CODE (XEXP (operands[0], 0)) == CONST_INT
551             && (INTVAL (XEXP (operands[0], 0)) & 7) == 0)
552           return \"fmov %D1, %D0\";
553         else
554           return \"fmov %L1, %L0\;fmov %H1, %H0\";
555     default:
556       abort ();
557     }
559   [(set (attr "cc")
560         (cond
561          [
562          (ior (lt (symbol_ref "which_alternative") (const_int 2))
563               (eq (symbol_ref "which_alternative") (const_int 12))
564               ) (const_string "none")
565          (eq (symbol_ref "which_alternative") (const_int 2)
566              ) (const_string "clobber")
567          (eq (symbol_ref "which_alternative") (const_int 3)
568              ) (if_then_else
569                 (ne (symbol_ref "rtx_equal_p (operands[0], operands[1])")
570                     (const_int 0)) (const_string "clobber")
571                     (const_string "none_0hit"))
572          (ior (eq (symbol_ref "which_alternative") (const_int 8))
573               (eq (symbol_ref "which_alternative") (const_int 9))
574               ) (if_then_else
575                  (ne (symbol_ref "mn10300_wide_const_load_uses_clr
576                                   (operands)")
577                      (const_int 0)) (const_string "clobber")
578                      (const_string "none_0hit"))
579          ] (const_string "none_0hit")))])
581 (define_expand "movdf"
582   [(set (match_operand:DF 0 "general_operand" "")
583         (match_operand:DF 1 "general_operand" ""))]
584   ""
585   "
587   /* One of the ops has to be in a register */
588   if (!register_operand (operand1, DFmode)
589       && !register_operand (operand0, DFmode))
590     operands[1] = copy_to_mode_reg (DFmode, operand1);
593 (define_insn ""
594   [(set (match_operand:DF 0 "nonimmediate_operand"
595                                 "=f,dx,ax,dx,f,f,dxa,f,Q,a,dxm,dxm,axm,axm,dx,dx,ax,ax")
596         (match_operand:DF 1 "general_operand"
597                                 "0,0,0,G,f,dxaF,f,Q,f,G,dx,ax,dx,ax,dxFm,axFm,dxFm,axFm"))]
598   "register_operand (operands[0], DFmode)
599    || register_operand (operands[1], DFmode)"
600   "*
602   long val[2];
603   REAL_VALUE_TYPE rv;
605   switch (which_alternative)
606     {
607       case 0:
608       case 1:
609       case 2:
610         return \"nop\";
612       case 3:
613         return \"clr %L0\;clr %H0\";
615       case 4:
616       case 5:
617       case 6:
618         return \"fmov %L1, %L0\;fmov %H1, %H0\";
620       case 7:
621         if (GET_CODE (operands[1]) == MEM
622             && GET_CODE (XEXP (operands[1], 0)) == CONST_INT
623             && (INTVAL (XEXP (operands[1], 0)) & 7) == 0)
624           return \"fmov %D1, %D0\";
625         else
626           return \"fmov %L1, %L0\;fmov %H1, %H0\";
628       case 8:
629         if (GET_CODE (operands[0]) == MEM
630             && GET_CODE (XEXP (operands[0], 0)) == CONST_INT
631             && (INTVAL (XEXP (operands[0], 0)) & 7) == 0)
632           return \"fmov %D1, %D0\";
633         else
634           return \"fmov %L1, %L0\;fmov %H1, %H0\";
636       case 9:
637          if (rtx_equal_p (operands[0], operands[1]))
638            return \"sub %L1,%L0\;mov %L0,%H0\";
639          else
640            return \"mov %1,%L0\;mov %L0,%H0\";
641       case 10:
642       case 11:
643       case 12:
644       case 13:
645       case 14:
646       case 15:
647       case 16:
648       case 17:
649         if (GET_CODE (operands[1]) == CONST_INT)
650           {
651             rtx low, high;
652             split_double (operands[1], &low, &high);
653             val[0] = INTVAL (low);
654             val[1] = INTVAL (high);
655           }
656         if (GET_CODE (operands[1]) == CONST_DOUBLE)
657           {
658             if (GET_MODE (operands[1]) == DFmode)
659               {
660                 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
661                 REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
662               }
663             else if (GET_MODE (operands[1]) == VOIDmode
664                      || GET_MODE (operands[1]) == DImode)
665               {
666                 val[0] = CONST_DOUBLE_LOW (operands[1]);
667                 val[1] = CONST_DOUBLE_HIGH (operands[1]);
668               }
669           }
671         if (GET_CODE (operands[1]) == MEM
672             && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
673           {
674             rtx temp = operands[0];
676             while (GET_CODE (temp) == SUBREG)
677               temp = SUBREG_REG (temp);
679             if (GET_CODE (temp) != REG)
680               abort ();
682             if (reg_overlap_mentioned_p (gen_rtx_REG (SImode, REGNO (temp)),
683                                          XEXP (operands[1], 0)))
684               return \"mov %H1,%H0\;mov %L1,%L0\";
685             else
686               return \"mov %L1,%L0\;mov %H1,%H0\";
687               
688           }
689         else if (GET_CODE (operands[1]) == MEM
690                  && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
691                  && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
692           {
693             rtx xoperands[2];
695             xoperands[0] = operands[0];
696             xoperands[1] = XEXP (operands[1], 0);
698             output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\",
699                              xoperands);
700             return \"\";
701           }
702         else
703           {
704             if ((GET_CODE (operands[1]) == CONST_INT
705                  || GET_CODE (operands[1]) == CONST_DOUBLE)
706                 && val[0] == 0)
707               {
708                 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
709                   output_asm_insn (\"clr %L0\", operands);
710                 else
711                   output_asm_insn (\"mov %L1,%L0\", operands);
712               }
713             else if ((GET_CODE (operands[1]) == CONST_INT
714                       || GET_CODE (operands[1]) == CONST_DOUBLE)
715                      && (REGNO_REG_CLASS (true_regnum (operands[0]))
716                          == EXTENDED_REGS)
717                      && (((val[0] & 0x80) && ! (val[0] & 0xffffff00))
718                          || ((val[0] & 0x800000) && ! (val[0] & 0xff000000))))
719               output_asm_insn (\"movu %1,%0\", operands);
720             else
721               output_asm_insn (\"mov %L1,%L0\", operands);
723             if ((GET_CODE (operands[1]) == CONST_INT
724                  || GET_CODE (operands[1]) == CONST_DOUBLE)
725                 && val[1] == 0)
726               {
727                 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
728                   output_asm_insn (\"clr %H0\", operands);
729                 else
730                   output_asm_insn (\"mov %H1,%H0\", operands);
731               }
732             else if ((GET_CODE (operands[1]) == CONST_INT
733                       || GET_CODE (operands[1]) == CONST_DOUBLE)
734                      && val[0] == val[1])
735               output_asm_insn (\"mov %L0,%H0\", operands);
736             else if ((GET_CODE (operands[1]) == CONST_INT
737                       || GET_CODE (operands[1]) == CONST_DOUBLE)
738                      && (REGNO_REG_CLASS (true_regnum (operands[0]))
739                          == EXTENDED_REGS)
740                      && (((val[1] & 0x80) && ! (val[1] & 0xffffff00))
741                          || ((val[1] & 0x800000) && ! (val[1] & 0xff000000))))
742               output_asm_insn (\"movu %1,%0\", operands);
743             else
744               output_asm_insn (\"mov %H1,%H0\", operands);
745             return \"\";
746           }
747     default:
748       abort ();
749     }
751   [(set (attr "cc")
752         (cond
753          [
754          (lt (symbol_ref "which_alternative") (const_int 3)
755              ) (const_string "none")
756          (eq (symbol_ref "which_alternative") (const_int 3)
757              ) (const_string "clobber")
758          (eq (symbol_ref "which_alternative") (const_int 9)
759              ) (if_then_else
760                 (ne (symbol_ref "rtx_equal_p (operands[0], operands[1])")
761                     (const_int 0)) (const_string "clobber")
762                     (const_string "none_0hit"))
763          (ior (eq (symbol_ref "which_alternative") (const_int 14))
764               (eq (symbol_ref "which_alternative") (const_int 15))
765               ) (if_then_else
766                  (ne (symbol_ref "mn10300_wide_const_load_uses_clr
767                                   (operands)")
768                      (const_int 0)) (const_string "clobber")
769                      (const_string "none_0hit"))
770          ] (const_string "none_0hit")))])
774 ;; ----------------------------------------------------------------------
775 ;; TEST INSTRUCTIONS
776 ;; ----------------------------------------------------------------------
778 ;; Go ahead and define tstsi so we can eliminate redundant tst insns
779 ;; when we start trying to optimize this port.
780 (define_insn "tstsi"
781   [(set (cc0) (match_operand:SI 0 "register_operand" "dax"))]
782   ""
783   "* return output_tst (operands[0], insn);"
784   [(set_attr "cc" "set_znv")])
786 (define_insn ""
787   [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "dx,!a")))]
788   "TARGET_AM33"
789   "* return output_tst (operands[0], insn);"
790   [(set_attr "cc" "set_znv")])
792 (define_insn ""
793   [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "dx")))]
794   ""
795   "* return output_tst (operands[0], insn);"
796   [(set_attr "cc" "set_znv")])
798 (define_insn ""
799   [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "dx,!a")))]
800   "TARGET_AM33"
801   "* return output_tst (operands[0], insn);"
802   [(set_attr "cc" "set_znv")])
804 (define_insn ""
805   [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "dx")))]
806   ""
807   "* return output_tst (operands[0], insn);"
808   [(set_attr "cc" "set_znv")])
810 ;; Ordinarily, the cmp instruction will set the Z bit of cc0 to 1 if
811 ;; its operands hold equal values, but the operands of a cmp
812 ;; instruction must be distinct registers.  In the case where we'd
813 ;; like to compare a register to itself, we can achieve this effect
814 ;; with a btst 0,d0 instead.  (This will not alter the contents of d0
815 ;; but will have the proper effect on cc0.  Using d0 is arbitrary; any
816 ;; data register would work.)
818 ;; Even though the first alternative would be preferrable if it can
819 ;; possibly match, reload must not be given the opportunity to attempt
820 ;; to use it.  It assumes that such matches can only occur when one of
821 ;; the operands is used for input and the other for output.  Since
822 ;; this is not the case, it abort()s.  Indeed, such a reload cannot be
823 ;; possibly satisfied, so just mark the alternative with a `!', so
824 ;; that it is not considered by reload.
826 (define_insn "cmpsi"
827   [(set (cc0)
828         (compare (match_operand:SI 0 "register_operand" "!*d*a*x,dax")
829                  (match_operand:SI 1 "nonmemory_operand" "*0,daxi")))]
830   ""
831   "@
832   btst 0,d0
833   cmp %1,%0"
834   [(set_attr "cc" "compare,compare")])
836 (define_insn "cmpsf"
837   [(set (cc0)
838         (compare (match_operand:SF 0 "register_operand" "f,f")
839                  (match_operand:SF 1 "nonmemory_operand" "f,F")))]
840   "TARGET_AM33_2"
841   "fcmp %1,%0"
842   [(set_attr "cc" "compare,compare")])
844 ;; ----------------------------------------------------------------------
845 ;; ADD INSTRUCTIONS
846 ;; ----------------------------------------------------------------------
848 (define_expand "addsi3"
849   [(set (match_operand:SI 0 "register_operand" "")
850         (plus:SI (match_operand:SI 1 "register_operand" "")
851                  (match_operand:SI 2 "nonmemory_operand" "")))]
852   ""
853   "")
855 (define_insn ""
856   [(set (match_operand:SI 0 "register_operand" "=dx,a,x,a,dax,!*y,!dax")
857         (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,dax")
858                  (match_operand:SI 2 "nonmemory_operand" "J,J,L,L,daxi,i,dax")))]
859   "TARGET_AM33"
860   "*
862   switch (which_alternative)
863     {
864     case 0:
865     case 1:
866       return \"inc %0\";
867     case 2:
868     case 3:
869       return \"inc4 %0\";
870     case 4:
871     case 5:
872       return \"add %2,%0\";
873     case 6:
874       {
875         enum reg_class src1_class, src2_class, dst_class;
877         src1_class = REGNO_REG_CLASS (true_regnum (operands[1]));
878         src2_class = REGNO_REG_CLASS (true_regnum (operands[2]));
879         dst_class = REGNO_REG_CLASS (true_regnum (operands[0]));
880         
881         /* I'm not sure if this can happen or not.  Might as well be prepared
882           and generate the best possible code if it does happen.  */
883         if (true_regnum (operands[0]) == true_regnum (operands[1]))
884           return \"add %2,%0\";
885         if (true_regnum (operands[0]) == true_regnum (operands[2]))
886           return \"add %1,%0\";
888         /* Catch cases where no extended register was used.  These should be
889            handled just like the mn10300.  */
890         if (src1_class != EXTENDED_REGS
891             && src2_class != EXTENDED_REGS
892             && dst_class != EXTENDED_REGS)
893           {
894             /* We have to copy one of the sources into the destination, then
895                add the other source to the destination.
897                Carefully select which source to copy to the destination; a naive
898                implementation will waste a byte when the source classes are 
899                different and the destination is an address register.  Selecting
900                the lowest cost register copy will optimize this sequence.  */
901             if (REGNO_REG_CLASS (true_regnum (operands[1]))
902                 == REGNO_REG_CLASS (true_regnum (operands[0])))
903               return \"mov %1,%0\;add %2,%0\";
904             return \"mov %2,%0\;add %1,%0\";
905           }
907         /* At least one register is an extended register.  */
909         /* The three operand add instruction on the am33 is a win iff the
910            output register is an extended register, or if both source
911            registers are extended registers.  */
912         if (dst_class == EXTENDED_REGS
913             || src1_class == src2_class)
914           return \"add %2,%1,%0\";
916       /* It is better to copy one of the sources to the destination, then
917          perform a 2 address add.  The destination in this case must be
918          an address or data register and one of the sources must be an
919          extended register and the remaining source must not be an extended
920          register.
922          The best code for this case is to copy the extended reg to the
923          destination, then emit a two address add.  */
924       if (src1_class == EXTENDED_REGS)
925         return \"mov %1,%0\;add %2,%0\";
926       return \"mov %2,%0\;add %1,%0\";
927       }
928     default:
929       abort ();
930     }
932   [(set_attr "cc" "set_zn,none_0hit,set_zn,none_0hit,set_zn,none_0hit,set_zn")])
934 (define_insn ""
935   [(set (match_operand:SI 0 "register_operand" "=dx,a,a,dax,!*y,!dax")
936         (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,dax")
937                  (match_operand:SI 2 "nonmemory_operand" "J,J,L,daxi,i,dax")))]
938   ""
939   "*
941   switch (which_alternative)
942     {
943     case 0:
944     case 1:
945       return \"inc %0\";
946     case 2:
947       return \"inc4 %0\";
948     case 3:
949     case 4:
950       return \"add %2,%0\";
951     case 5:
952       /* I'm not sure if this can happen or not.  Might as well be prepared
953          and generate the best possible code if it does happen.  */
954       if (true_regnum (operands[0]) == true_regnum (operands[1]))
955         return \"add %2,%0\";
956       if (true_regnum (operands[0]) == true_regnum (operands[2]))
957         return \"add %1,%0\";
959       /* We have to copy one of the sources into the destination, then add
960          the other source to the destination.
962          Carefully select which source to copy to the destination; a naive
963          implementation will waste a byte when the source classes are different
964          and the destination is an address register.  Selecting the lowest
965          cost register copy will optimize this sequence.  */
966       if (REGNO_REG_CLASS (true_regnum (operands[1]))
967           == REGNO_REG_CLASS (true_regnum (operands[0])))
968         return \"mov %1,%0\;add %2,%0\";
969       return \"mov %2,%0\;add %1,%0\";
970     default:
971       abort ();
972     }
974   [(set_attr "cc" "set_zn,none_0hit,none_0hit,set_zn,none_0hit,set_zn")])
976 ;; ----------------------------------------------------------------------
977 ;; SUBTRACT INSTRUCTIONS
978 ;; ----------------------------------------------------------------------
980 (define_expand "subsi3"
981   [(set (match_operand:SI 0 "register_operand" "")
982         (minus:SI (match_operand:SI 1 "register_operand" "")
983                   (match_operand:SI 2 "nonmemory_operand" "")))]
984   ""
985   "")
987 (define_insn ""
988   [(set (match_operand:SI 0 "register_operand" "=dax,!dax")
989         (minus:SI (match_operand:SI 1 "register_operand" "0,dax")
990                   (match_operand:SI 2 "nonmemory_operand" "daxi,dax")))]
991   "TARGET_AM33"
992   "*
994   if (true_regnum (operands[0]) == true_regnum (operands[1]))
995     return \"sub %2,%0\";
996   else
997     {
998       enum reg_class src1_class, src2_class, dst_class;
1000       src1_class = REGNO_REG_CLASS (true_regnum (operands[1]));
1001       src2_class = REGNO_REG_CLASS (true_regnum (operands[2]));
1002       dst_class = REGNO_REG_CLASS (true_regnum (operands[0]));
1004       /* If no extended registers are used, then the best way to handle
1005          this is to copy the first source operand into the destination
1006          and emit a two address subtraction.  */
1007       if (src1_class != EXTENDED_REGS
1008           && src2_class != EXTENDED_REGS
1009           && dst_class != EXTENDED_REGS
1010           && true_regnum (operands[0]) != true_regnum (operands[2]))
1011         return \"mov %1,%0\;sub %2,%0\";
1012       return \"sub %2,%1,%0\";
1013     }
1015   [(set_attr "cc" "set_zn")])
1017 (define_insn ""
1018   [(set (match_operand:SI 0 "register_operand" "=dax")
1019         (minus:SI (match_operand:SI 1 "register_operand" "0")
1020                   (match_operand:SI 2 "nonmemory_operand" "daxi")))]
1021   ""
1022   "sub %2,%0"
1023   [(set_attr "cc" "set_zn")])
1025 (define_expand "negsi2"
1026   [(set (match_operand:SI 0 "register_operand" "")
1027         (neg:SI (match_operand:SI 1 "register_operand" "")))]
1028   ""
1029   "
1031   rtx target = gen_reg_rtx (SImode);
1033   emit_move_insn (target, GEN_INT (0));
1034   emit_insn (gen_subsi3 (target, target, operands[1]));
1035   emit_move_insn (operands[0], target);
1036   DONE;
1039 ;; ----------------------------------------------------------------------
1040 ;; MULTIPLY INSTRUCTIONS
1041 ;; ----------------------------------------------------------------------
1043 (define_insn "mulsidi3"
1044   [(set (match_operand:DI 0 "register_operand" "=dax")
1045         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "dax"))
1046                  (sign_extend:DI (match_operand:SI 2 "register_operand" "dax"))))]
1047   "TARGET_AM33"
1048   "mul %1,%2,%H0,%L0"
1049   [(set_attr "cc" "set_zn")])
1051 (define_insn "umulsidi3"
1052   [(set (match_operand:DI 0 "register_operand" "=dax")
1053         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "dax"))
1054                  (zero_extend:DI (match_operand:SI 2 "register_operand" "dax"))))]
1055   "TARGET_AM33"
1056   "mulu %1,%2,%H0,%L0"
1057   [(set_attr "cc" "set_zn")])
1059 (define_expand "mulsi3"
1060   [(set (match_operand:SI 0 "register_operand" "")
1061         (mult:SI (match_operand:SI 1 "register_operand" "")
1062                  (match_operand:SI 2 "register_operand" "")))]
1063   ""
1064   "")
1066 (define_insn ""
1067   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1068         (mult:SI (match_operand:SI 1 "register_operand" "%0,0")
1069                  (match_operand:SI 2 "nonmemory_operand" "dx,daxi")))]
1070   "TARGET_AM33"
1071   "*
1073   if (TARGET_MULT_BUG)
1074     return \"nop\;nop\;mul %2,%0\";
1075   else
1076     return \"mul %2,%0\";
1078   [(set_attr "cc" "set_zn")])
1079   
1080 (define_insn ""
1081   [(set (match_operand:SI 0 "register_operand" "=dx")
1082         (mult:SI (match_operand:SI 1 "register_operand" "%0")
1083                  (match_operand:SI 2 "register_operand" "dx")))]
1084   ""
1085   "*
1087   if (TARGET_MULT_BUG)
1088     return \"nop\;nop\;mul %2,%0\";
1089   else
1090     return \"mul %2,%0\";
1092   [(set_attr "cc" "set_zn")])
1094 (define_insn "udivmodsi4"
1095   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx")
1096         (udiv:SI (match_operand:SI 1 "general_operand" "0")
1097                  (match_operand:SI 2 "general_operand" "dx")))
1098    (set (match_operand:SI 3 "nonimmediate_operand" "=&d")
1099         (umod:SI (match_dup 1) (match_dup 2)))]
1100   ""
1101   "*
1103   output_asm_insn (\"sub %3,%3\;mov %3,mdr\", operands);
1105   if (find_reg_note (insn, REG_UNUSED, operands[3]))
1106     return \"divu %2,%0\";
1107   else
1108     return \"divu %2,%0\;mov mdr,%3\";
1110   [(set_attr "cc" "set_zn")])
1112 (define_insn "divmodsi4"
1113   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx")
1114         (div:SI (match_operand:SI 1 "general_operand" "0")
1115                  (match_operand:SI 2 "general_operand" "dx")))
1116    (set (match_operand:SI 3 "nonimmediate_operand" "=d")
1117         (mod:SI (match_dup 1) (match_dup 2)))]
1118   ""
1119   "*
1121   if (find_reg_note (insn, REG_UNUSED, operands[3]))
1122     return \"ext %0\;div %2,%0\";
1123   else
1124     return \"ext %0\;div %2,%0\;mov mdr,%3\";
1126   [(set_attr "cc" "set_zn")])
1129 ;; ----------------------------------------------------------------------
1130 ;; AND INSTRUCTIONS
1131 ;; ----------------------------------------------------------------------
1133 (define_expand "andsi3"
1134   [(set (match_operand:SI 0 "register_operand" "")
1135         (and:SI (match_operand:SI 1 "register_operand" "")
1136                 (match_operand:SI 2 "nonmemory_operand" "")))]
1137   ""
1138   "")
1140 (define_insn ""
1141   [(set (match_operand:SI 0 "register_operand" "=dx,dx,!dax")
1142         (and:SI (match_operand:SI 1 "register_operand" "%0,0,dax")
1143                 (match_operand:SI 2 "nonmemory_operand" "N,dxi,dax")))]
1144   "TARGET_AM33"
1145   "*
1147   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff)
1148     return \"extbu %0\";
1149   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xffff)
1150     return \"exthu %0\";
1151   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x7fffffff)
1152     return \"add %0,%0\;lsr 1,%0\";
1153   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x3fffffff)
1154     return \"asl2 %0\;lsr 2,%0\";
1155   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x1fffffff)
1156     return \"add %0,%0\;asl2 %0\;lsr 3,%0\";
1157   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x0fffffff)
1158     return \"asl2 %0\;asl2 %0\;lsr 4,%0\";
1159   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffe)
1160     return \"lsr 1,%0\;add %0,%0\";
1161   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffc)
1162     return \"lsr 2,%0\;asl2 %0\";
1163   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff8)
1164     return \"lsr 3,%0\;add %0,%0\;asl2 %0\";
1165   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff0)
1166     return \"lsr 4,%0\;asl2 %0\;asl2 %0\";
1167   if (REG_P (operands[2]) && REG_P (operands[1])
1168       && true_regnum (operands[0]) != true_regnum (operands[1])
1169       && true_regnum (operands[0]) != true_regnum (operands[2])
1170       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1171       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1172       && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
1173     return \"mov %1,%0\;and %2,%0\";
1174   if (REG_P (operands[2]) && REG_P (operands[1])
1175       && true_regnum (operands[0]) != true_regnum (operands[1])
1176       && true_regnum (operands[0]) != true_regnum (operands[2]))
1177     return \"and %1,%2,%0\";
1178   if (REG_P (operands[2]) && REG_P (operands[0])
1179       && true_regnum (operands[2]) == true_regnum (operands[0]))
1180     return \"and %1,%0\";
1181   return \"and %2,%0\";
1183   [(set_attr "cc" "none_0hit,set_znv,set_znv")])
1185 (define_insn ""
1186   [(set (match_operand:SI 0 "register_operand" "=dx,dx")
1187         (and:SI (match_operand:SI 1 "register_operand" "%0,0")
1188                 (match_operand:SI 2 "nonmemory_operand" "N,dxi")))]
1189   ""
1190   "*
1192   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff)
1193     return \"extbu %0\";
1194   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xffff)
1195     return \"exthu %0\";
1196   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x7fffffff)
1197     return \"add %0,%0\;lsr 1,%0\";
1198   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x3fffffff)
1199     return \"asl2 %0\;lsr 2,%0\";
1200   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x1fffffff)
1201     return \"add %0,%0\;asl2 %0\;lsr 3,%0\";
1202   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x0fffffff)
1203     return \"asl2 %0\;asl2 %0\;lsr 4,%0\";
1204   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffe)
1205     return \"lsr 1,%0\;add %0,%0\";
1206   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffc)
1207     return \"lsr 2,%0\;asl2 %0\";
1208   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff8)
1209     return \"lsr 3,%0\;add %0,%0\;asl2 %0\";
1210   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff0)
1211     return \"lsr 4,%0\;asl2 %0\;asl2 %0\";
1212   return \"and %2,%0\";
1214   [(set_attr "cc" "none_0hit,set_znv")])
1216 ;; ----------------------------------------------------------------------
1217 ;; OR INSTRUCTIONS
1218 ;; ----------------------------------------------------------------------
1220 (define_expand "iorsi3"
1221   [(set (match_operand:SI 0 "register_operand" "")
1222         (ior:SI (match_operand:SI 1 "register_operand" "")
1223                 (match_operand:SI 2 "nonmemory_operand" "")))]
1224   ""
1225   "")
1227 (define_insn ""
1228   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1229         (ior:SI (match_operand:SI 1 "register_operand" "%0,dax")
1230                 (match_operand:SI 2 "nonmemory_operand" "dxi,dax")))]
1231   "TARGET_AM33"
1232   "*
1234   if (REG_P (operands[2]) && REG_P (operands[1])
1235       && true_regnum (operands[0]) != true_regnum (operands[1])
1236       && true_regnum (operands[0]) != true_regnum (operands[2])
1237       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1238       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1239       && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
1240     return \"mov %1,%0\;or %2,%0\";
1241   if (REG_P (operands[2]) && REG_P (operands[1])
1242       && true_regnum (operands[0]) != true_regnum (operands[1])
1243       && true_regnum (operands[0]) != true_regnum (operands[2]))
1244     return \"or %1,%2,%0\";
1245   if (REG_P (operands[2]) && REG_P (operands[0])
1246       && true_regnum (operands[2]) == true_regnum (operands[0]))
1247     return \"or %1,%0\";
1248   return \"or %2,%0\";
1250   [(set_attr "cc" "set_znv")])
1252 (define_insn ""
1253   [(set (match_operand:SI 0 "register_operand" "=dx")
1254         (ior:SI (match_operand:SI 1 "register_operand" "%0")
1255                 (match_operand:SI 2 "nonmemory_operand" "dxi")))]
1256   ""
1257   "or %2,%0"
1258   [(set_attr "cc" "set_znv")])
1260 ;; ----------------------------------------------------------------------
1261 ;; XOR INSTRUCTIONS
1262 ;; ----------------------------------------------------------------------
1264 (define_expand "xorsi3"
1265   [(set (match_operand:SI 0 "register_operand" "")
1266         (xor:SI (match_operand:SI 1 "register_operand" "")
1267                 (match_operand:SI 2 "nonmemory_operand" "")))]
1268   ""
1269   "")
1271 (define_insn ""
1272   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1273         (xor:SI (match_operand:SI 1 "register_operand" "%0,dax")
1274                 (match_operand:SI 2 "nonmemory_operand" "dxi,dax")))]
1275   "TARGET_AM33"
1276   "*
1278   if (REG_P (operands[2]) && REG_P (operands[1])
1279       && true_regnum (operands[0]) != true_regnum (operands[1])
1280       && true_regnum (operands[0]) != true_regnum (operands[2])
1281       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1282       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1283       && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
1284     return \"mov %1,%0\;xor %2,%0\";
1285   if (REG_P (operands[2]) && REG_P (operands[1])
1286       && true_regnum (operands[0]) != true_regnum (operands[1])
1287       && true_regnum (operands[0]) != true_regnum (operands[2]))
1288     return \"xor %1,%2,%0\";
1289   if (REG_P (operands[2]) && REG_P (operands[0])
1290       && true_regnum (operands[2]) == true_regnum (operands[0]))
1291     return \"xor %1,%0\";
1292   return \"xor %2,%0\";
1294   [(set_attr "cc" "set_znv")])
1296 (define_insn ""
1297   [(set (match_operand:SI 0 "register_operand" "=dx")
1298         (xor:SI (match_operand:SI 1 "register_operand" "%0")
1299                 (match_operand:SI 2 "nonmemory_operand" "dxi")))]
1300   ""
1301   "xor %2,%0"
1302   [(set_attr "cc" "set_znv")])
1304 ;; ----------------------------------------------------------------------
1305 ;; NOT INSTRUCTIONS
1306 ;; ----------------------------------------------------------------------
1308 (define_expand "one_cmplsi2"
1309   [(set (match_operand:SI 0 "register_operand" "")
1310         (not:SI (match_operand:SI 1 "register_operand" "")))]
1311   ""
1312   "")
1314 (define_insn ""
1315   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1316         (not:SI (match_operand:SI 1 "register_operand" "0,0")))]
1317   "TARGET_AM33"
1318   "not %0"
1319   [(set_attr "cc" "set_znv")])
1321 (define_insn ""
1322   [(set (match_operand:SI 0 "register_operand" "=dx")
1323         (not:SI (match_operand:SI 1 "register_operand" "0")))]
1324   ""
1325   "not %0"
1326   [(set_attr "cc" "set_znv")])
1328 ;; -----------------------------------------------------------------
1329 ;; BIT FIELDS
1330 ;; -----------------------------------------------------------------
1333 ;; These set/clear memory in byte sized chunks.
1335 ;; They are no smaller/faster than loading the value into a register
1336 ;; and storing the register, but they don't need a scratch register
1337 ;; which may allow for better code generation.
1338 (define_insn ""
1339   [(set (match_operand:QI 0 "nonimmediate_operand" "=R,d") (const_int 0))]
1340   ""
1341   "@
1342   bclr 255,%A0
1343   clr %0"
1344   [(set_attr "cc" "clobber")])
1346 (define_insn ""
1347   [(set (match_operand:QI 0 "nonimmediate_operand" "=R,d") (const_int -1))]
1348   ""
1349   "@
1350   bset 255,%A0
1351   mov -1,%0"
1352   [(set_attr "cc" "clobber,none_0hit")])
1354 (define_insn ""
1355   [(set (match_operand:QI 0 "nonimmediate_operand" "+R,d")
1356         (subreg:QI
1357           (and:SI (subreg:SI (match_dup 0) 0)
1358                   (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
1359   ""
1360   "@
1361   bclr %N1,%A0
1362   and %1,%0"
1363   [(set_attr "cc" "clobber,set_znv")])
1365 (define_insn ""
1366   [(set (match_operand:QI 0 "memory_operand" "=R,T")
1367         (and:QI
1368          (match_dup 0)
1369          (not:QI (match_operand:QI 1 "nonmemory_operand" "i,d"))))]
1370   ""
1371   "@
1372   bclr %U1,%A0
1373   bclr %1,%0"
1374   [(set_attr "cc" "clobber,clobber")])
1376 (define_insn ""
1377   [(set (match_operand:QI 0 "nonimmediate_operand" "+R,d")
1378         (subreg:QI
1379           (ior:SI (subreg:SI (match_dup 0) 0)
1380                   (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
1381   ""
1382   "@
1383   bset %U1,%A0
1384   or %1,%0"
1385   [(set_attr "cc" "clobber,set_znv")])
1387 (define_expand "iorqi3"
1388   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1389         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
1390                 (match_operand:QI 2 "nonmemory_operand" "")))]
1391   ""
1392   "")
1394 (define_insn ""
1395   [(set (match_operand:QI 0 "nonimmediate_operand" "=R,T,r")
1396         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
1397                 ;; This constraint should really be nonmemory_operand,
1398                 ;; but making it general_operand, along with the
1399                 ;; condition that not both input operands are MEMs, it
1400                 ;; here helps combine do a better job.
1401                 (match_operand:QI 2 "general_operand" "i,d,ir")))]
1402   "TARGET_AM33 &&
1403    (GET_CODE (operands[2]) != MEM || GET_CODE (operands[1]) != MEM)"
1404   "@
1405   bset %U2,%A0
1406   bset %2,%0
1407   or %2,%0"
1408   [(set_attr "cc" "clobber,clobber,set_znv")])
1410 (define_insn ""
1411   [(set (match_operand:QI 0 "nonimmediate_operand" "=R,T,d")
1412         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
1413                 ;; This constraint should really be nonmemory_operand,
1414                 ;; but making it general_operand, along with the
1415                 ;; condition that not both input operands are MEMs, it
1416                 ;; here helps combine do a better job.
1417                 (match_operand:QI 2 "general_operand" "i,d,id")))]
1418   "GET_CODE (operands[2]) != MEM || GET_CODE (operands[1]) != MEM"
1419   "@
1420   bset %U2,%A0
1421   bset %2,%0
1422   or %2,%0"
1423   [(set_attr "cc" "clobber,clobber,set_znv")])
1425 (define_insn ""
1426   [(set (cc0)
1427      (zero_extract:SI (match_operand:SI 0 "register_operand" "dx")
1428                       (match_operand 1 "const_int_operand" "")
1429                       (match_operand 2 "const_int_operand" "")))]
1430   ""
1431   "*
1433   int len = INTVAL (operands[1]);
1434   int bit = INTVAL (operands[2]);
1435   int mask = 0;
1436   rtx xoperands[2];
1438   while (len > 0)
1439     {
1440       mask |= (1 << bit);
1441       bit++;
1442       len--;
1443     }
1445   xoperands[0] = operands[0];
1446   xoperands[1] = GEN_INT (trunc_int_for_mode (mask, SImode));
1447   output_asm_insn (\"btst %1,%0\", xoperands);
1448   return \"\";
1450   [(set_attr "cc" "clobber")])
1452 (define_insn ""
1453   [(set (cc0)
1454      (zero_extract:SI (match_operand:QI 0 "general_operand" "R,dx")
1455                       (match_operand 1 "const_int_operand" "")
1456                       (match_operand 2 "const_int_operand" "")))]
1457   "mask_ok_for_mem_btst (INTVAL (operands[1]), INTVAL (operands[2]))"
1458   "*
1460   int len = INTVAL (operands[1]);
1461   int bit = INTVAL (operands[2]);
1462   int mask = 0;
1463   rtx xoperands[2];
1465   while (len > 0)
1466     {
1467       mask |= (1 << bit);
1468       bit++;
1469       len--;
1470     }
1472   /* If the source operand is not a reg (ie it is memory), then extract the
1473      bits from mask that we actually want to test.  Note that the mask will
1474      never cross a byte boundary.  */
1475   if (!REG_P (operands[0]))
1476     {
1477       if (mask & 0xff)
1478         mask = mask & 0xff;
1479       else if (mask & 0xff00)
1480         mask = (mask >> 8) & 0xff;
1481       else if (mask & 0xff0000)
1482         mask = (mask >> 16) & 0xff;
1483       else if (mask & 0xff000000)
1484         mask = (mask >> 24) & 0xff;
1485     }
1486   
1487   xoperands[0] = operands[0];
1488   xoperands[1] = GEN_INT (trunc_int_for_mode (mask, SImode));
1489   if (GET_CODE (operands[0]) == REG)
1490     output_asm_insn (\"btst %1,%0\", xoperands);
1491   else
1492     output_asm_insn (\"btst %U1,%A0\", xoperands);
1493   return \"\";
1495   [(set_attr "cc" "clobber")])
1497 (define_insn ""
1498   [(set (cc0) (and:SI (match_operand:SI 0 "register_operand" "dx")
1499                       (match_operand:SI 1 "const_int_operand" "")))]
1500   ""
1501   "btst %1,%0"
1502   [(set_attr "cc" "clobber")])
1504 (define_insn ""
1505   [(set (cc0)
1506      (and:SI
1507        (subreg:SI (match_operand:QI 0 "general_operand" "R,dx") 0)
1508        (match_operand:SI 1 "const_8bit_operand" "")))]
1509   ""
1510   "@
1511   btst %U1,%A0
1512   btst %1,%0"
1513   [(set_attr "cc" "clobber")])
1516 ;; ----------------------------------------------------------------------
1517 ;; JUMP INSTRUCTIONS
1518 ;; ----------------------------------------------------------------------
1520 ;; Conditional jump instructions
1522 (define_expand "ble"
1523   [(set (pc)
1524         (if_then_else (le (cc0)
1525                           (const_int 0))
1526                       (label_ref (match_operand 0 "" ""))
1527                       (pc)))]
1528   ""
1529   "")
1531 (define_expand "bleu"
1532   [(set (pc)
1533         (if_then_else (leu (cc0)
1534                            (const_int 0))
1535                       (label_ref (match_operand 0 "" ""))
1536                       (pc)))]
1537   ""
1538   "")
1540 (define_expand "bge"
1541   [(set (pc)
1542         (if_then_else (ge (cc0)
1543                           (const_int 0))
1544                       (label_ref (match_operand 0 "" ""))
1545                       (pc)))]
1546   ""
1547   "")
1549 (define_expand "bgeu"
1550   [(set (pc)
1551         (if_then_else (geu (cc0)
1552                            (const_int 0))
1553                       (label_ref (match_operand 0 "" ""))
1554                       (pc)))]
1555   ""
1556   "")
1558 (define_expand "blt"
1559   [(set (pc)
1560         (if_then_else (lt (cc0)
1561                           (const_int 0))
1562                       (label_ref (match_operand 0 "" ""))
1563                       (pc)))]
1564   ""
1565   "")
1567 (define_expand "bltu"
1568   [(set (pc)
1569         (if_then_else (ltu (cc0)
1570                            (const_int 0))
1571                       (label_ref (match_operand 0 "" ""))
1572                       (pc)))]
1573   ""
1574   "")
1576 (define_expand "bgt"
1577   [(set (pc)
1578         (if_then_else (gt (cc0)
1579                           (const_int 0))
1580                       (label_ref (match_operand 0 "" ""))
1581                       (pc)))]
1582   ""
1583   "")
1585 (define_expand "bgtu"
1586   [(set (pc)
1587         (if_then_else (gtu (cc0)
1588                            (const_int 0))
1589                       (label_ref (match_operand 0 "" ""))
1590                       (pc)))]
1591   ""
1592   "")
1594 (define_expand "beq"
1595   [(set (pc)
1596         (if_then_else (eq (cc0)
1597                           (const_int 0))
1598                       (label_ref (match_operand 0 "" ""))
1599                       (pc)))]
1600   ""
1601   "")
1603 (define_expand "bne"
1604   [(set (pc)
1605         (if_then_else (ne (cc0)
1606                           (const_int 0))
1607                       (label_ref (match_operand 0 "" ""))
1608                       (pc)))]
1609   ""
1610   "")
1612 (define_insn ""
1613   [(set (pc)
1614         (if_then_else (match_operator 1 "comparison_operator"
1615                                       [(cc0) (const_int 0)])
1616                       (label_ref (match_operand 0 "" ""))
1617                       (pc)))]
1618   ""
1619   "*
1621   if (cc_status.mdep.fpCC)
1622     return \"fb%b1 %0\";
1623   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1624       && (GET_CODE (operands[1]) == GT
1625           || GET_CODE (operands[1]) == GE
1626           || GET_CODE (operands[1]) == LE
1627           || GET_CODE (operands[1]) == LT))
1628     return 0;
1629   return \"b%b1 %0\";
1631  [(set_attr "cc" "none")])
1633 (define_insn ""
1634   [(set (pc)
1635         (if_then_else (match_operator 1 "comparison_operator"
1636                                       [(cc0) (const_int 0)])
1637                       (pc)
1638                       (label_ref (match_operand 0 "" ""))))]
1639   ""
1640   "*
1642   if (cc_status.mdep.fpCC)
1643     return \"fb%B1 %0\";
1644   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1645       && (GET_CODE (operands[1]) == GT
1646           || GET_CODE (operands[1]) == GE
1647           || GET_CODE (operands[1]) == LE
1648           || GET_CODE (operands[1]) == LT))
1649     return 0;
1650   return \"b%B1 %0\";
1652  [(set_attr "cc" "none")])
1654 ;; Unconditional and other jump instructions.
1656 (define_insn "jump"
1657   [(set (pc)
1658         (label_ref (match_operand 0 "" "")))]
1659   ""
1660   "jmp %l0"
1661  [(set_attr "cc" "none")])
1663 (define_insn "indirect_jump"
1664   [(set (pc) (match_operand:SI 0 "register_operand" "a"))]
1665   ""
1666   "jmp (%0)"
1667   [(set_attr "cc" "none")])
1669 (define_insn "tablejump"
1670   [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1671    (use (label_ref (match_operand 1 "" "")))]
1672   ""
1673   "jmp (%0)"
1674   [(set_attr "cc" "none")])
1676 ;; Call subroutine with no return value.
1678 (define_expand "call"
1679   [(call (match_operand:QI 0 "general_operand" "")
1680          (match_operand:SI 1 "general_operand" ""))]
1681   ""
1682   "
1684   if (! call_address_operand (XEXP (operands[0], 0), VOIDmode))
1685     XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
1686   emit_call_insn (gen_call_internal (XEXP (operands[0], 0), operands[1]));
1687   DONE;
1690 (define_insn "call_internal"
1691   [(call (mem:QI (match_operand:SI 0 "call_address_operand" "aS"))
1692          (match_operand:SI 1 "general_operand" "g"))]
1693   ""
1694   "*
1696   if (REG_P (operands[0]))
1697     return \"calls %C0\";
1698   else
1699     return \"call %C0,[],0\";
1701   [(set_attr "cc" "clobber")])
1703 ;; Call subroutine, returning value in operand 0
1704 ;; (which must be a hard register).
1706 (define_expand "call_value"
1707   [(set (match_operand 0 "" "")
1708         (call (match_operand:QI 1 "general_operand" "")
1709               (match_operand:SI 2 "general_operand" "")))]
1710   ""
1711   "
1713   if (! call_address_operand (XEXP (operands[1], 0), VOIDmode))
1714     XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
1715   emit_call_insn (gen_call_value_internal (operands[0],
1716                                            XEXP (operands[1], 0),
1717                                            operands[2]));
1718   DONE;
1721 (define_insn "call_value_internal"
1722   [(set (match_operand 0 "" "=dax")
1723         (call (mem:QI (match_operand:SI 1 "call_address_operand" "aS"))
1724               (match_operand:SI 2 "general_operand" "g")))]
1725   ""
1726   "*
1728   if (REG_P (operands[1]))
1729     return \"calls %C1\";
1730   else
1731     return \"call %C1,[],0\";
1733   [(set_attr "cc" "clobber")])
1735 (define_expand "untyped_call"
1736   [(parallel [(call (match_operand 0 "" "")
1737                     (const_int 0))
1738               (match_operand 1 "" "")
1739               (match_operand 2 "" "")])]
1740   ""
1741   "
1743   int i;
1745   emit_call_insn (gen_call (operands[0], const0_rtx));
1747   for (i = 0; i < XVECLEN (operands[2], 0); i++)
1748     {
1749       rtx set = XVECEXP (operands[2], 0, i);
1750       emit_move_insn (SET_DEST (set), SET_SRC (set));
1751     }
1752   DONE;
1755 (define_insn "nop"
1756   [(const_int 0)]
1757   ""
1758   "nop"
1759   [(set_attr "cc" "none")])
1761 ;; ----------------------------------------------------------------------
1762 ;; EXTEND INSTRUCTIONS
1763 ;; ----------------------------------------------------------------------
1765 (define_expand "zero_extendqisi2"
1766   [(set (match_operand:SI 0 "general_operand" "")
1767         (zero_extend:SI
1768          (match_operand:QI 1 "general_operand" "")))]
1769   ""
1770   "")
1772 (define_insn ""
1773   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx,!dax,!dax,!dax")
1774         (zero_extend:SI
1775          (match_operand:QI 1 "general_operand" "0,dax,m,0,dax,m")))]
1776   "TARGET_AM33"
1777   "@
1778   extbu %0
1779   mov %1,%0\;extbu %0
1780   movbu %1,%0
1781   extbu %0
1782   mov %1,%0\;extbu %0
1783   movbu %1,%0"
1784   [(set_attr "cc" "none_0hit")])
1786 (define_insn ""
1787   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx")
1788         (zero_extend:SI
1789          (match_operand:QI 1 "general_operand" "0,d,m")))]
1790   ""
1791   "@
1792   extbu %0
1793   mov %1,%0\;extbu %0
1794   movbu %1,%0"
1795   [(set_attr "cc" "none_0hit")])
1797 (define_expand "zero_extendhisi2"
1798   [(set (match_operand:SI 0 "general_operand" "")
1799         (zero_extend:SI
1800          (match_operand:HI 1 "general_operand" "")))]
1801   ""
1802   "")
1804 (define_insn ""
1805   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx,!dax,!dax,!dax")
1806         (zero_extend:SI
1807          (match_operand:HI 1 "general_operand" "0,dax,m,0,dax,m")))]
1808   "TARGET_AM33"
1809   "@
1810   exthu %0
1811   mov %1,%0\;exthu %0
1812   movhu %1,%0
1813   exthu %0
1814   mov %1,%0\;exthu %0
1815   movhu %1,%0"
1816   [(set_attr "cc" "none_0hit")])
1818 (define_insn ""
1819   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx")
1820         (zero_extend:SI
1821          (match_operand:HI 1 "general_operand" "0,dx,m")))]
1822   ""
1823   "@
1824   exthu %0
1825   mov %1,%0\;exthu %0
1826   movhu %1,%0"
1827   [(set_attr "cc" "none_0hit")])
1829 ;;- sign extension instructions
1831 (define_expand "extendqisi2"
1832   [(set (match_operand:SI 0 "general_operand" "")
1833         (sign_extend:SI
1834          (match_operand:QI 1 "general_operand" "")))]
1835   ""
1836   "")
1838 (define_insn ""
1839   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,!dax,!dax")
1840         (sign_extend:SI
1841          (match_operand:QI 1 "general_operand" "0,dx,0,dax")))]
1842   "TARGET_AM33"
1843   "@
1844   extb %0
1845   mov %1,%0\;extb %0
1846   extb %0
1847   mov %1,%0\;extb %0"
1848   [(set_attr "cc" "none_0hit")])
1850 (define_insn ""
1851   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx")
1852         (sign_extend:SI
1853          (match_operand:QI 1 "general_operand" "0,dx")))]
1854   ""
1855   "@
1856   extb %0
1857   mov %1,%0\;extb %0"
1858   [(set_attr "cc" "none_0hit")])
1860 (define_expand "extendhisi2"
1861   [(set (match_operand:SI 0 "general_operand" "")
1862         (sign_extend:SI
1863          (match_operand:HI 1 "general_operand" "")))]
1864   ""
1865   "")
1867 (define_insn ""
1868   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,!dax,!dax")
1869         (sign_extend:SI
1870          (match_operand:HI 1 "general_operand" "0,dax,0,dax")))]
1871   "TARGET_AM33"
1872   "@
1873   exth %0
1874   mov %1,%0\;exth %0
1875   exth %0
1876   mov %1,%0\;exth %0"
1877   [(set_attr "cc" "none_0hit")])
1879 (define_insn ""
1880   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx")
1881         (sign_extend:SI
1882          (match_operand:HI 1 "general_operand" "0,dx")))]
1883   ""
1884   "@
1885   exth %0
1886   mov %1,%0\;exth %0"
1887   [(set_attr "cc" "none_0hit")])
1889 ;; ----------------------------------------------------------------------
1890 ;; SHIFTS
1891 ;; ----------------------------------------------------------------------
1893 (define_expand "ashlsi3"
1894   [(set (match_operand:SI 0 "register_operand" "")
1895         (ashift:SI
1896          (match_operand:SI 1 "register_operand" "")
1897          (match_operand:QI 2 "nonmemory_operand" "")))]
1898   ""
1899   "")
1901 (define_insn ""
1902   [(set (match_operand:SI 0 "register_operand" "=dax,dx,!dax")
1903         (ashift:SI
1904          (match_operand:SI 1 "register_operand" "0,0,dax")
1905          (match_operand:QI 2 "nonmemory_operand" "J,dxi,dax")))]
1906   "TARGET_AM33"
1907   "*
1909   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 1)
1910     return \"add %0,%0\";
1912   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 2)
1913     return \"asl2 %0\";
1915   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 3
1916       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS)
1917     return \"asl2 %0\;add %0,%0\";
1919   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 4
1920       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS)
1921     return \"asl2 %0\;asl2 %0\";
1923   if (true_regnum (operands[1]) == true_regnum (operands[0]))
1924     return \"asl %S2,%0\";
1926   if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1927       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1928       && true_regnum (operands[0]) != true_regnum (operands[2]))
1929     return \"mov %1,%0\;asl %S2,%0\";
1930   return \"asl %2,%1,%0\";
1932   [(set_attr "cc" "set_zn")])
1934 (define_insn ""
1935   [(set (match_operand:SI 0 "register_operand" "=dax,dx,dx,dx,dx")
1936         (ashift:SI
1937          (match_operand:SI 1 "register_operand" "0,0,0,0,0")
1938          (match_operand:QI 2 "nonmemory_operand" "J,K,M,L,dxi")))]
1939   ""
1940   "@
1941   add %0,%0
1942   asl2 %0
1943   asl2 %0\;add %0,%0
1944   asl2 %0\;asl2 %0
1945   asl %S2,%0"
1946   [(set_attr "cc" "set_zn")])
1948 (define_expand "lshrsi3"
1949   [(set (match_operand:SI 0 "register_operand" "")
1950         (lshiftrt:SI
1951          (match_operand:SI 1 "register_operand" "")
1952          (match_operand:QI 2 "nonmemory_operand" "")))]
1953   ""
1954   "")
1956 (define_insn ""
1957   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1958         (lshiftrt:SI
1959          (match_operand:SI 1 "register_operand" "0,dax")
1960          (match_operand:QI 2 "nonmemory_operand" "dxi,dax")))]
1961   "TARGET_AM33"
1962   "*
1964   if (true_regnum (operands[1]) == true_regnum (operands[0]))
1965     return \"lsr %S2,%0\";
1967   if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1968       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1969       && true_regnum (operands[0]) != true_regnum (operands[2]))
1970     return \"mov %1,%0\;lsr %S2,%0\";
1971   return \"lsr %2,%1,%0\";
1973   [(set_attr "cc" "set_zn")])
1975 (define_insn ""
1976   [(set (match_operand:SI 0 "register_operand" "=dx")
1977         (lshiftrt:SI
1978          (match_operand:SI 1 "register_operand" "0")
1979          (match_operand:QI 2 "nonmemory_operand" "dxi")))]
1980   ""
1981   "lsr %S2,%0"
1982   [(set_attr "cc" "set_zn")])
1984 (define_expand "ashrsi3"
1985   [(set (match_operand:SI 0 "register_operand" "")
1986         (ashiftrt:SI
1987          (match_operand:SI 1 "register_operand" "")
1988          (match_operand:QI 2 "nonmemory_operand" "")))]
1989   ""
1990   "")
1992 (define_insn ""
1993   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1994         (ashiftrt:SI
1995          (match_operand:SI 1 "register_operand" "0,dax")
1996          (match_operand:QI 2 "nonmemory_operand" "dxi,dax")))]
1997   "TARGET_AM33"
1998   "*
2000   if (true_regnum (operands[1]) == true_regnum (operands[0]))
2001     return \"asr %S2,%0\";
2003   if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
2004       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
2005       && true_regnum (operands[0]) != true_regnum (operands[2]))
2006     return \"mov %1,%0\;asr %S2,%0\";
2007   return \"asr %2,%1,%0\";
2009   [(set_attr "cc" "set_zn")])
2011 (define_insn ""
2012   [(set (match_operand:SI 0 "register_operand" "=dx")
2013         (ashiftrt:SI
2014          (match_operand:SI 1 "register_operand" "0")
2015          (match_operand:QI 2 "nonmemory_operand" "dxi")))]
2016   ""
2017   "asr %S2,%0"
2018   [(set_attr "cc" "set_zn")])
2020 ;; ----------------------------------------------------------------------
2021 ;; FP INSTRUCTIONS
2022 ;; ----------------------------------------------------------------------
2024 ;; The mn103 series does not have floating point instructions, but since
2025 ;; FP values are held in integer regs, we can clear the high bit easily
2026 ;; which gives us an efficient inline floating point absolute value.
2028 ;; Similarly for negation of a FP value.
2031 (define_expand "absdf2"
2032   [(set (match_operand:DF 0 "register_operand" "")
2033         (abs:DF (match_operand:DF 1 "register_operand" "")))]
2034   ""
2035   "
2037   rtx target, result, insns;
2039   start_sequence ();
2040   target = operand_subword (operands[0], 1, 1, DFmode);
2041   result = expand_binop (SImode, and_optab,
2042                          operand_subword_force (operands[1], 1, DFmode),
2043                          GEN_INT (0x7fffffff), target, 0, OPTAB_WIDEN);
2045   if (result == 0)
2046     abort ();
2048   if (result != target)
2049     emit_move_insn (result, target);
2051   emit_move_insn (operand_subword (operands[0], 0, 1, DFmode),
2052                   operand_subword_force (operands[1], 0, DFmode));
2054   insns = get_insns ();
2055   end_sequence ();
2057   emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
2058   DONE;
2061 (define_expand "abssf2"
2062   [(set (match_operand:SF 0 "register_operand" "")
2063         (abs:SF (match_operand:SF 1 "register_operand" "")))]
2064   ""
2065   "
2067   rtx result;
2068   rtx target;
2070   if (TARGET_AM33_2)
2071     {
2072       emit_insn (gen_abssf2_am33_2 (operands[0], operands[1]));
2073       DONE;
2074     }
2076   target = operand_subword_force (operands[0], 0, SFmode);
2077   result = expand_binop (SImode, and_optab,
2078                          operand_subword_force (operands[1], 0, SFmode),
2079                          GEN_INT (0x7fffffff), target, 0, OPTAB_WIDEN);
2080   if (result == 0)
2081     abort ();
2083   if (result != target)
2084     emit_move_insn (result, target);
2086   /* Make a place for REG_EQUAL.  */
2087   emit_move_insn (operands[0], operands[0]);
2088   DONE;
2092 (define_insn "abssf2_am33_2"
2093   [(set (match_operand:SF 0 "register_operand" "=f,f")
2094         (abs:SF (match_operand:SF 1 "register_operand" "0,?f")))]
2095   "TARGET_AM33_2"
2096   "@
2097    fabs %0
2098    fabs %1, %0"
2099   [(set_attr "cc" "none_0hit")])
2101 (define_expand "negdf2"
2102   [(set (match_operand:DF 0 "register_operand" "")
2103         (neg:DF (match_operand:DF 1 "register_operand" "")))]
2104   ""
2105   "
2107   rtx target, result, insns;
2109   start_sequence ();
2110   target = operand_subword (operands[0], 1, 1, DFmode);
2111   result = expand_binop (SImode, xor_optab,
2112                          operand_subword_force (operands[1], 1, DFmode),
2113                          GEN_INT (trunc_int_for_mode (0x80000000, SImode)),
2114                          target, 0, OPTAB_WIDEN);
2116   if (result == 0)
2117     abort ();
2119   if (result != target)
2120     emit_move_insn (result, target);
2122   emit_move_insn (operand_subword (operands[0], 0, 1, DFmode),
2123                   operand_subword_force (operands[1], 0, DFmode));
2125   insns = get_insns ();
2126   end_sequence ();
2128   emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
2129   DONE;
2132 (define_expand "negsf2"
2133   [(set (match_operand:SF 0 "register_operand" "")
2134         (neg:SF (match_operand:SF 1 "register_operand" "")))]
2135   ""
2136   "
2138   rtx result;
2139   rtx target;
2141   if (TARGET_AM33_2)
2142     {
2143       emit_insn (gen_negsf2_am33_2 (operands[0], operands[1]));
2144       DONE;
2145     }
2147   target = operand_subword_force (operands[0], 0, SFmode);
2148   result = expand_binop (SImode, xor_optab,
2149                          operand_subword_force (operands[1], 0, SFmode),
2150                          GEN_INT (trunc_int_for_mode (0x80000000, SImode)),
2151                          target, 0, OPTAB_WIDEN);
2152   if (result == 0)
2153     abort ();
2155   if (result != target)
2156     emit_move_insn (result, target);
2158   /* Make a place for REG_EQUAL.  */
2159   emit_move_insn (operands[0], operands[0]);
2160   DONE;
2163 (define_insn "negsf2_am33_2"
2164   [(set (match_operand:SF 0 "register_operand" "=f,f")
2165         (neg:SF (match_operand:SF 1 "register_operand" "0,?f")))]
2166   "TARGET_AM33_2"
2167   "@
2168    fneg %0
2169    fneg %1, %0"
2170   [(set_attr "cc" "none_0hit")])
2172 (define_expand "sqrtsf2"
2173   [(set (match_operand:SF 0 "register_operand" "")
2174         (sqrt:SF (match_operand:SF 1 "register_operand" "")))]
2175   "TARGET_AM33_2 && flag_unsafe_math_optimizations"
2176   "
2178   rtx scratch = gen_reg_rtx (SFmode);
2179   emit_insn (gen_rsqrtsf2 (scratch, operands[1], CONST1_RTX (SFmode)));
2180   emit_insn (gen_divsf3 (operands[0], force_reg (SFmode, CONST1_RTX (SFmode)),
2181                          scratch));
2182   DONE;
2185 (define_insn "rsqrtsf2"
2186   [(set (match_operand:SF 0 "register_operand" "=f,f")
2187         (div:SF (match_operand:SF 2 "const_1f_operand" "F,F")
2188                 (sqrt:SF (match_operand:SF 1 "register_operand" "0,?f"))))]
2189   "TARGET_AM33_2"
2190   "@
2191    frsqrt %0
2192    frsqrt %1, %0"
2193   [(set_attr "cc" "none_0hit")])
2195 (define_insn "addsf3"
2196   [(set (match_operand:SF 0 "register_operand" "=f,f")
2197         (plus:SF (match_operand:SF 1 "register_operand" "%0,f")
2198                  (match_operand:SF 2 "general_operand" "f,?fF")))]
2199   "TARGET_AM33_2"
2200   "@
2201    fadd %2, %0
2202    fadd %2, %1, %0"
2203   [(set_attr "cc" "none_0hit")])
2205 (define_insn "subsf3"
2206   [(set (match_operand:SF 0 "register_operand" "=f,f")
2207         (minus:SF (match_operand:SF 1 "register_operand" "0,f")
2208                   (match_operand:SF 2 "general_operand" "f,?fF")))]
2209   "TARGET_AM33_2"
2210   "@
2211    fsub %2, %0
2212    fsub %2, %1, %0"
2213   [(set_attr "cc" "none_0hit")])
2215 (define_insn "mulsf3"
2216   [(set (match_operand:SF 0 "register_operand" "=f,f")
2217         (mult:SF (match_operand:SF 1 "register_operand" "%0,f")
2218                  (match_operand:SF 2 "general_operand" "f,?fF")))]
2219   "TARGET_AM33_2"
2220   "@
2221    fmul %2, %0
2222    fmul %2, %1, %0"
2223   [(set_attr "cc" "none_0hit")])
2225 (define_insn "divsf3"
2226   [(set (match_operand:SF 0 "register_operand" "=f,f")
2227         (div:SF (match_operand:SF 1 "register_operand" "0,f")
2228                 (match_operand:SF 2 "general_operand" "f,?fF")))]
2229   "TARGET_AM33_2"
2230   "@
2231    fdiv %2, %0
2232    fdiv %2, %1, %0"
2233   [(set_attr "cc" "none_0hit")])
2235 (define_insn "fmaddsf4"
2236   [(set (match_operand:SF 0 "register_operand" "=A")
2237         (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
2238                           (match_operand:SF 2 "register_operand" "f"))
2239                  (match_operand:SF 3 "register_operand" "f")))]
2240   "TARGET_AM33_2"
2241   "fmadd %1, %2, %3, %0"
2242   [(set_attr "cc" "none_0hit")])
2244 (define_insn "fmsubsf4"
2245   [(set (match_operand:SF 0 "register_operand" "=A")
2246         (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
2247                            (match_operand:SF 2 "register_operand" "f"))
2248                   (match_operand:SF 3 "register_operand" "f")))]
2249   "TARGET_AM33_2"
2250   "fmsub %1, %2, %3, %0"
2251   [(set_attr "cc" "none_0hit")])
2253 (define_insn "fnmaddsf4"
2254   [(set (match_operand:SF 0 "register_operand" "=A")
2255         (minus:SF (match_operand:SF 3 "register_operand" "f")
2256                   (mult:SF (match_operand:SF 1 "register_operand" "%f")
2257                            (match_operand:SF 2 "register_operand" "f"))))]
2258   "TARGET_AM33_2"
2259   "fnmadd %1, %2, %3, %0"
2260   [(set_attr "cc" "none_0hit")])
2262 (define_insn "fnmsubsf4"
2263   [(set (match_operand:SF 0 "register_operand" "=A")
2264         (minus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
2265                                    (match_operand:SF 2 "register_operand" "f")))
2266                   (match_operand:SF 3 "register_operand" "f")))]
2267   "TARGET_AM33_2"
2268   "fnmsub %1, %2, %3, %0"
2269   [(set_attr "cc" "none_0hit")])
2272 ;; ----------------------------------------------------------------------
2273 ;; PROLOGUE/EPILOGUE
2274 ;; ----------------------------------------------------------------------
2275 (define_expand "prologue"
2276   [(const_int 0)]
2277   ""
2278   "expand_prologue (); DONE;")
2280 (define_expand "epilogue"
2281   [(return)]
2282   ""
2283   "
2285   expand_epilogue ();
2286   DONE;
2289 (define_insn "return_internal"
2290   [(const_int 2)
2291    (return)]
2292   ""
2293   "rets"
2294   [(set_attr "cc" "clobber")])
2296 ;; This insn restores the callee saved registers and does a return, it
2297 ;; can also deallocate stack space.
2298 (define_insn "return_internal_regs"
2299   [(const_int 0)
2300    (match_operand:SI 0  "const_int_operand" "i")
2301    (return)]
2302   ""
2303   "*
2305   fputs (\"\\tret \", asm_out_file);
2306   mn10300_print_reg_list (asm_out_file, mn10300_get_live_callee_saved_regs ());
2307   fprintf (asm_out_file, \",%d\\n\", (int) INTVAL (operands[0]));
2308   return \"\";
2310   [(set_attr "cc" "clobber")])
2312 ;; This instruction matches one generated by mn10300_gen_multiple_store()
2313 (define_insn "store_movm"
2314   [(match_parallel 0 "store_multiple_operation"
2315     [(set (reg:SI 9) (plus:SI (reg:SI 9) (match_operand 1 "" "")))])]
2316   ""
2317   "*
2319   fputs (\"\\tmovm \", asm_out_file);
2320   mn10300_print_reg_list (asm_out_file,
2321                           store_multiple_operation (operands[0], VOIDmode));
2322   fprintf (asm_out_file, \",(sp)\\n\");
2323   return \"\";
2325   [(set_attr "cc" "clobber")])
2326   
2327 (define_insn "return"
2328   [(return)]
2329   "can_use_return_insn ()"
2330   "*
2332   rtx next = next_active_insn (insn);
2334   if (next
2335       && GET_CODE (next) == JUMP_INSN
2336       && GET_CODE (PATTERN (next)) == RETURN)
2337     return \"\";
2338   else
2339     return \"rets\";
2341   [(set_attr "cc" "clobber")])
2343 ;; Try to combine consecutive updates of the stack pointer (or any
2344 ;; other register for that matter).
2345 (define_peephole
2346   [(set (match_operand:SI 0 "register_operand" "=dxay")
2347         (plus:SI (match_dup 0)
2348                  (match_operand 1 "const_int_operand" "")))
2349    (set (match_dup 0)
2350         (plus:SI (match_dup 0)
2351                  (match_operand 2 "const_int_operand" "")))]
2352   ""
2353   "*
2355   operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]));
2356   return \"add %1,%0\";
2358   [(set_attr "cc" "clobber")])
2361 ;; We had patterns to check eq/ne, but the they don't work because
2362 ;; 0x80000000 + 0x80000000 = 0x0 with a carry out.
2364 ;; The Z flag and C flag would be set, and we have no way to
2365 ;; check for the Z flag set and C flag clear.
2367 ;; This will work on the mn10200 because we can check the ZX flag
2368 ;; if the comparison is in HImode.
2369 (define_peephole
2370   [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2371    (set (pc) (if_then_else (ge (cc0) (const_int 0))
2372                            (match_operand 1 "" "")
2373                            (pc)))]
2374   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2375   "add %0,%0\;bcc %1"
2376   [(set_attr "cc" "clobber")])
2378 (define_peephole
2379   [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2380    (set (pc) (if_then_else (lt (cc0) (const_int 0))
2381                            (match_operand 1 "" "")
2382                            (pc)))]
2383   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2384   "add %0,%0\;bcs %1"
2385   [(set_attr "cc" "clobber")])
2387 (define_peephole
2388   [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2389    (set (pc) (if_then_else (ge (cc0) (const_int 0))
2390                            (pc)
2391                            (match_operand 1 "" "")))]
2392   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2393   "add %0,%0\;bcs %1"
2394   [(set_attr "cc" "clobber")])
2396 (define_peephole
2397   [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2398    (set (pc) (if_then_else (lt (cc0) (const_int 0))
2399                            (pc)
2400                            (match_operand 1 "" "")))]
2401   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2402   "add %0,%0\;bcc %1"
2403   [(set_attr "cc" "clobber")])