2003-12-26 Guilhem Lavaux <guilhem@kaffe.org>
[official-gcc.git] / gcc / config / mn10300 / mn10300.md
blobc9d9bb858032ee46b8a8fdeaf51a6b565e82626a
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 GCC.
8 ;; GCC 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 ;; GCC 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 GCC; 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 (define_constants [
42   (PIC_REG      6)
43   (SP_REG       9)
45   (UNSPEC_INT_LABEL     0)
46   (UNSPEC_PIC           1)
47   (UNSPEC_GOT           2)
48   (UNSPEC_GOTOFF        3)
49   (UNSPEC_PLT           4)
52 ;; ----------------------------------------------------------------------
53 ;; MOVE INSTRUCTIONS
54 ;; ----------------------------------------------------------------------
56 ;; movqi
58 (define_expand "movqi"
59   [(set (match_operand:QI 0 "general_operand" "")
60         (match_operand:QI 1 "general_operand" ""))]
61   ""
62   "
64   /* One of the ops has to be in a register */
65   if (!register_operand (operand0, QImode)
66       && !register_operand (operand1, QImode))
67     operands[1] = copy_to_mode_reg (QImode, operand1);
68 }")
70 (define_insn ""
71   [(set (match_operand:QI 0 "nonimmediate_operand" "=d*x*a*f,d*x,d*x*a,d*x*a,m,*f,d*x*a")
72         (match_operand:QI 1 "general_operand" "0,I,d*xai,m,d*xa,d*xa*f,*f"))]
73   "TARGET_AM33
74    && (register_operand (operands[0], QImode)
75        || register_operand (operands[1], QImode))"
76   "*
78   switch (which_alternative)
79     {
80     case 0:
81       return \"nop\";
82     case 1:
83       return \"clr %0\";
84     case 2:
85       if (GET_CODE (operands[1]) == CONST_DOUBLE)
86         {
87           rtx xoperands[2];
88           xoperands[0] = operands[0];
89           xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
90           output_asm_insn (\"mov %1,%0\", xoperands);
91           return \"\";
92         }
94       if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
95           && GET_CODE (operands[1]) == CONST_INT)
96         {
97           HOST_WIDE_INT val = INTVAL (operands[1]);
99           if (((val & 0x80) && ! (val & 0xffffff00))
100               || ((val & 0x800000) && ! (val & 0xff000000)))
101             return \"movu %1,%0\";
102         }
103       return \"mov %1,%0\";
104     case 3:
105     case 4:
106       return \"movbu %1,%0\";
107     case 5:
108     case 6:
109       return \"fmov %1,%0\";
110     default:
111       abort ();
112     }
114   [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
116 (define_insn ""
117   [(set (match_operand:QI 0 "nonimmediate_operand" "=d*a,d,d*a,d,m")
118         (match_operand:QI 1 "general_operand" "0,I,dai,m,d"))]
119   "register_operand (operands[0], QImode)
120    || register_operand (operands[1], QImode)"
121   "*
123   switch (which_alternative)
124     {
125     case 0:
126       return \"nop\";
127     case 1:
128       return \"clr %0\";
129     case 2:
130       if (GET_CODE (operands[1]) == CONST_DOUBLE)
131         {
132           rtx xoperands[2];
133           xoperands[0] = operands[0];
134           xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
135           output_asm_insn (\"mov %1,%0\", xoperands);
136           return \"\";
137         }
139       return \"mov %1,%0\";
140     case 3:
141     case 4:
142       return \"movbu %1,%0\";
143     default:
144       abort ();
145     }
147   [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit")])
149 ;; movhi
151 (define_expand "movhi"
152   [(set (match_operand:HI 0 "general_operand" "")
153         (match_operand:HI 1 "general_operand" ""))]
154   ""
155   "
157   /* One of the ops has to be in a register */
158   if (!register_operand (operand1, HImode)
159       && !register_operand (operand0, HImode))
160     operands[1] = copy_to_mode_reg (HImode, operand1);
163 (define_insn ""
164   [(set (match_operand:HI 0 "nonimmediate_operand" "=d*x*a*f,d*x,d*x*a,d*x*a,m,*f,d*x*a")
165         (match_operand:HI 1 "general_operand" "0,I,d*x*ai,m,d*x*a,d*x*a*f,*f"))]
166   "TARGET_AM33
167    && (register_operand (operands[0], HImode)
168        || register_operand (operands[1], HImode))"
169   "*
171   switch (which_alternative)
172     {
173     case 0:
174       return \"nop\";
175     case 1:
176       return \"clr %0\";
177     case 2:
178       if (GET_CODE (operands[1]) == CONST_DOUBLE)
179         {
180           rtx xoperands[2];
181           xoperands[0] = operands[0];
182           xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
183           output_asm_insn (\"mov %1,%0\", xoperands);
184           return \"\";
185         }
187       if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
188           && GET_CODE (operands[1]) == CONST_INT)
189         {
190           HOST_WIDE_INT val = INTVAL (operands[1]);
192           if (((val & 0x80) && ! (val & 0xffffff00))
193               || ((val & 0x800000) && ! (val & 0xff000000)))
194             return \"movu %1,%0\";
195         }
196       return \"mov %1,%0\";
197     case 3:
198     case 4:
199       return \"movhu %1,%0\";
200     case 5:
201     case 6:
202       return \"fmov %1,%0\";
203     default:
204       abort ();
205     }
207   [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
209 (define_insn ""
210   [(set (match_operand:HI 0 "nonimmediate_operand" "=d*a,d,d*a,d,m")
211         (match_operand:HI 1 "general_operand" "0,I,dai,m,d"))]
212   "register_operand (operands[0], HImode)
213    || register_operand (operands[1], HImode)"
214   "*
216   switch (which_alternative)
217     {
218     case 0:
219       return \"nop\";
220     case 1:
221       return \"clr %0\";
222     case 2:
223       if (GET_CODE (operands[1]) == CONST_DOUBLE)
224         {
225           rtx xoperands[2];
226           xoperands[0] = operands[0];
227           xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
228           output_asm_insn (\"mov %1,%0\", xoperands);
229           return \"\";
230         }
231       return \"mov %1,%0\";
232     case 3:
233     case 4:
234       return \"movhu %1,%0\";
235     default:
236       abort ();
237     }
239   [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit")])
241 ;; movsi and helpers
243 ;; We use this to handle addition of two values when one operand is the
244 ;; stack pointer and the other is a memory reference of some kind.  Reload
245 ;; does not handle them correctly without this expander.
246 (define_expand "reload_insi"
247   [(set (match_operand:SI 0 "register_operand" "=a")
248         (match_operand:SI 1 "impossible_plus_operand" ""))
249    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
250   ""
251   "
253   if (XEXP (operands[1], 0) == stack_pointer_rtx)
254     {
255       if (GET_CODE (XEXP (operands[1], 1)) == SUBREG
256           && (GET_MODE_SIZE (GET_MODE (XEXP (operands[1], 1)))
257               > GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (operands[1], 1))))))
258         emit_move_insn (operands[2],
259                         gen_rtx_ZERO_EXTEND
260                         (GET_MODE (XEXP (operands[1], 1)),
261                          SUBREG_REG (XEXP (operands[1], 1))));
262       else
263         emit_move_insn (operands[2], XEXP (operands[1], 1));
264       emit_move_insn (operands[0], XEXP (operands[1], 0));
265     }
266   else
267     {
268       if (GET_CODE (XEXP (operands[1], 0)) == SUBREG
269           && (GET_MODE_SIZE (GET_MODE (XEXP (operands[1], 0)))
270               > GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (operands[1], 0))))))
271         emit_move_insn (operands[2],
272                         gen_rtx_ZERO_EXTEND
273                         (GET_MODE (XEXP (operands[1], 0)),
274                          SUBREG_REG (XEXP (operands[1], 0))));
275       else
276         emit_move_insn (operands[2], XEXP (operands[1], 0));
277       emit_move_insn (operands[0], XEXP (operands[1], 1));
278     }
279   emit_insn (gen_addsi3 (operands[0], operands[0], operands[2]));
280   DONE;
283 (define_insn "pop_pic_reg"
284   [(set (reg:SI PIC_REG)
285         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
286   "reload_completed"
287   "movm (sp),[a2]")
289 (define_expand "movsi"
290   [(set (match_operand:SI 0 "general_operand" "")
291         (match_operand:SI 1 "general_operand" ""))]
292   ""
293   "
295   /* One of the ops has to be in a register */
296   if (!register_operand (operand1, SImode)
297       && !register_operand (operand0, SImode))
298     operands[1] = copy_to_mode_reg (SImode, operand1);
299   if (flag_pic)
300     {
301       rtx temp;
302       if (SYMBOLIC_CONST_P (operands[1]))
303         {
304           if (GET_CODE (operands[0]) == MEM)
305             operands[1] = force_reg (Pmode, operands[1]);
306           else
307             {
308               temp = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
309               operands[1] = legitimize_pic_address (operands[1], temp);
310             }
311         }
312       else if (GET_CODE (operands[1]) == CONST
313                && GET_CODE (XEXP (operands[1], 0)) == PLUS
314                && SYMBOLIC_CONST_P (XEXP (XEXP (operands[1], 0), 0)))
315         {
316           temp = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
317           temp = legitimize_pic_address (XEXP (XEXP (operands[1], 0), 0),
318                                          temp);
319           operands[1] = expand_binop (SImode, add_optab, temp,
320                                       XEXP (XEXP (operands[1], 0), 1),
321                                       no_new_pseudos ? temp
322                                       : gen_reg_rtx (Pmode),
323                                       0, OPTAB_LIB_WIDEN);
324         }
325     }
328 (define_insn ""
329   [(set (match_operand:SI 0 "nonimmediate_operand"
330                                 "=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax,axR,!*y,*f,*f,dxaQ")
331         (match_operand:SI 1 "general_operand"
332                                 "0,0,I,I,dx,ax,dx,ax,dixm,aixm,dixm,aixm,!*y,axR,0,dxaQi*f,*f"))]
333   "register_operand (operands[0], SImode)
334    || register_operand (operands[1], SImode)"
335   "*
337   switch (which_alternative)
338     {
339     case 0:
340     case 1:
341       return \"nop\";
342     case 2:
343       return \"clr %0\";
344     case 3:
345     case 4:
346     case 5:
347     case 6:
348     case 7:
349     case 8:
350     case 9:
351     case 10:
352     case 11:
353     case 12:
354     case 13:
355       if (GET_CODE (operands[1]) == CONST_DOUBLE)
356         {
357           rtx xoperands[2];
358           xoperands[0] = operands[0];
359           xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
360           output_asm_insn (\"mov %1,%0\", xoperands);
361           return \"\";
362         }
364       if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
365           && GET_CODE (operands[1]) == CONST_INT)
366         {
367           HOST_WIDE_INT val = INTVAL (operands[1]);
369           if (((val & 0x80) && ! (val & 0xffffff00))
370               || ((val & 0x800000) && ! (val & 0xff000000)))
371             return \"movu %1,%0\";
372         }
373       return \"mov %1,%0\";
374     case 14:
375       return \"nop\";
376     case 15:
377     case 16:
378       return \"fmov %1,%0\";
379     default:
380       abort ();
381     }
383   [(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")])
385 (define_expand "movsf"
386   [(set (match_operand:SF 0 "general_operand" "")
387         (match_operand:SF 1 "general_operand" ""))]
388   ""
389   "
391   /* One of the ops has to be in a register */
392   if (!register_operand (operand1, SFmode)
393       && !register_operand (operand0, SFmode))
394     operands[1] = copy_to_mode_reg (SFmode, operand1);
397 (define_insn ""
398   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,dx,ax,dx,a,f,dxaQ,daxm,dax")
399         (match_operand:SF 1 "general_operand" "0,0,0,G,G,fdxaQF,f,dax,daxFm"))]
400   "register_operand (operands[0], SFmode)
401    || register_operand (operands[1], SFmode)"
402   "*
404   switch (which_alternative)
405     {
406     case 0:
407     case 1:
408     case 2:
409       return \"nop\";
410     case 3:
411       return \"clr %0\";
412     /* case 4: below */
413     case 5:
414     case 6:
415       return \"fmov %1, %0\";
416     case 4:
417     case 7:
418     case 8:
419       if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
420           && GET_CODE (operands[1]) == CONST_INT)
421         {
422           HOST_WIDE_INT val = INTVAL (operands[1]);
424           if (((val & 0x80) && ! (val & 0xffffff00))
425               || ((val & 0x800000) && ! (val & 0xff000000)))
426             return \"movu %1,%0\";
427         }
428       return \"mov %1,%0\";
429     default:
430       abort ();
431     }
433   [(set_attr "cc" "none,none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
435 (define_expand "movdi"
436   [(set (match_operand:DI 0 "general_operand" "")
437         (match_operand:DI 1 "general_operand" ""))]
438   ""
439   "
441   /* One of the ops has to be in a register */
442   if (!register_operand (operand1, DImode)
443       && !register_operand (operand0, DImode))
444     operands[1] = copy_to_mode_reg (DImode, operand1);
447 (define_insn ""
448   [(set (match_operand:DI 0 "nonimmediate_operand"
449                                 "=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax,*f,*f,*f,dxa,*f,Q")
450         (match_operand:DI 1 "general_operand"
451                                 "0,0,I,I,dx,ax,dx,ax,dxim,axim,dxim,axim,0,*f,dxai,*f,Q,*f"))]
452   "register_operand (operands[0], DImode)
453    || register_operand (operands[1], DImode)"
454   "*
456   long val[2];
457   REAL_VALUE_TYPE rv;
459   switch (which_alternative)
460     {
461       case 0:
462       case 1:
463         return \"nop\";
465       case 2:
466         return \"clr %L0\;clr %H0\";
468       case 3:
469         if (rtx_equal_p (operands[0], operands[1]))
470           return \"sub %L1,%L0\;mov %L0,%H0\";
471         else
472           return \"mov %1,%L0\;mov %L0,%H0\";
473       case 4:
474       case 5:
475       case 6:
476       case 7:
477       case 8:
478       case 9:
479       case 10:
480       case 11:
481         if (GET_CODE (operands[1]) == CONST_INT)
482           {
483             rtx low, high;
484             split_double (operands[1], &low, &high);
485             val[0] = INTVAL (low);
486             val[1] = INTVAL (high);
487           }
488         if (GET_CODE (operands[1]) == CONST_DOUBLE)
489           {
490             if (GET_MODE (operands[1]) == DFmode)
491               {
492                 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
493                 REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
494               }
495             else if (GET_MODE (operands[1]) == VOIDmode
496                      || GET_MODE (operands[1]) == DImode)
497               {
498                 val[0] = CONST_DOUBLE_LOW (operands[1]);
499                 val[1] = CONST_DOUBLE_HIGH (operands[1]);
500               }
501           }
503         if (GET_CODE (operands[1]) == MEM
504             && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
505           {
506             rtx temp = operands[0];
508             while (GET_CODE (temp) == SUBREG)
509               temp = SUBREG_REG (temp);
511             if (GET_CODE (temp) != REG)
512               abort ();
514             if (reg_overlap_mentioned_p (gen_rtx_REG (SImode, REGNO (temp)),
515                                          XEXP (operands[1], 0)))
516               return \"mov %H1,%H0\;mov %L1,%L0\";
517             else
518               return \"mov %L1,%L0\;mov %H1,%H0\";
519               
520           }
521         else if (GET_CODE (operands[1]) == MEM
522                  && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
523                  && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
524           {
525             rtx xoperands[2];
527             xoperands[0] = operands[0];
528             xoperands[1] = XEXP (operands[1], 0);
530             output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\",
531                              xoperands);
532             return \"\";
533           }
534         else
535           {
536             if ((GET_CODE (operands[1]) == CONST_INT
537                  || GET_CODE (operands[1]) == CONST_DOUBLE)
538                 && val[0] == 0)
539               {
540                 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
541                   output_asm_insn (\"clr %L0\", operands);
542                 else
543                   output_asm_insn (\"mov %L1,%L0\", operands);
544               }
545             else if ((GET_CODE (operands[1]) == CONST_INT
546                       || GET_CODE (operands[1]) == CONST_DOUBLE)
547                      && (REGNO_REG_CLASS (true_regnum (operands[0]))
548                          == EXTENDED_REGS)
549                      && (((val[0] & 0x80) && ! (val[0] & 0xffffff00))
550                          || ((val[0] & 0x800000) && ! (val[0] & 0xff000000))))
551               output_asm_insn (\"movu %1,%0\", operands);
552             else
553               output_asm_insn (\"mov %L1,%L0\", operands);
555             if ((GET_CODE (operands[1]) == CONST_INT
556                  || GET_CODE (operands[1]) == CONST_DOUBLE)
557                 && val[1] == 0)
558               {
559                 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
560                   output_asm_insn (\"clr %H0\", operands);
561                 else
562                   output_asm_insn (\"mov %H1,%H0\", operands);
563               }
564             else if ((GET_CODE (operands[1]) == CONST_INT
565                       || GET_CODE (operands[1]) == CONST_DOUBLE)
566                      && val[0] == val[1])
567               output_asm_insn (\"mov %L0,%H0\", operands);
568             else if ((GET_CODE (operands[1]) == CONST_INT
569                       || GET_CODE (operands[1]) == CONST_DOUBLE)
570                      && (REGNO_REG_CLASS (true_regnum (operands[0]))
571                          == EXTENDED_REGS)
572                      && (((val[1] & 0x80) && ! (val[1] & 0xffffff00))
573                          || ((val[1] & 0x800000) && ! (val[1] & 0xff000000))))
574               output_asm_insn (\"movu %1,%0\", operands);
575             else
576               output_asm_insn (\"mov %H1,%H0\", operands);
577             return \"\";
578           }
579       case 12:
580         return \"nop\";
581       case 13:
582       case 14:
583       case 15:
584         return \"fmov %L1, %L0\;fmov %H1, %H0\";
585       case 16:
586         if (GET_CODE (operands[1]) == MEM
587             && GET_CODE (XEXP (operands[1], 0)) == CONST_INT
588             && (INTVAL (XEXP (operands[1], 0)) & 7) == 0)
589           return \"fmov %D1, %D0\";
590         else
591           return \"fmov %L1, %L0\;fmov %H1, %H0\";
592       case 17:
593         if (GET_CODE (operands[0]) == MEM
594             && GET_CODE (XEXP (operands[0], 0)) == CONST_INT
595             && (INTVAL (XEXP (operands[0], 0)) & 7) == 0)
596           return \"fmov %D1, %D0\";
597         else
598           return \"fmov %L1, %L0\;fmov %H1, %H0\";
599     default:
600       abort ();
601     }
603   [(set (attr "cc")
604         (cond
605          [
606          (ior (lt (symbol_ref "which_alternative") (const_int 2))
607               (eq (symbol_ref "which_alternative") (const_int 12))
608               ) (const_string "none")
609          (eq (symbol_ref "which_alternative") (const_int 2)
610              ) (const_string "clobber")
611          (eq (symbol_ref "which_alternative") (const_int 3)
612              ) (if_then_else
613                 (ne (symbol_ref "rtx_equal_p (operands[0], operands[1])")
614                     (const_int 0)) (const_string "clobber")
615                     (const_string "none_0hit"))
616          (ior (eq (symbol_ref "which_alternative") (const_int 8))
617               (eq (symbol_ref "which_alternative") (const_int 9))
618               ) (if_then_else
619                  (ne (symbol_ref "mn10300_wide_const_load_uses_clr
620                                   (operands)")
621                      (const_int 0)) (const_string "clobber")
622                      (const_string "none_0hit"))
623          ] (const_string "none_0hit")))])
625 (define_expand "movdf"
626   [(set (match_operand:DF 0 "general_operand" "")
627         (match_operand:DF 1 "general_operand" ""))]
628   ""
629   "
631   /* One of the ops has to be in a register */
632   if (!register_operand (operand1, DFmode)
633       && !register_operand (operand0, DFmode))
634     operands[1] = copy_to_mode_reg (DFmode, operand1);
637 (define_insn ""
638   [(set (match_operand:DF 0 "nonimmediate_operand"
639                                 "=f,dx,ax,dx,f,f,dxa,f,Q,a,dxm,dxm,axm,axm,dx,dx,ax,ax")
640         (match_operand:DF 1 "general_operand"
641                                 "0,0,0,G,f,dxaF,f,Q,f,G,dx,ax,dx,ax,dxFm,axFm,dxFm,axFm"))]
642   "register_operand (operands[0], DFmode)
643    || register_operand (operands[1], DFmode)"
644   "*
646   long val[2];
647   REAL_VALUE_TYPE rv;
649   switch (which_alternative)
650     {
651       case 0:
652       case 1:
653       case 2:
654         return \"nop\";
656       case 3:
657         return \"clr %L0\;clr %H0\";
659       case 4:
660       case 5:
661       case 6:
662         return \"fmov %L1, %L0\;fmov %H1, %H0\";
664       case 7:
665         if (GET_CODE (operands[1]) == MEM
666             && GET_CODE (XEXP (operands[1], 0)) == CONST_INT
667             && (INTVAL (XEXP (operands[1], 0)) & 7) == 0)
668           return \"fmov %D1, %D0\";
669         else
670           return \"fmov %L1, %L0\;fmov %H1, %H0\";
672       case 8:
673         if (GET_CODE (operands[0]) == MEM
674             && GET_CODE (XEXP (operands[0], 0)) == CONST_INT
675             && (INTVAL (XEXP (operands[0], 0)) & 7) == 0)
676           return \"fmov %D1, %D0\";
677         else
678           return \"fmov %L1, %L0\;fmov %H1, %H0\";
680       case 9:
681          if (rtx_equal_p (operands[0], operands[1]))
682            return \"sub %L1,%L0\;mov %L0,%H0\";
683          else
684            return \"mov %1,%L0\;mov %L0,%H0\";
685       case 10:
686       case 11:
687       case 12:
688       case 13:
689       case 14:
690       case 15:
691       case 16:
692       case 17:
693         if (GET_CODE (operands[1]) == CONST_INT)
694           {
695             rtx low, high;
696             split_double (operands[1], &low, &high);
697             val[0] = INTVAL (low);
698             val[1] = INTVAL (high);
699           }
700         if (GET_CODE (operands[1]) == CONST_DOUBLE)
701           {
702             if (GET_MODE (operands[1]) == DFmode)
703               {
704                 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
705                 REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
706               }
707             else if (GET_MODE (operands[1]) == VOIDmode
708                      || GET_MODE (operands[1]) == DImode)
709               {
710                 val[0] = CONST_DOUBLE_LOW (operands[1]);
711                 val[1] = CONST_DOUBLE_HIGH (operands[1]);
712               }
713           }
715         if (GET_CODE (operands[1]) == MEM
716             && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
717           {
718             rtx temp = operands[0];
720             while (GET_CODE (temp) == SUBREG)
721               temp = SUBREG_REG (temp);
723             if (GET_CODE (temp) != REG)
724               abort ();
726             if (reg_overlap_mentioned_p (gen_rtx_REG (SImode, REGNO (temp)),
727                                          XEXP (operands[1], 0)))
728               return \"mov %H1,%H0\;mov %L1,%L0\";
729             else
730               return \"mov %L1,%L0\;mov %H1,%H0\";
731               
732           }
733         else if (GET_CODE (operands[1]) == MEM
734                  && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
735                  && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
736           {
737             rtx xoperands[2];
739             xoperands[0] = operands[0];
740             xoperands[1] = XEXP (operands[1], 0);
742             output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\",
743                              xoperands);
744             return \"\";
745           }
746         else
747           {
748             if ((GET_CODE (operands[1]) == CONST_INT
749                  || GET_CODE (operands[1]) == CONST_DOUBLE)
750                 && val[0] == 0)
751               {
752                 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
753                   output_asm_insn (\"clr %L0\", operands);
754                 else
755                   output_asm_insn (\"mov %L1,%L0\", operands);
756               }
757             else if ((GET_CODE (operands[1]) == CONST_INT
758                       || GET_CODE (operands[1]) == CONST_DOUBLE)
759                      && (REGNO_REG_CLASS (true_regnum (operands[0]))
760                          == EXTENDED_REGS)
761                      && (((val[0] & 0x80) && ! (val[0] & 0xffffff00))
762                          || ((val[0] & 0x800000) && ! (val[0] & 0xff000000))))
763               output_asm_insn (\"movu %1,%0\", operands);
764             else
765               output_asm_insn (\"mov %L1,%L0\", operands);
767             if ((GET_CODE (operands[1]) == CONST_INT
768                  || GET_CODE (operands[1]) == CONST_DOUBLE)
769                 && val[1] == 0)
770               {
771                 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
772                   output_asm_insn (\"clr %H0\", operands);
773                 else
774                   output_asm_insn (\"mov %H1,%H0\", operands);
775               }
776             else if ((GET_CODE (operands[1]) == CONST_INT
777                       || GET_CODE (operands[1]) == CONST_DOUBLE)
778                      && val[0] == val[1])
779               output_asm_insn (\"mov %L0,%H0\", operands);
780             else if ((GET_CODE (operands[1]) == CONST_INT
781                       || GET_CODE (operands[1]) == CONST_DOUBLE)
782                      && (REGNO_REG_CLASS (true_regnum (operands[0]))
783                          == EXTENDED_REGS)
784                      && (((val[1] & 0x80) && ! (val[1] & 0xffffff00))
785                          || ((val[1] & 0x800000) && ! (val[1] & 0xff000000))))
786               output_asm_insn (\"movu %1,%0\", operands);
787             else
788               output_asm_insn (\"mov %H1,%H0\", operands);
789             return \"\";
790           }
791     default:
792       abort ();
793     }
795   [(set (attr "cc")
796         (cond
797          [
798          (lt (symbol_ref "which_alternative") (const_int 3)
799              ) (const_string "none")
800          (eq (symbol_ref "which_alternative") (const_int 3)
801              ) (const_string "clobber")
802          (eq (symbol_ref "which_alternative") (const_int 9)
803              ) (if_then_else
804                 (ne (symbol_ref "rtx_equal_p (operands[0], operands[1])")
805                     (const_int 0)) (const_string "clobber")
806                     (const_string "none_0hit"))
807          (ior (eq (symbol_ref "which_alternative") (const_int 14))
808               (eq (symbol_ref "which_alternative") (const_int 15))
809               ) (if_then_else
810                  (ne (symbol_ref "mn10300_wide_const_load_uses_clr
811                                   (operands)")
812                      (const_int 0)) (const_string "clobber")
813                      (const_string "none_0hit"))
814          ] (const_string "none_0hit")))])
818 ;; ----------------------------------------------------------------------
819 ;; TEST INSTRUCTIONS
820 ;; ----------------------------------------------------------------------
822 ;; Go ahead and define tstsi so we can eliminate redundant tst insns
823 ;; when we start trying to optimize this port.
824 (define_insn "tstsi"
825   [(set (cc0) (match_operand:SI 0 "register_operand" "dax"))]
826   ""
827   "* return output_tst (operands[0], insn);"
828   [(set_attr "cc" "set_znv")])
830 (define_insn ""
831   [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "dx,!a")))]
832   "TARGET_AM33"
833   "* return output_tst (operands[0], insn);"
834   [(set_attr "cc" "set_znv")])
836 (define_insn ""
837   [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "dx")))]
838   ""
839   "* return output_tst (operands[0], insn);"
840   [(set_attr "cc" "set_znv")])
842 (define_insn ""
843   [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "dx,!a")))]
844   "TARGET_AM33"
845   "* return output_tst (operands[0], insn);"
846   [(set_attr "cc" "set_znv")])
848 (define_insn ""
849   [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "dx")))]
850   ""
851   "* return output_tst (operands[0], insn);"
852   [(set_attr "cc" "set_znv")])
854 ;; Ordinarily, the cmp instruction will set the Z bit of cc0 to 1 if
855 ;; its operands hold equal values, but the operands of a cmp
856 ;; instruction must be distinct registers.  In the case where we'd
857 ;; like to compare a register to itself, we can achieve this effect
858 ;; with a btst 0,d0 instead.  (This will not alter the contents of d0
859 ;; but will have the proper effect on cc0.  Using d0 is arbitrary; any
860 ;; data register would work.)
862 ;; Even though the first alternative would be preferable if it can
863 ;; possibly match, reload must not be given the opportunity to attempt
864 ;; to use it.  It assumes that such matches can only occur when one of
865 ;; the operands is used for input and the other for output.  Since
866 ;; this is not the case, it abort()s.  Indeed, such a reload cannot be
867 ;; possibly satisfied, so just mark the alternative with a `!', so
868 ;; that it is not considered by reload.
870 (define_insn "cmpsi"
871   [(set (cc0)
872         (compare (match_operand:SI 0 "register_operand" "!*d*a*x,dax")
873                  (match_operand:SI 1 "nonmemory_operand" "*0,daxi")))]
874   ""
875   "@
876   btst 0,d0
877   cmp %1,%0"
878   [(set_attr "cc" "compare,compare")])
880 (define_insn "cmpsf"
881   [(set (cc0)
882         (compare (match_operand:SF 0 "register_operand" "f,f")
883                  (match_operand:SF 1 "nonmemory_operand" "f,F")))]
884   "TARGET_AM33_2"
885   "fcmp %1,%0"
886   [(set_attr "cc" "compare,compare")])
888 ;; ----------------------------------------------------------------------
889 ;; ADD INSTRUCTIONS
890 ;; ----------------------------------------------------------------------
892 (define_expand "addsi3"
893   [(set (match_operand:SI 0 "register_operand" "")
894         (plus:SI (match_operand:SI 1 "register_operand" "")
895                  (match_operand:SI 2 "nonmemory_operand" "")))]
896   ""
897   "")
899 (define_insn ""
900   [(set (match_operand:SI 0 "register_operand" "=dx,a,x,a,dax,!*y,!dax")
901         (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,dax")
902                  (match_operand:SI 2 "nonmemory_operand" "J,J,L,L,daxi,i,dax")))]
903   "TARGET_AM33"
904   "*
906   switch (which_alternative)
907     {
908     case 0:
909     case 1:
910       return \"inc %0\";
911     case 2:
912     case 3:
913       return \"inc4 %0\";
914     case 4:
915     case 5:
916       return \"add %2,%0\";
917     case 6:
918       {
919         enum reg_class src1_class, src2_class, dst_class;
921         src1_class = REGNO_REG_CLASS (true_regnum (operands[1]));
922         src2_class = REGNO_REG_CLASS (true_regnum (operands[2]));
923         dst_class = REGNO_REG_CLASS (true_regnum (operands[0]));
924         
925         /* I'm not sure if this can happen or not.  Might as well be prepared
926           and generate the best possible code if it does happen.  */
927         if (true_regnum (operands[0]) == true_regnum (operands[1]))
928           return \"add %2,%0\";
929         if (true_regnum (operands[0]) == true_regnum (operands[2]))
930           return \"add %1,%0\";
932         /* Catch cases where no extended register was used.  These should be
933            handled just like the mn10300.  */
934         if (src1_class != EXTENDED_REGS
935             && src2_class != EXTENDED_REGS
936             && dst_class != EXTENDED_REGS)
937           {
938             /* We have to copy one of the sources into the destination, then
939                add the other source to the destination.
941                Carefully select which source to copy to the destination; a naive
942                implementation will waste a byte when the source classes are 
943                different and the destination is an address register.  Selecting
944                the lowest cost register copy will optimize this sequence.  */
945             if (REGNO_REG_CLASS (true_regnum (operands[1]))
946                 == REGNO_REG_CLASS (true_regnum (operands[0])))
947               return \"mov %1,%0\;add %2,%0\";
948             return \"mov %2,%0\;add %1,%0\";
949           }
951         /* At least one register is an extended register.  */
953         /* The three operand add instruction on the am33 is a win iff the
954            output register is an extended register, or if both source
955            registers are extended registers.  */
956         if (dst_class == EXTENDED_REGS
957             || src1_class == src2_class)
958           return \"add %2,%1,%0\";
960       /* It is better to copy one of the sources to the destination, then
961          perform a 2 address add.  The destination in this case must be
962          an address or data register and one of the sources must be an
963          extended register and the remaining source must not be an extended
964          register.
966          The best code for this case is to copy the extended reg to the
967          destination, then emit a two address add.  */
968       if (src1_class == EXTENDED_REGS)
969         return \"mov %1,%0\;add %2,%0\";
970       return \"mov %2,%0\;add %1,%0\";
971       }
972     default:
973       abort ();
974     }
976   [(set_attr "cc" "set_zn,none_0hit,set_zn,none_0hit,set_zn,none_0hit,set_zn")])
978 (define_insn ""
979   [(set (match_operand:SI 0 "register_operand" "=dx,a,a,dax,!*y,!dax")
980         (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,dax")
981                  (match_operand:SI 2 "nonmemory_operand" "J,J,L,daxi,i,dax")))]
982   ""
983   "*
985   switch (which_alternative)
986     {
987     case 0:
988     case 1:
989       return \"inc %0\";
990     case 2:
991       return \"inc4 %0\";
992     case 3:
993     case 4:
994       return \"add %2,%0\";
995     case 5:
996       /* I'm not sure if this can happen or not.  Might as well be prepared
997          and generate the best possible code if it does happen.  */
998       if (true_regnum (operands[0]) == true_regnum (operands[1]))
999         return \"add %2,%0\";
1000       if (true_regnum (operands[0]) == true_regnum (operands[2]))
1001         return \"add %1,%0\";
1003       /* We have to copy one of the sources into the destination, then add
1004          the other source to the destination.
1006          Carefully select which source to copy to the destination; a naive
1007          implementation will waste a byte when the source classes are different
1008          and the destination is an address register.  Selecting the lowest
1009          cost register copy will optimize this sequence.  */
1010       if (REGNO_REG_CLASS (true_regnum (operands[1]))
1011           == REGNO_REG_CLASS (true_regnum (operands[0])))
1012         return \"mov %1,%0\;add %2,%0\";
1013       return \"mov %2,%0\;add %1,%0\";
1014     default:
1015       abort ();
1016     }
1018   [(set_attr "cc" "set_zn,none_0hit,none_0hit,set_zn,none_0hit,set_zn")])
1020 ;; ----------------------------------------------------------------------
1021 ;; SUBTRACT INSTRUCTIONS
1022 ;; ----------------------------------------------------------------------
1024 (define_expand "subsi3"
1025   [(set (match_operand:SI 0 "register_operand" "")
1026         (minus:SI (match_operand:SI 1 "register_operand" "")
1027                   (match_operand:SI 2 "nonmemory_operand" "")))]
1028   ""
1029   "")
1031 (define_insn ""
1032   [(set (match_operand:SI 0 "register_operand" "=dax,!dax")
1033         (minus:SI (match_operand:SI 1 "register_operand" "0,dax")
1034                   (match_operand:SI 2 "nonmemory_operand" "daxi,dax")))]
1035   "TARGET_AM33"
1036   "*
1038   if (true_regnum (operands[0]) == true_regnum (operands[1]))
1039     return \"sub %2,%0\";
1040   else
1041     {
1042       enum reg_class src1_class, src2_class, dst_class;
1044       src1_class = REGNO_REG_CLASS (true_regnum (operands[1]));
1045       src2_class = REGNO_REG_CLASS (true_regnum (operands[2]));
1046       dst_class = REGNO_REG_CLASS (true_regnum (operands[0]));
1048       /* If no extended registers are used, then the best way to handle
1049          this is to copy the first source operand into the destination
1050          and emit a two address subtraction.  */
1051       if (src1_class != EXTENDED_REGS
1052           && src2_class != EXTENDED_REGS
1053           && dst_class != EXTENDED_REGS
1054           && true_regnum (operands[0]) != true_regnum (operands[2]))
1055         return \"mov %1,%0\;sub %2,%0\";
1056       return \"sub %2,%1,%0\";
1057     }
1059   [(set_attr "cc" "set_zn")])
1061 (define_insn ""
1062   [(set (match_operand:SI 0 "register_operand" "=dax")
1063         (minus:SI (match_operand:SI 1 "register_operand" "0")
1064                   (match_operand:SI 2 "nonmemory_operand" "daxi")))]
1065   ""
1066   "sub %2,%0"
1067   [(set_attr "cc" "set_zn")])
1069 (define_expand "negsi2"
1070   [(set (match_operand:SI 0 "register_operand" "")
1071         (neg:SI (match_operand:SI 1 "register_operand" "")))]
1072   ""
1073   "
1075   rtx target = gen_reg_rtx (SImode);
1077   emit_move_insn (target, GEN_INT (0));
1078   emit_insn (gen_subsi3 (target, target, operands[1]));
1079   emit_move_insn (operands[0], target);
1080   DONE;
1083 ;; ----------------------------------------------------------------------
1084 ;; MULTIPLY INSTRUCTIONS
1085 ;; ----------------------------------------------------------------------
1087 (define_insn "mulsidi3"
1088   [(set (match_operand:DI 0 "register_operand" "=dax")
1089         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "dax"))
1090                  (sign_extend:DI (match_operand:SI 2 "register_operand" "dax"))))]
1091   "TARGET_AM33"
1092   "mul %1,%2,%H0,%L0"
1093   [(set_attr "cc" "set_zn")])
1095 (define_insn "umulsidi3"
1096   [(set (match_operand:DI 0 "register_operand" "=dax")
1097         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "dax"))
1098                  (zero_extend:DI (match_operand:SI 2 "register_operand" "dax"))))]
1099   "TARGET_AM33"
1100   "mulu %1,%2,%H0,%L0"
1101   [(set_attr "cc" "set_zn")])
1103 (define_expand "mulsi3"
1104   [(set (match_operand:SI 0 "register_operand" "")
1105         (mult:SI (match_operand:SI 1 "register_operand" "")
1106                  (match_operand:SI 2 "register_operand" "")))]
1107   ""
1108   "")
1110 (define_insn ""
1111   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1112         (mult:SI (match_operand:SI 1 "register_operand" "%0,0")
1113                  (match_operand:SI 2 "nonmemory_operand" "dx,daxi")))]
1114   "TARGET_AM33"
1115   "*
1117   if (TARGET_MULT_BUG)
1118     return \"nop\;nop\;mul %2,%0\";
1119   else
1120     return \"mul %2,%0\";
1122   [(set_attr "cc" "set_zn")])
1123   
1124 (define_insn ""
1125   [(set (match_operand:SI 0 "register_operand" "=dx")
1126         (mult:SI (match_operand:SI 1 "register_operand" "%0")
1127                  (match_operand:SI 2 "register_operand" "dx")))]
1128   ""
1129   "*
1131   if (TARGET_MULT_BUG)
1132     return \"nop\;nop\;mul %2,%0\";
1133   else
1134     return \"mul %2,%0\";
1136   [(set_attr "cc" "set_zn")])
1138 (define_insn "udivmodsi4"
1139   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx")
1140         (udiv:SI (match_operand:SI 1 "general_operand" "0")
1141                  (match_operand:SI 2 "general_operand" "dx")))
1142    (set (match_operand:SI 3 "nonimmediate_operand" "=&d")
1143         (umod:SI (match_dup 1) (match_dup 2)))]
1144   ""
1145   "*
1147   output_asm_insn (\"sub %3,%3\;mov %3,mdr\", operands);
1149   if (find_reg_note (insn, REG_UNUSED, operands[3]))
1150     return \"divu %2,%0\";
1151   else
1152     return \"divu %2,%0\;mov mdr,%3\";
1154   [(set_attr "cc" "set_zn")])
1156 (define_insn "divmodsi4"
1157   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx")
1158         (div:SI (match_operand:SI 1 "general_operand" "0")
1159                  (match_operand:SI 2 "general_operand" "dx")))
1160    (set (match_operand:SI 3 "nonimmediate_operand" "=d")
1161         (mod:SI (match_dup 1) (match_dup 2)))]
1162   ""
1163   "*
1165   if (find_reg_note (insn, REG_UNUSED, operands[3]))
1166     return \"ext %0\;div %2,%0\";
1167   else
1168     return \"ext %0\;div %2,%0\;mov mdr,%3\";
1170   [(set_attr "cc" "set_zn")])
1173 ;; ----------------------------------------------------------------------
1174 ;; AND INSTRUCTIONS
1175 ;; ----------------------------------------------------------------------
1177 (define_expand "andsi3"
1178   [(set (match_operand:SI 0 "register_operand" "")
1179         (and:SI (match_operand:SI 1 "register_operand" "")
1180                 (match_operand:SI 2 "nonmemory_operand" "")))]
1181   ""
1182   "")
1184 (define_insn ""
1185   [(set (match_operand:SI 0 "register_operand" "=dx,dx,!dax")
1186         (and:SI (match_operand:SI 1 "register_operand" "%0,0,dax")
1187                 (match_operand:SI 2 "nonmemory_operand" "N,dxi,dax")))]
1188   "TARGET_AM33"
1189   "*
1191   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff)
1192     return \"extbu %0\";
1193   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xffff)
1194     return \"exthu %0\";
1195   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x7fffffff)
1196     return \"add %0,%0\;lsr 1,%0\";
1197   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x3fffffff)
1198     return \"asl2 %0\;lsr 2,%0\";
1199   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x1fffffff)
1200     return \"add %0,%0\;asl2 %0\;lsr 3,%0\";
1201   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x0fffffff)
1202     return \"asl2 %0\;asl2 %0\;lsr 4,%0\";
1203   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffe)
1204     return \"lsr 1,%0\;add %0,%0\";
1205   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffc)
1206     return \"lsr 2,%0\;asl2 %0\";
1207   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff8)
1208     return \"lsr 3,%0\;add %0,%0\;asl2 %0\";
1209   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff0)
1210     return \"lsr 4,%0\;asl2 %0\;asl2 %0\";
1211   if (REG_P (operands[2]) && REG_P (operands[1])
1212       && true_regnum (operands[0]) != true_regnum (operands[1])
1213       && true_regnum (operands[0]) != true_regnum (operands[2])
1214       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1215       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1216       && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
1217     return \"mov %1,%0\;and %2,%0\";
1218   if (REG_P (operands[2]) && REG_P (operands[1])
1219       && true_regnum (operands[0]) != true_regnum (operands[1])
1220       && true_regnum (operands[0]) != true_regnum (operands[2]))
1221     return \"and %1,%2,%0\";
1222   if (REG_P (operands[2]) && REG_P (operands[0])
1223       && true_regnum (operands[2]) == true_regnum (operands[0]))
1224     return \"and %1,%0\";
1225   return \"and %2,%0\";
1227   [(set (attr "cc")
1228         (cond
1229          [
1230          (eq (symbol_ref "which_alternative") (const_int 0)
1231              ) (const_string "none_0hit")
1232          (ne (symbol_ref "GET_CODE (operands[2]) == CONST_INT
1233                           && (INTVAL (operands[2]) == 0x7fffffff
1234                               || INTVAL (operands[2]) == 0x3fffffff
1235                               || INTVAL (operands[2]) == 0x1fffffff
1236                               || INTVAL (operands[2]) == 0x0fffffff
1237                               || INTVAL (operands[2]) == 0xfffffffe
1238                               || INTVAL (operands[2]) == 0xfffffffc
1239                               || INTVAL (operands[2]) == 0xfffffff8
1240                               || INTVAL (operands[2]) == 0xfffffff0)")
1241              (const_int 0)) (const_string "set_zn")
1242           ] (const_string "set_znv")))])
1244 (define_insn ""
1245   [(set (match_operand:SI 0 "register_operand" "=dx,dx")
1246         (and:SI (match_operand:SI 1 "register_operand" "%0,0")
1247                 (match_operand:SI 2 "nonmemory_operand" "N,dxi")))]
1248   ""
1249   "*
1251   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff)
1252     return \"extbu %0\";
1253   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xffff)
1254     return \"exthu %0\";
1255   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x7fffffff)
1256     return \"add %0,%0\;lsr 1,%0\";
1257   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x3fffffff)
1258     return \"asl2 %0\;lsr 2,%0\";
1259   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x1fffffff)
1260     return \"add %0,%0\;asl2 %0\;lsr 3,%0\";
1261   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x0fffffff)
1262     return \"asl2 %0\;asl2 %0\;lsr 4,%0\";
1263   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffe)
1264     return \"lsr 1,%0\;add %0,%0\";
1265   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffc)
1266     return \"lsr 2,%0\;asl2 %0\";
1267   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff8)
1268     return \"lsr 3,%0\;add %0,%0\;asl2 %0\";
1269   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff0)
1270     return \"lsr 4,%0\;asl2 %0\;asl2 %0\";
1271   return \"and %2,%0\";
1273   [(set (attr "cc")
1274         (cond
1275          [
1276          (eq (symbol_ref "which_alternative") (const_int 0)
1277              ) (const_string "none_0hit")
1278          ;; Shifts don't set the V flag, but bitwise operations clear
1279          ;; it (which correctly reflects the absence of overflow in a
1280          ;; compare-with-zero that might follow).  As for the
1281          ;; 0xfffffffe case, the add may overflow, so we can't use the
1282          ;; V flag.
1283          (ne (symbol_ref "GET_CODE (operands[2]) == CONST_INT
1284                           && (INTVAL (operands[2]) == 0x7fffffff
1285                               || INTVAL (operands[2]) == 0x3fffffff
1286                               || INTVAL (operands[2]) == 0x1fffffff
1287                               || INTVAL (operands[2]) == 0x0fffffff
1288                               || INTVAL (operands[2]) == 0xfffffffe
1289                               || INTVAL (operands[2]) == 0xfffffffc
1290                               || INTVAL (operands[2]) == 0xfffffff8
1291                               || INTVAL (operands[2]) == 0xfffffff0)")
1292              (const_int 0)) (const_string "set_zn")
1293           ] (const_string "set_znv")))])
1295 ;; ----------------------------------------------------------------------
1296 ;; OR INSTRUCTIONS
1297 ;; ----------------------------------------------------------------------
1299 (define_expand "iorsi3"
1300   [(set (match_operand:SI 0 "register_operand" "")
1301         (ior:SI (match_operand:SI 1 "register_operand" "")
1302                 (match_operand:SI 2 "nonmemory_operand" "")))]
1303   ""
1304   "")
1306 (define_insn ""
1307   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1308         (ior:SI (match_operand:SI 1 "register_operand" "%0,dax")
1309                 (match_operand:SI 2 "nonmemory_operand" "dxi,dax")))]
1310   "TARGET_AM33"
1311   "*
1313   if (REG_P (operands[2]) && REG_P (operands[1])
1314       && true_regnum (operands[0]) != true_regnum (operands[1])
1315       && true_regnum (operands[0]) != true_regnum (operands[2])
1316       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1317       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1318       && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
1319     return \"mov %1,%0\;or %2,%0\";
1320   if (REG_P (operands[2]) && REG_P (operands[1])
1321       && true_regnum (operands[0]) != true_regnum (operands[1])
1322       && true_regnum (operands[0]) != true_regnum (operands[2]))
1323     return \"or %1,%2,%0\";
1324   if (REG_P (operands[2]) && REG_P (operands[0])
1325       && true_regnum (operands[2]) == true_regnum (operands[0]))
1326     return \"or %1,%0\";
1327   return \"or %2,%0\";
1329   [(set_attr "cc" "set_znv")])
1331 (define_insn ""
1332   [(set (match_operand:SI 0 "register_operand" "=dx")
1333         (ior:SI (match_operand:SI 1 "register_operand" "%0")
1334                 (match_operand:SI 2 "nonmemory_operand" "dxi")))]
1335   ""
1336   "or %2,%0"
1337   [(set_attr "cc" "set_znv")])
1339 ;; ----------------------------------------------------------------------
1340 ;; XOR INSTRUCTIONS
1341 ;; ----------------------------------------------------------------------
1343 (define_expand "xorsi3"
1344   [(set (match_operand:SI 0 "register_operand" "")
1345         (xor:SI (match_operand:SI 1 "register_operand" "")
1346                 (match_operand:SI 2 "nonmemory_operand" "")))]
1347   ""
1348   "")
1350 (define_insn ""
1351   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1352         (xor:SI (match_operand:SI 1 "register_operand" "%0,dax")
1353                 (match_operand:SI 2 "nonmemory_operand" "dxi,dax")))]
1354   "TARGET_AM33"
1355   "*
1357   if (REG_P (operands[2]) && REG_P (operands[1])
1358       && true_regnum (operands[0]) != true_regnum (operands[1])
1359       && true_regnum (operands[0]) != true_regnum (operands[2])
1360       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1361       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1362       && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
1363     return \"mov %1,%0\;xor %2,%0\";
1364   if (REG_P (operands[2]) && REG_P (operands[1])
1365       && true_regnum (operands[0]) != true_regnum (operands[1])
1366       && true_regnum (operands[0]) != true_regnum (operands[2]))
1367     return \"xor %1,%2,%0\";
1368   if (REG_P (operands[2]) && REG_P (operands[0])
1369       && true_regnum (operands[2]) == true_regnum (operands[0]))
1370     return \"xor %1,%0\";
1371   return \"xor %2,%0\";
1373   [(set_attr "cc" "set_znv")])
1375 (define_insn ""
1376   [(set (match_operand:SI 0 "register_operand" "=dx")
1377         (xor:SI (match_operand:SI 1 "register_operand" "%0")
1378                 (match_operand:SI 2 "nonmemory_operand" "dxi")))]
1379   ""
1380   "xor %2,%0"
1381   [(set_attr "cc" "set_znv")])
1383 ;; ----------------------------------------------------------------------
1384 ;; NOT INSTRUCTIONS
1385 ;; ----------------------------------------------------------------------
1387 (define_expand "one_cmplsi2"
1388   [(set (match_operand:SI 0 "register_operand" "")
1389         (not:SI (match_operand:SI 1 "register_operand" "")))]
1390   ""
1391   "")
1393 (define_insn ""
1394   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1395         (not:SI (match_operand:SI 1 "register_operand" "0,0")))]
1396   "TARGET_AM33"
1397   "not %0"
1398   [(set_attr "cc" "set_znv")])
1400 (define_insn ""
1401   [(set (match_operand:SI 0 "register_operand" "=dx")
1402         (not:SI (match_operand:SI 1 "register_operand" "0")))]
1403   ""
1404   "not %0"
1405   [(set_attr "cc" "set_znv")])
1407 ;; -----------------------------------------------------------------
1408 ;; BIT FIELDS
1409 ;; -----------------------------------------------------------------
1412 ;; These set/clear memory in byte sized chunks.
1414 ;; They are no smaller/faster than loading the value into a register
1415 ;; and storing the register, but they don't need a scratch register
1416 ;; which may allow for better code generation.
1417 (define_insn ""
1418   [(set (match_operand:QI 0 "nonimmediate_operand" "=R,d") (const_int 0))]
1419   ""
1420   "@
1421   bclr 255,%A0
1422   clr %0"
1423   [(set_attr "cc" "clobber")])
1425 (define_insn ""
1426   [(set (match_operand:QI 0 "nonimmediate_operand" "=R,d") (const_int -1))]
1427   ""
1428   "@
1429   bset 255,%A0
1430   mov -1,%0"
1431   [(set_attr "cc" "clobber,none_0hit")])
1433 (define_insn ""
1434   [(set (match_operand:QI 0 "nonimmediate_operand" "+R,d")
1435         (subreg:QI
1436           (and:SI (subreg:SI (match_dup 0) 0)
1437                   (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
1438   ""
1439   "@
1440   bclr %N1,%A0
1441   and %1,%0"
1442   [(set_attr "cc" "clobber,set_znv")])
1444 (define_insn ""
1445   [(set (match_operand:QI 0 "memory_operand" "=R,T")
1446         (and:QI
1447          (match_dup 0)
1448          (not:QI (match_operand:QI 1 "nonmemory_operand" "i,d"))))]
1449   ""
1450   "@
1451   bclr %U1,%A0
1452   bclr %1,%0"
1453   [(set_attr "cc" "clobber,clobber")])
1455 (define_insn ""
1456   [(set (match_operand:QI 0 "nonimmediate_operand" "+R,d")
1457         (subreg:QI
1458           (ior:SI (subreg:SI (match_dup 0) 0)
1459                   (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
1460   ""
1461   "@
1462   bset %U1,%A0
1463   or %1,%0"
1464   [(set_attr "cc" "clobber,set_znv")])
1466 (define_expand "iorqi3"
1467   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1468         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
1469                 (match_operand:QI 2 "nonmemory_operand" "")))]
1470   ""
1471   "")
1473 (define_insn ""
1474   [(set (match_operand:QI 0 "nonimmediate_operand" "=R,T,r")
1475         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
1476                 ;; This constraint should really be nonmemory_operand,
1477                 ;; but making it general_operand, along with the
1478                 ;; condition that not both input operands are MEMs, it
1479                 ;; here helps combine do a better job.
1480                 (match_operand:QI 2 "general_operand" "i,d,ir")))]
1481   "TARGET_AM33 &&
1482    (GET_CODE (operands[2]) != MEM || GET_CODE (operands[1]) != MEM)"
1483   "@
1484   bset %U2,%A0
1485   bset %2,%0
1486   or %2,%0"
1487   [(set_attr "cc" "clobber,clobber,set_znv")])
1489 (define_insn ""
1490   [(set (match_operand:QI 0 "nonimmediate_operand" "=R,T,d")
1491         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
1492                 ;; This constraint should really be nonmemory_operand,
1493                 ;; but making it general_operand, along with the
1494                 ;; condition that not both input operands are MEMs, it
1495                 ;; here helps combine do a better job.
1496                 (match_operand:QI 2 "general_operand" "i,d,id")))]
1497   "GET_CODE (operands[2]) != MEM || GET_CODE (operands[1]) != MEM"
1498   "@
1499   bset %U2,%A0
1500   bset %2,%0
1501   or %2,%0"
1502   [(set_attr "cc" "clobber,clobber,set_znv")])
1504 (define_insn ""
1505   [(set (cc0)
1506      (zero_extract:SI (match_operand:SI 0 "register_operand" "dx")
1507                       (match_operand 1 "const_int_operand" "")
1508                       (match_operand 2 "const_int_operand" "")))]
1509   ""
1510   "*
1512   int len = INTVAL (operands[1]);
1513   int bit = INTVAL (operands[2]);
1514   int mask = 0;
1515   rtx xoperands[2];
1517   while (len > 0)
1518     {
1519       mask |= (1 << bit);
1520       bit++;
1521       len--;
1522     }
1524   xoperands[0] = operands[0];
1525   xoperands[1] = GEN_INT (trunc_int_for_mode (mask, SImode));
1526   output_asm_insn (\"btst %1,%0\", xoperands);
1527   return \"\";
1529   [(set_attr "cc" "clobber")])
1531 (define_insn ""
1532   [(set (cc0)
1533      (zero_extract:SI (match_operand:QI 0 "general_operand" "R,dx")
1534                       (match_operand 1 "const_int_operand" "")
1535                       (match_operand 2 "const_int_operand" "")))]
1536   "mask_ok_for_mem_btst (INTVAL (operands[1]), INTVAL (operands[2]))"
1537   "*
1539   int len = INTVAL (operands[1]);
1540   int bit = INTVAL (operands[2]);
1541   int mask = 0;
1542   rtx xoperands[2];
1544   while (len > 0)
1545     {
1546       mask |= (1 << bit);
1547       bit++;
1548       len--;
1549     }
1551   /* If the source operand is not a reg (ie it is memory), then extract the
1552      bits from mask that we actually want to test.  Note that the mask will
1553      never cross a byte boundary.  */
1554   if (!REG_P (operands[0]))
1555     {
1556       if (mask & 0xff)
1557         mask = mask & 0xff;
1558       else if (mask & 0xff00)
1559         mask = (mask >> 8) & 0xff;
1560       else if (mask & 0xff0000)
1561         mask = (mask >> 16) & 0xff;
1562       else if (mask & 0xff000000)
1563         mask = (mask >> 24) & 0xff;
1564     }
1565   
1566   xoperands[0] = operands[0];
1567   xoperands[1] = GEN_INT (trunc_int_for_mode (mask, SImode));
1568   if (GET_CODE (operands[0]) == REG)
1569     output_asm_insn (\"btst %1,%0\", xoperands);
1570   else
1571     output_asm_insn (\"btst %U1,%A0\", xoperands);
1572   return \"\";
1574   [(set_attr "cc" "clobber")])
1576 (define_insn ""
1577   [(set (cc0) (and:SI (match_operand:SI 0 "register_operand" "dx")
1578                       (match_operand:SI 1 "const_int_operand" "")))]
1579   ""
1580   "btst %1,%0"
1581   [(set_attr "cc" "clobber")])
1583 (define_insn ""
1584   [(set (cc0)
1585      (and:SI
1586        (subreg:SI (match_operand:QI 0 "general_operand" "R,dx") 0)
1587        (match_operand:SI 1 "const_8bit_operand" "")))]
1588   ""
1589   "@
1590   btst %U1,%A0
1591   btst %1,%0"
1592   [(set_attr "cc" "clobber")])
1595 ;; ----------------------------------------------------------------------
1596 ;; JUMP INSTRUCTIONS
1597 ;; ----------------------------------------------------------------------
1599 ;; Conditional jump instructions
1601 (define_expand "ble"
1602   [(set (pc)
1603         (if_then_else (le (cc0)
1604                           (const_int 0))
1605                       (label_ref (match_operand 0 "" ""))
1606                       (pc)))]
1607   ""
1608   "")
1610 (define_expand "bleu"
1611   [(set (pc)
1612         (if_then_else (leu (cc0)
1613                            (const_int 0))
1614                       (label_ref (match_operand 0 "" ""))
1615                       (pc)))]
1616   ""
1617   "")
1619 (define_expand "bge"
1620   [(set (pc)
1621         (if_then_else (ge (cc0)
1622                           (const_int 0))
1623                       (label_ref (match_operand 0 "" ""))
1624                       (pc)))]
1625   ""
1626   "")
1628 (define_expand "bgeu"
1629   [(set (pc)
1630         (if_then_else (geu (cc0)
1631                            (const_int 0))
1632                       (label_ref (match_operand 0 "" ""))
1633                       (pc)))]
1634   ""
1635   "")
1637 (define_expand "blt"
1638   [(set (pc)
1639         (if_then_else (lt (cc0)
1640                           (const_int 0))
1641                       (label_ref (match_operand 0 "" ""))
1642                       (pc)))]
1643   ""
1644   "")
1646 (define_expand "bltu"
1647   [(set (pc)
1648         (if_then_else (ltu (cc0)
1649                            (const_int 0))
1650                       (label_ref (match_operand 0 "" ""))
1651                       (pc)))]
1652   ""
1653   "")
1655 (define_expand "bgt"
1656   [(set (pc)
1657         (if_then_else (gt (cc0)
1658                           (const_int 0))
1659                       (label_ref (match_operand 0 "" ""))
1660                       (pc)))]
1661   ""
1662   "")
1664 (define_expand "bgtu"
1665   [(set (pc)
1666         (if_then_else (gtu (cc0)
1667                            (const_int 0))
1668                       (label_ref (match_operand 0 "" ""))
1669                       (pc)))]
1670   ""
1671   "")
1673 (define_expand "beq"
1674   [(set (pc)
1675         (if_then_else (eq (cc0)
1676                           (const_int 0))
1677                       (label_ref (match_operand 0 "" ""))
1678                       (pc)))]
1679   ""
1680   "")
1682 (define_expand "bne"
1683   [(set (pc)
1684         (if_then_else (ne (cc0)
1685                           (const_int 0))
1686                       (label_ref (match_operand 0 "" ""))
1687                       (pc)))]
1688   ""
1689   "")
1691 (define_insn ""
1692   [(set (pc)
1693         (if_then_else (match_operator 1 "comparison_operator"
1694                                       [(cc0) (const_int 0)])
1695                       (label_ref (match_operand 0 "" ""))
1696                       (pc)))]
1697   ""
1698   "*
1700   if (cc_status.mdep.fpCC)
1701     return \"fb%b1 %0\";
1702   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1703       && (GET_CODE (operands[1]) == GT
1704           || GET_CODE (operands[1]) == GE
1705           || GET_CODE (operands[1]) == LE
1706           || GET_CODE (operands[1]) == LT))
1707     return 0;
1708   return \"b%b1 %0\";
1710  [(set_attr "cc" "none")])
1712 (define_insn ""
1713   [(set (pc)
1714         (if_then_else (match_operator 1 "comparison_operator"
1715                                       [(cc0) (const_int 0)])
1716                       (pc)
1717                       (label_ref (match_operand 0 "" ""))))]
1718   ""
1719   "*
1721   if (cc_status.mdep.fpCC)
1722     return \"fb%B1 %0\";
1723   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1724       && (GET_CODE (operands[1]) == GT
1725           || GET_CODE (operands[1]) == GE
1726           || GET_CODE (operands[1]) == LE
1727           || GET_CODE (operands[1]) == LT))
1728     return 0;
1729   return \"b%B1 %0\";
1731  [(set_attr "cc" "none")])
1733 ;; Unconditional and other jump instructions.
1735 (define_insn "jump"
1736   [(set (pc)
1737         (label_ref (match_operand 0 "" "")))]
1738   ""
1739   "jmp %l0"
1740  [(set_attr "cc" "none")])
1742 (define_insn "indirect_jump"
1743   [(set (pc) (match_operand:SI 0 "register_operand" "a"))]
1744   ""
1745   "jmp (%0)"
1746   [(set_attr "cc" "none")])
1748 (define_expand "builtin_setjmp_receiver"
1749   [(match_operand 0 "" "")]
1750   "flag_pic"
1751   "
1753   if (flag_pic)
1754     emit_insn (gen_GOTaddr2picreg ());
1756   DONE;
1759 (define_expand "casesi"
1760   [(match_operand:SI 0 "register_operand" "")
1761    (match_operand:SI 1 "immediate_operand" "")
1762    (match_operand:SI 2 "immediate_operand" "")
1763    (match_operand 3 "" "") (match_operand 4 "" "")]
1764   ""
1765   "
1767   rtx table = gen_reg_rtx (SImode);
1768   rtx index = gen_reg_rtx (SImode);
1769   rtx addr = gen_reg_rtx (Pmode);
1771   emit_move_insn (table, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
1772   emit_move_insn (index, plus_constant (operands[0], - INTVAL (operands[1])));
1773   emit_insn (gen_cmpsi (index, operands[2]));
1774   emit_jump_insn (gen_bgtu (operands[4]));
1775   emit_move_insn (index, gen_rtx_ASHIFT (SImode, index, GEN_INT (2)));
1776   emit_move_insn (addr, gen_rtx_MEM (SImode,
1777                                      gen_rtx_PLUS (SImode, table, index)));
1778   if (flag_pic)
1779     emit_move_insn (addr, gen_rtx_PLUS (SImode, addr, table));
1781   emit_jump_insn (gen_tablejump (addr, operands[3]));
1782   DONE;
1785 (define_insn "tablejump"
1786   [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1787    (use (label_ref (match_operand 1 "" "")))]
1788   ""
1789   "jmp (%0)"
1790   [(set_attr "cc" "none")])
1792 ;; Call subroutine with no return value.
1794 (define_expand "call"
1795   [(call (match_operand:QI 0 "general_operand" "")
1796          (match_operand:SI 1 "general_operand" ""))]
1797   ""
1798   "
1800   if (flag_pic && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
1801     {
1802       if (MN10300_GLOBAL_P (XEXP (operands[0], 0)))
1803         {
1804           /* The PLT code won't run on AM30, but then, there's no
1805              shared library support for AM30 either, so we just assume
1806              the linker is going to adjust all @PLT relocs to the
1807              actual symbols.  */
1808           emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
1809           XEXP (operands[0], 0) = gen_sym2PLT (XEXP (operands[0], 0));
1810         }
1811       else
1812         XEXP (operands[0], 0) = gen_sym2PIC (XEXP (operands[0], 0));
1813     }
1814   if (! call_address_operand (XEXP (operands[0], 0), VOIDmode))
1815     XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
1816   emit_call_insn (gen_call_internal (XEXP (operands[0], 0), operands[1]));
1817   DONE;
1820 (define_insn "call_internal"
1821   [(call (mem:QI (match_operand:SI 0 "call_address_operand" "aS"))
1822          (match_operand:SI 1 "general_operand" "g"))]
1823   ""
1824   "*
1826   if (REG_P (operands[0]))
1827     return \"calls %C0\";
1828   else
1829     return \"call %C0,[],0\";
1831   [(set_attr "cc" "clobber")])
1833 ;; Call subroutine, returning value in operand 0
1834 ;; (which must be a hard register).
1836 (define_expand "call_value"
1837   [(set (match_operand 0 "" "")
1838         (call (match_operand:QI 1 "general_operand" "")
1839               (match_operand:SI 2 "general_operand" "")))]
1840   ""
1841   "
1843   if (flag_pic && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
1844     {
1845       if (MN10300_GLOBAL_P (XEXP (operands[1], 0)))
1846         {
1847           /* The PLT code won't run on AM30, but then, there's no
1848              shared library support for AM30 either, so we just assume
1849              the linker is going to adjust all @PLT relocs to the
1850              actual symbols.  */
1851           emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
1852           XEXP (operands[1], 0) = gen_sym2PLT (XEXP (operands[1], 0));
1853         }
1854       else
1855         XEXP (operands[1], 0) = gen_sym2PIC (XEXP (operands[1], 0));
1856     }
1857   if (! call_address_operand (XEXP (operands[1], 0), VOIDmode))
1858     XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
1859   emit_call_insn (gen_call_value_internal (operands[0],
1860                                            XEXP (operands[1], 0),
1861                                            operands[2]));
1862   DONE;
1865 (define_insn "call_value_internal"
1866   [(set (match_operand 0 "" "=dax")
1867         (call (mem:QI (match_operand:SI 1 "call_address_operand" "aS"))
1868               (match_operand:SI 2 "general_operand" "g")))]
1869   ""
1870   "*
1872   if (REG_P (operands[1]))
1873     return \"calls %C1\";
1874   else
1875     return \"call %C1,[],0\";
1877   [(set_attr "cc" "clobber")])
1879 (define_expand "untyped_call"
1880   [(parallel [(call (match_operand 0 "" "")
1881                     (const_int 0))
1882               (match_operand 1 "" "")
1883               (match_operand 2 "" "")])]
1884   ""
1885   "
1887   int i;
1889   emit_call_insn (gen_call (operands[0], const0_rtx));
1891   for (i = 0; i < XVECLEN (operands[2], 0); i++)
1892     {
1893       rtx set = XVECEXP (operands[2], 0, i);
1894       emit_move_insn (SET_DEST (set), SET_SRC (set));
1895     }
1896   DONE;
1899 (define_insn "nop"
1900   [(const_int 0)]
1901   ""
1902   "nop"
1903   [(set_attr "cc" "none")])
1905 ;; ----------------------------------------------------------------------
1906 ;; EXTEND INSTRUCTIONS
1907 ;; ----------------------------------------------------------------------
1909 (define_expand "zero_extendqisi2"
1910   [(set (match_operand:SI 0 "general_operand" "")
1911         (zero_extend:SI
1912          (match_operand:QI 1 "general_operand" "")))]
1913   ""
1914   "")
1916 (define_insn ""
1917   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx,!dax,!dax,!dax")
1918         (zero_extend:SI
1919          (match_operand:QI 1 "general_operand" "0,dax,m,0,dax,m")))]
1920   "TARGET_AM33"
1921   "@
1922   extbu %0
1923   mov %1,%0\;extbu %0
1924   movbu %1,%0
1925   extbu %0
1926   mov %1,%0\;extbu %0
1927   movbu %1,%0"
1928   [(set_attr "cc" "none_0hit")])
1930 (define_insn ""
1931   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx")
1932         (zero_extend:SI
1933          (match_operand:QI 1 "general_operand" "0,d,m")))]
1934   ""
1935   "@
1936   extbu %0
1937   mov %1,%0\;extbu %0
1938   movbu %1,%0"
1939   [(set_attr "cc" "none_0hit")])
1941 (define_expand "zero_extendhisi2"
1942   [(set (match_operand:SI 0 "general_operand" "")
1943         (zero_extend:SI
1944          (match_operand:HI 1 "general_operand" "")))]
1945   ""
1946   "")
1948 (define_insn ""
1949   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx,!dax,!dax,!dax")
1950         (zero_extend:SI
1951          (match_operand:HI 1 "general_operand" "0,dax,m,0,dax,m")))]
1952   "TARGET_AM33"
1953   "@
1954   exthu %0
1955   mov %1,%0\;exthu %0
1956   movhu %1,%0
1957   exthu %0
1958   mov %1,%0\;exthu %0
1959   movhu %1,%0"
1960   [(set_attr "cc" "none_0hit")])
1962 (define_insn ""
1963   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx")
1964         (zero_extend:SI
1965          (match_operand:HI 1 "general_operand" "0,dx,m")))]
1966   ""
1967   "@
1968   exthu %0
1969   mov %1,%0\;exthu %0
1970   movhu %1,%0"
1971   [(set_attr "cc" "none_0hit")])
1973 ;;- sign extension instructions
1975 (define_expand "extendqisi2"
1976   [(set (match_operand:SI 0 "general_operand" "")
1977         (sign_extend:SI
1978          (match_operand:QI 1 "general_operand" "")))]
1979   ""
1980   "")
1982 (define_insn ""
1983   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,!dax,!dax")
1984         (sign_extend:SI
1985          (match_operand:QI 1 "general_operand" "0,dx,0,dax")))]
1986   "TARGET_AM33"
1987   "@
1988   extb %0
1989   mov %1,%0\;extb %0
1990   extb %0
1991   mov %1,%0\;extb %0"
1992   [(set_attr "cc" "none_0hit")])
1994 (define_insn ""
1995   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx")
1996         (sign_extend:SI
1997          (match_operand:QI 1 "general_operand" "0,dx")))]
1998   ""
1999   "@
2000   extb %0
2001   mov %1,%0\;extb %0"
2002   [(set_attr "cc" "none_0hit")])
2004 (define_expand "extendhisi2"
2005   [(set (match_operand:SI 0 "general_operand" "")
2006         (sign_extend:SI
2007          (match_operand:HI 1 "general_operand" "")))]
2008   ""
2009   "")
2011 (define_insn ""
2012   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,!dax,!dax")
2013         (sign_extend:SI
2014          (match_operand:HI 1 "general_operand" "0,dax,0,dax")))]
2015   "TARGET_AM33"
2016   "@
2017   exth %0
2018   mov %1,%0\;exth %0
2019   exth %0
2020   mov %1,%0\;exth %0"
2021   [(set_attr "cc" "none_0hit")])
2023 (define_insn ""
2024   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx")
2025         (sign_extend:SI
2026          (match_operand:HI 1 "general_operand" "0,dx")))]
2027   ""
2028   "@
2029   exth %0
2030   mov %1,%0\;exth %0"
2031   [(set_attr "cc" "none_0hit")])
2033 ;; ----------------------------------------------------------------------
2034 ;; SHIFTS
2035 ;; ----------------------------------------------------------------------
2037 (define_expand "ashlsi3"
2038   [(set (match_operand:SI 0 "register_operand" "")
2039         (ashift:SI
2040          (match_operand:SI 1 "register_operand" "")
2041          (match_operand:QI 2 "nonmemory_operand" "")))]
2042   ""
2043   "")
2045 (define_insn ""
2046   [(set (match_operand:SI 0 "register_operand" "=dax,dx,!dax")
2047         (ashift:SI
2048          (match_operand:SI 1 "register_operand" "0,0,dax")
2049          (match_operand:QI 2 "nonmemory_operand" "J,dxi,dax")))]
2050   "TARGET_AM33"
2051   "*
2053   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 1)
2054     return \"add %0,%0\";
2056   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 2)
2057     return \"asl2 %0\";
2059   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 3
2060       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS)
2061     return \"asl2 %0\;add %0,%0\";
2063   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 4
2064       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS)
2065     return \"asl2 %0\;asl2 %0\";
2067   if (true_regnum (operands[1]) == true_regnum (operands[0]))
2068     return \"asl %S2,%0\";
2070   if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
2071       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
2072       && true_regnum (operands[0]) != true_regnum (operands[2]))
2073     return \"mov %1,%0\;asl %S2,%0\";
2074   return \"asl %2,%1,%0\";
2076   [(set_attr "cc" "set_zn")])
2078 (define_insn ""
2079   [(set (match_operand:SI 0 "register_operand" "=dax,dx,dx,dx,dx")
2080         (ashift:SI
2081          (match_operand:SI 1 "register_operand" "0,0,0,0,0")
2082          (match_operand:QI 2 "nonmemory_operand" "J,K,M,L,dxi")))]
2083   ""
2084   "@
2085   add %0,%0
2086   asl2 %0
2087   asl2 %0\;add %0,%0
2088   asl2 %0\;asl2 %0
2089   asl %S2,%0"
2090   [(set_attr "cc" "set_zn")])
2092 (define_expand "lshrsi3"
2093   [(set (match_operand:SI 0 "register_operand" "")
2094         (lshiftrt:SI
2095          (match_operand:SI 1 "register_operand" "")
2096          (match_operand:QI 2 "nonmemory_operand" "")))]
2097   ""
2098   "")
2100 (define_insn ""
2101   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
2102         (lshiftrt:SI
2103          (match_operand:SI 1 "register_operand" "0,dax")
2104          (match_operand:QI 2 "nonmemory_operand" "dxi,dax")))]
2105   "TARGET_AM33"
2106   "*
2108   if (true_regnum (operands[1]) == true_regnum (operands[0]))
2109     return \"lsr %S2,%0\";
2111   if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
2112       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
2113       && true_regnum (operands[0]) != true_regnum (operands[2]))
2114     return \"mov %1,%0\;lsr %S2,%0\";
2115   return \"lsr %2,%1,%0\";
2117   [(set_attr "cc" "set_zn")])
2119 (define_insn ""
2120   [(set (match_operand:SI 0 "register_operand" "=dx")
2121         (lshiftrt:SI
2122          (match_operand:SI 1 "register_operand" "0")
2123          (match_operand:QI 2 "nonmemory_operand" "dxi")))]
2124   ""
2125   "lsr %S2,%0"
2126   [(set_attr "cc" "set_zn")])
2128 (define_expand "ashrsi3"
2129   [(set (match_operand:SI 0 "register_operand" "")
2130         (ashiftrt:SI
2131          (match_operand:SI 1 "register_operand" "")
2132          (match_operand:QI 2 "nonmemory_operand" "")))]
2133   ""
2134   "")
2136 (define_insn ""
2137   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
2138         (ashiftrt:SI
2139          (match_operand:SI 1 "register_operand" "0,dax")
2140          (match_operand:QI 2 "nonmemory_operand" "dxi,dax")))]
2141   "TARGET_AM33"
2142   "*
2144   if (true_regnum (operands[1]) == true_regnum (operands[0]))
2145     return \"asr %S2,%0\";
2147   if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
2148       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
2149       && true_regnum (operands[0]) != true_regnum (operands[2]))
2150     return \"mov %1,%0\;asr %S2,%0\";
2151   return \"asr %2,%1,%0\";
2153   [(set_attr "cc" "set_zn")])
2155 (define_insn ""
2156   [(set (match_operand:SI 0 "register_operand" "=dx")
2157         (ashiftrt:SI
2158          (match_operand:SI 1 "register_operand" "0")
2159          (match_operand:QI 2 "nonmemory_operand" "dxi")))]
2160   ""
2161   "asr %S2,%0"
2162   [(set_attr "cc" "set_zn")])
2164 ;; ----------------------------------------------------------------------
2165 ;; FP INSTRUCTIONS
2166 ;; ----------------------------------------------------------------------
2168 ;; The mn103 series does not have floating point instructions, but since
2169 ;; FP values are held in integer regs, we can clear the high bit easily
2170 ;; which gives us an efficient inline floating point absolute value.
2172 ;; Similarly for negation of a FP value.
2175 (define_expand "absdf2"
2176   [(set (match_operand:DF 0 "register_operand" "")
2177         (abs:DF (match_operand:DF 1 "register_operand" "")))]
2178   ""
2179   "
2181   rtx target, result, insns;
2183   start_sequence ();
2184   target = operand_subword (operands[0], 1, 1, DFmode);
2185   result = expand_binop (SImode, and_optab,
2186                          operand_subword_force (operands[1], 1, DFmode),
2187                          GEN_INT (0x7fffffff), target, 0, OPTAB_WIDEN);
2189   if (result == 0)
2190     abort ();
2192   if (result != target)
2193     emit_move_insn (result, target);
2195   emit_move_insn (operand_subword (operands[0], 0, 1, DFmode),
2196                   operand_subword_force (operands[1], 0, DFmode));
2198   insns = get_insns ();
2199   end_sequence ();
2201   emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
2202   DONE;
2205 (define_expand "abssf2"
2206   [(set (match_operand:SF 0 "register_operand" "")
2207         (abs:SF (match_operand:SF 1 "register_operand" "")))]
2208   ""
2209   "
2211   rtx result;
2212   rtx target;
2214   if (TARGET_AM33_2)
2215     {
2216       emit_insn (gen_abssf2_am33_2 (operands[0], operands[1]));
2217       DONE;
2218     }
2220   target = operand_subword_force (operands[0], 0, SFmode);
2221   result = expand_binop (SImode, and_optab,
2222                          operand_subword_force (operands[1], 0, SFmode),
2223                          GEN_INT (0x7fffffff), target, 0, OPTAB_WIDEN);
2224   if (result == 0)
2225     abort ();
2227   if (result != target)
2228     emit_move_insn (result, target);
2230   /* Make a place for REG_EQUAL.  */
2231   emit_move_insn (operands[0], operands[0]);
2232   DONE;
2236 (define_insn "abssf2_am33_2"
2237   [(set (match_operand:SF 0 "register_operand" "=f,f")
2238         (abs:SF (match_operand:SF 1 "register_operand" "0,?f")))]
2239   "TARGET_AM33_2"
2240   "@
2241    fabs %0
2242    fabs %1, %0"
2243   [(set_attr "cc" "none_0hit")])
2245 (define_expand "negdf2"
2246   [(set (match_operand:DF 0 "register_operand" "")
2247         (neg:DF (match_operand:DF 1 "register_operand" "")))]
2248   ""
2249   "
2251   rtx target, result, insns;
2253   start_sequence ();
2254   target = operand_subword (operands[0], 1, 1, DFmode);
2255   result = expand_binop (SImode, xor_optab,
2256                          operand_subword_force (operands[1], 1, DFmode),
2257                          GEN_INT (trunc_int_for_mode (0x80000000, SImode)),
2258                          target, 0, OPTAB_WIDEN);
2260   if (result == 0)
2261     abort ();
2263   if (result != target)
2264     emit_move_insn (result, target);
2266   emit_move_insn (operand_subword (operands[0], 0, 1, DFmode),
2267                   operand_subword_force (operands[1], 0, DFmode));
2269   insns = get_insns ();
2270   end_sequence ();
2272   emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
2273   DONE;
2276 (define_expand "negsf2"
2277   [(set (match_operand:SF 0 "register_operand" "")
2278         (neg:SF (match_operand:SF 1 "register_operand" "")))]
2279   ""
2280   "
2282   rtx result;
2283   rtx target;
2285   if (TARGET_AM33_2)
2286     {
2287       emit_insn (gen_negsf2_am33_2 (operands[0], operands[1]));
2288       DONE;
2289     }
2291   target = operand_subword_force (operands[0], 0, SFmode);
2292   result = expand_binop (SImode, xor_optab,
2293                          operand_subword_force (operands[1], 0, SFmode),
2294                          GEN_INT (trunc_int_for_mode (0x80000000, SImode)),
2295                          target, 0, OPTAB_WIDEN);
2296   if (result == 0)
2297     abort ();
2299   if (result != target)
2300     emit_move_insn (result, target);
2302   /* Make a place for REG_EQUAL.  */
2303   emit_move_insn (operands[0], operands[0]);
2304   DONE;
2307 (define_insn "negsf2_am33_2"
2308   [(set (match_operand:SF 0 "register_operand" "=f,f")
2309         (neg:SF (match_operand:SF 1 "register_operand" "0,?f")))]
2310   "TARGET_AM33_2"
2311   "@
2312    fneg %0
2313    fneg %1, %0"
2314   [(set_attr "cc" "none_0hit")])
2316 (define_expand "sqrtsf2"
2317   [(set (match_operand:SF 0 "register_operand" "")
2318         (sqrt:SF (match_operand:SF 1 "register_operand" "")))]
2319   "TARGET_AM33_2 && flag_unsafe_math_optimizations"
2320   "
2322   rtx scratch = gen_reg_rtx (SFmode);
2323   emit_insn (gen_rsqrtsf2 (scratch, operands[1], CONST1_RTX (SFmode)));
2324   emit_insn (gen_divsf3 (operands[0], force_reg (SFmode, CONST1_RTX (SFmode)),
2325                          scratch));
2326   DONE;
2329 (define_insn "rsqrtsf2"
2330   [(set (match_operand:SF 0 "register_operand" "=f,f")
2331         (div:SF (match_operand:SF 2 "const_1f_operand" "F,F")
2332                 (sqrt:SF (match_operand:SF 1 "register_operand" "0,?f"))))]
2333   "TARGET_AM33_2"
2334   "@
2335    frsqrt %0
2336    frsqrt %1, %0"
2337   [(set_attr "cc" "none_0hit")])
2339 (define_insn "addsf3"
2340   [(set (match_operand:SF 0 "register_operand" "=f,f")
2341         (plus:SF (match_operand:SF 1 "register_operand" "%0,f")
2342                  (match_operand:SF 2 "general_operand" "f,?fF")))]
2343   "TARGET_AM33_2"
2344   "@
2345    fadd %2, %0
2346    fadd %2, %1, %0"
2347   [(set_attr "cc" "none_0hit")])
2349 (define_insn "subsf3"
2350   [(set (match_operand:SF 0 "register_operand" "=f,f")
2351         (minus:SF (match_operand:SF 1 "register_operand" "0,f")
2352                   (match_operand:SF 2 "general_operand" "f,?fF")))]
2353   "TARGET_AM33_2"
2354   "@
2355    fsub %2, %0
2356    fsub %2, %1, %0"
2357   [(set_attr "cc" "none_0hit")])
2359 (define_insn "mulsf3"
2360   [(set (match_operand:SF 0 "register_operand" "=f,f")
2361         (mult:SF (match_operand:SF 1 "register_operand" "%0,f")
2362                  (match_operand:SF 2 "general_operand" "f,?fF")))]
2363   "TARGET_AM33_2"
2364   "@
2365    fmul %2, %0
2366    fmul %2, %1, %0"
2367   [(set_attr "cc" "none_0hit")])
2369 (define_insn "divsf3"
2370   [(set (match_operand:SF 0 "register_operand" "=f,f")
2371         (div:SF (match_operand:SF 1 "register_operand" "0,f")
2372                 (match_operand:SF 2 "general_operand" "f,?fF")))]
2373   "TARGET_AM33_2"
2374   "@
2375    fdiv %2, %0
2376    fdiv %2, %1, %0"
2377   [(set_attr "cc" "none_0hit")])
2379 (define_insn "fmaddsf4"
2380   [(set (match_operand:SF 0 "register_operand" "=A")
2381         (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
2382                           (match_operand:SF 2 "register_operand" "f"))
2383                  (match_operand:SF 3 "register_operand" "f")))]
2384   "TARGET_AM33_2"
2385   "fmadd %1, %2, %3, %0"
2386   [(set_attr "cc" "none_0hit")])
2388 (define_insn "fmsubsf4"
2389   [(set (match_operand:SF 0 "register_operand" "=A")
2390         (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
2391                            (match_operand:SF 2 "register_operand" "f"))
2392                   (match_operand:SF 3 "register_operand" "f")))]
2393   "TARGET_AM33_2"
2394   "fmsub %1, %2, %3, %0"
2395   [(set_attr "cc" "none_0hit")])
2397 (define_insn "fnmaddsf4"
2398   [(set (match_operand:SF 0 "register_operand" "=A")
2399         (minus:SF (match_operand:SF 3 "register_operand" "f")
2400                   (mult:SF (match_operand:SF 1 "register_operand" "%f")
2401                            (match_operand:SF 2 "register_operand" "f"))))]
2402   "TARGET_AM33_2"
2403   "fnmadd %1, %2, %3, %0"
2404   [(set_attr "cc" "none_0hit")])
2406 (define_insn "fnmsubsf4"
2407   [(set (match_operand:SF 0 "register_operand" "=A")
2408         (minus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
2409                                    (match_operand:SF 2 "register_operand" "f")))
2410                   (match_operand:SF 3 "register_operand" "f")))]
2411   "TARGET_AM33_2"
2412   "fnmsub %1, %2, %3, %0"
2413   [(set_attr "cc" "none_0hit")])
2416 ;; ----------------------------------------------------------------------
2417 ;; PROLOGUE/EPILOGUE
2418 ;; ----------------------------------------------------------------------
2419 (define_expand "prologue"
2420   [(const_int 0)]
2421   ""
2422   "expand_prologue (); DONE;")
2424 (define_expand "epilogue"
2425   [(return)]
2426   ""
2427   "
2429   expand_epilogue ();
2430   DONE;
2433 (define_insn "return_internal"
2434   [(const_int 2)
2435    (return)]
2436   ""
2437   "rets"
2438   [(set_attr "cc" "clobber")])
2440 ;; This insn restores the callee saved registers and does a return, it
2441 ;; can also deallocate stack space.
2442 (define_insn "return_internal_regs"
2443   [(const_int 0)
2444    (match_operand:SI 0  "const_int_operand" "i")
2445    (return)]
2446   ""
2447   "*
2449   fputs (\"\\tret \", asm_out_file);
2450   mn10300_print_reg_list (asm_out_file, mn10300_get_live_callee_saved_regs ());
2451   fprintf (asm_out_file, \",%d\\n\", (int) INTVAL (operands[0]));
2452   return \"\";
2454   [(set_attr "cc" "clobber")])
2456 ;; This instruction matches one generated by mn10300_gen_multiple_store()
2457 (define_insn "store_movm"
2458   [(match_parallel 0 "store_multiple_operation"
2459     [(set (reg:SI 9) (plus:SI (reg:SI 9) (match_operand 1 "" "")))])]
2460   ""
2461   "*
2463   fputs (\"\\tmovm \", asm_out_file);
2464   mn10300_print_reg_list (asm_out_file,
2465                           store_multiple_operation (operands[0], VOIDmode));
2466   fprintf (asm_out_file, \",(sp)\\n\");
2467   return \"\";
2469   [(set_attr "cc" "clobber")])
2470   
2471 (define_insn "return"
2472   [(return)]
2473   "can_use_return_insn ()"
2474   "*
2476   rtx next = next_active_insn (insn);
2478   if (next
2479       && GET_CODE (next) == JUMP_INSN
2480       && GET_CODE (PATTERN (next)) == RETURN)
2481     return \"\";
2482   else
2483     return \"rets\";
2485   [(set_attr "cc" "clobber")])
2487 ;; Try to combine consecutive updates of the stack pointer (or any
2488 ;; other register for that matter).
2489 (define_peephole
2490   [(set (match_operand:SI 0 "register_operand" "=dxay")
2491         (plus:SI (match_dup 0)
2492                  (match_operand 1 "const_int_operand" "")))
2493    (set (match_dup 0)
2494         (plus:SI (match_dup 0)
2495                  (match_operand 2 "const_int_operand" "")))]
2496   ""
2497   "*
2499   operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]));
2500   return \"add %1,%0\";
2502   [(set_attr "cc" "clobber")])
2505 ;; We had patterns to check eq/ne, but the they don't work because
2506 ;; 0x80000000 + 0x80000000 = 0x0 with a carry out.
2508 ;; The Z flag and C flag would be set, and we have no way to
2509 ;; check for the Z flag set and C flag clear.
2511 ;; This will work on the mn10200 because we can check the ZX flag
2512 ;; if the comparison is in HImode.
2513 (define_peephole
2514   [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2515    (set (pc) (if_then_else (ge (cc0) (const_int 0))
2516                            (match_operand 1 "" "")
2517                            (pc)))]
2518   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2519   "add %0,%0\;bcc %1"
2520   [(set_attr "cc" "clobber")])
2522 (define_peephole
2523   [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2524    (set (pc) (if_then_else (lt (cc0) (const_int 0))
2525                            (match_operand 1 "" "")
2526                            (pc)))]
2527   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2528   "add %0,%0\;bcs %1"
2529   [(set_attr "cc" "clobber")])
2531 (define_peephole
2532   [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2533    (set (pc) (if_then_else (ge (cc0) (const_int 0))
2534                            (pc)
2535                            (match_operand 1 "" "")))]
2536   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2537   "add %0,%0\;bcs %1"
2538   [(set_attr "cc" "clobber")])
2540 (define_peephole
2541   [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2542    (set (pc) (if_then_else (lt (cc0) (const_int 0))
2543                            (pc)
2544                            (match_operand 1 "" "")))]
2545   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2546   "add %0,%0\;bcc %1"
2547   [(set_attr "cc" "clobber")])
2549 (define_expand "int_label"
2550   [(unspec [(match_operand:SI 0 "" "")] UNSPEC_INT_LABEL)]
2551   "" "")
2553 (define_expand "GOTaddr2picreg"
2554   [(match_dup 0)]
2555   "" "
2557   /* It would be nice to be able to have int_label keep track of the
2558      counter and all, but if we add C code to it, we'll get an insn
2559      back, and we just want the pattern.  */
2560   operands[0] = gen_int_label (GEN_INT (mn10300_unspec_int_label_counter++));
2561   if (TARGET_AM33)
2562     emit_insn (gen_am33_loadPC (operands[0]));
2563   else
2564     emit_insn (gen_mn10300_loadPC (operands[0]));
2565   emit_insn (gen_add_GOT_to_pic_reg (operands[0]));
2566   DONE;
2570 (define_insn "am33_loadPC"
2571   [(parallel
2572     [(set (reg:SI PIC_REG) (pc))
2573      (use (match_operand 0 "" ""))])]
2574   "TARGET_AM33"
2575   "%0:\;mov pc,a2")
2578 (define_insn_and_split "mn10300_loadPC"
2579   [(parallel
2580     [(set (reg:SI PIC_REG) (pc))
2581      (use (match_operand 0 "" ""))])]
2582   ""
2583   "#"
2584   "reload_completed"
2585   [(match_operand 0 "" "")]
2586   "
2588   rtx sp_reg = gen_rtx_REG (SImode, SP_REG);
2589   int need_stack_space = (get_frame_size () == 0
2590                           && current_function_outgoing_args_size == 0);
2592   if (need_stack_space)
2593     emit_move_insn (sp_reg, plus_constant (sp_reg, -4));
2595   emit_insn (gen_call_next_insn (operands[0]));
2597   if (need_stack_space)
2598     emit_insn (gen_pop_pic_reg ());
2599   else
2600     emit_move_insn (pic_offset_table_rtx, gen_rtx_MEM (SImode, sp_reg));
2602   DONE;
2605 (define_insn "call_next_insn"
2606   [(parallel
2607     [(set (mem:SI (reg:SI SP_REG)) (pc))
2608      (use (match_operand 0 "" ""))])]
2609   "reload_completed"
2610   "calls %0\;%0:")
2612 (define_expand "add_GOT_to_pic_reg"
2613   [(set (reg:SI PIC_REG)
2614         (plus:SI
2615          (reg:SI PIC_REG)
2616          (const
2617           (unspec [(minus:SI
2618                     (match_dup 1)
2619                     (const (minus:SI
2620                             (const (match_operand:SI 0 "" ""))
2621                             (pc))))
2622                   ] UNSPEC_PIC))))]
2623   ""
2624   "
2626   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
2629 (define_expand "symGOT2reg"
2630   [(match_operand:SI 0 "" "")
2631    (match_operand:SI 1 "" "")]
2632   ""
2633   "
2635   rtx insn = emit_insn (gen_symGOT2reg_i (operands[0], operands[1]));
2637   RTX_UNCHANGING_P (SET_SRC (PATTERN (insn))) = 1;
2639   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
2640                                         REG_NOTES (insn));
2642   DONE;
2645 (define_expand "symGOT2reg_i"
2646   [(set (match_operand:SI 0 "" "")
2647         (mem:SI (plus:SI (reg:SI PIC_REG)
2648                          (const (unspec [(match_operand:SI 1 "" "")]
2649                                         UNSPEC_GOT)))))]
2650   ""
2651   "")
2653 (define_expand "symGOTOFF2reg"
2654   [(match_operand:SI 0 "" "") (match_operand:SI 1 "" "")]
2655   ""
2656   "
2658   rtx insn = emit_insn (gen_symGOTOFF2reg_i (operands[0], operands[1]));
2660   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
2661                                         REG_NOTES (insn));
2663   DONE;
2666 (define_expand "symGOTOFF2reg_i"
2667   [(set (match_operand:SI 0 "" "")
2668         (const (unspec [(match_operand:SI 1 "" "")] UNSPEC_GOTOFF)))
2669   (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI PIC_REG)))]
2670   ""
2671   "")
2673 (define_expand "sym2PIC"
2674   [(unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC)]
2675   "" "")
2677 (define_expand "sym2PLT"
2678   [(unspec [(match_operand:SI 0 "" "")] UNSPEC_PLT)]
2679   "" "")