2003-06-16 Alexandre Oliva <aoliva@redhat.com>
[official-gcc.git] / gcc / config / mn10300 / mn10300.md
blob27a40ef37204c4564539de0302c0cdb0d64cd1fe
1 ;; GCC machine description for Matsushita MN10300
2 ;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
3 ;; Free Software Foundation, Inc.
4 ;; Contributed by Jeff Law (law@cygnus.com).
6 ;; This file is part of GNU CC.
8 ;; GNU CC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 2, or (at your option)
11 ;; any later version.
13 ;; GNU CC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GNU CC; see the file COPYING.  If not, write to
20 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
21 ;; Boston, MA 02111-1307, USA.
23 ;; The original PO technology requires these to be ordered by speed,
24 ;; so that assigner will pick the fastest.
26 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;; Condition code settings.
29 ;; none - insn does not affect cc
30 ;; none_0hit - insn does not affect cc but it does modify operand 0
31 ;;      This attribute is used to keep track of when operand 0 changes.
32 ;;      See the description of NOTICE_UPDATE_CC for more info.
33 ;; set_znv - insn sets z,n,v to usable values; c is unusable.
34 ;; set_zn  - insn sets z,n to usable values; v,c are unusable.
35 ;; compare - compare instruction
36 ;; invert -- like compare, but flags are inverted.
37 ;; clobber - value of cc is unknown
38 (define_attr "cc" "none,none_0hit,set_znv,set_zn,compare,clobber,invert"
39   (const_string "clobber"))
41 (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 preferrable 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" "none_0hit,set_znv,set_znv")])
1229 (define_insn ""
1230   [(set (match_operand:SI 0 "register_operand" "=dx,dx")
1231         (and:SI (match_operand:SI 1 "register_operand" "%0,0")
1232                 (match_operand:SI 2 "nonmemory_operand" "N,dxi")))]
1233   ""
1234   "*
1236   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff)
1237     return \"extbu %0\";
1238   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xffff)
1239     return \"exthu %0\";
1240   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x7fffffff)
1241     return \"add %0,%0\;lsr 1,%0\";
1242   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x3fffffff)
1243     return \"asl2 %0\;lsr 2,%0\";
1244   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x1fffffff)
1245     return \"add %0,%0\;asl2 %0\;lsr 3,%0\";
1246   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x0fffffff)
1247     return \"asl2 %0\;asl2 %0\;lsr 4,%0\";
1248   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffe)
1249     return \"lsr 1,%0\;add %0,%0\";
1250   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffc)
1251     return \"lsr 2,%0\;asl2 %0\";
1252   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff8)
1253     return \"lsr 3,%0\;add %0,%0\;asl2 %0\";
1254   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff0)
1255     return \"lsr 4,%0\;asl2 %0\;asl2 %0\";
1256   return \"and %2,%0\";
1258   [(set_attr "cc" "none_0hit,set_znv")])
1260 ;; ----------------------------------------------------------------------
1261 ;; OR INSTRUCTIONS
1262 ;; ----------------------------------------------------------------------
1264 (define_expand "iorsi3"
1265   [(set (match_operand:SI 0 "register_operand" "")
1266         (ior:SI (match_operand:SI 1 "register_operand" "")
1267                 (match_operand:SI 2 "nonmemory_operand" "")))]
1268   ""
1269   "")
1271 (define_insn ""
1272   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1273         (ior:SI (match_operand:SI 1 "register_operand" "%0,dax")
1274                 (match_operand:SI 2 "nonmemory_operand" "dxi,dax")))]
1275   "TARGET_AM33"
1276   "*
1278   if (REG_P (operands[2]) && REG_P (operands[1])
1279       && true_regnum (operands[0]) != true_regnum (operands[1])
1280       && true_regnum (operands[0]) != true_regnum (operands[2])
1281       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1282       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1283       && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
1284     return \"mov %1,%0\;or %2,%0\";
1285   if (REG_P (operands[2]) && REG_P (operands[1])
1286       && true_regnum (operands[0]) != true_regnum (operands[1])
1287       && true_regnum (operands[0]) != true_regnum (operands[2]))
1288     return \"or %1,%2,%0\";
1289   if (REG_P (operands[2]) && REG_P (operands[0])
1290       && true_regnum (operands[2]) == true_regnum (operands[0]))
1291     return \"or %1,%0\";
1292   return \"or %2,%0\";
1294   [(set_attr "cc" "set_znv")])
1296 (define_insn ""
1297   [(set (match_operand:SI 0 "register_operand" "=dx")
1298         (ior:SI (match_operand:SI 1 "register_operand" "%0")
1299                 (match_operand:SI 2 "nonmemory_operand" "dxi")))]
1300   ""
1301   "or %2,%0"
1302   [(set_attr "cc" "set_znv")])
1304 ;; ----------------------------------------------------------------------
1305 ;; XOR INSTRUCTIONS
1306 ;; ----------------------------------------------------------------------
1308 (define_expand "xorsi3"
1309   [(set (match_operand:SI 0 "register_operand" "")
1310         (xor:SI (match_operand:SI 1 "register_operand" "")
1311                 (match_operand:SI 2 "nonmemory_operand" "")))]
1312   ""
1313   "")
1315 (define_insn ""
1316   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1317         (xor:SI (match_operand:SI 1 "register_operand" "%0,dax")
1318                 (match_operand:SI 2 "nonmemory_operand" "dxi,dax")))]
1319   "TARGET_AM33"
1320   "*
1322   if (REG_P (operands[2]) && REG_P (operands[1])
1323       && true_regnum (operands[0]) != true_regnum (operands[1])
1324       && true_regnum (operands[0]) != true_regnum (operands[2])
1325       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1326       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1327       && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
1328     return \"mov %1,%0\;xor %2,%0\";
1329   if (REG_P (operands[2]) && REG_P (operands[1])
1330       && true_regnum (operands[0]) != true_regnum (operands[1])
1331       && true_regnum (operands[0]) != true_regnum (operands[2]))
1332     return \"xor %1,%2,%0\";
1333   if (REG_P (operands[2]) && REG_P (operands[0])
1334       && true_regnum (operands[2]) == true_regnum (operands[0]))
1335     return \"xor %1,%0\";
1336   return \"xor %2,%0\";
1338   [(set_attr "cc" "set_znv")])
1340 (define_insn ""
1341   [(set (match_operand:SI 0 "register_operand" "=dx")
1342         (xor:SI (match_operand:SI 1 "register_operand" "%0")
1343                 (match_operand:SI 2 "nonmemory_operand" "dxi")))]
1344   ""
1345   "xor %2,%0"
1346   [(set_attr "cc" "set_znv")])
1348 ;; ----------------------------------------------------------------------
1349 ;; NOT INSTRUCTIONS
1350 ;; ----------------------------------------------------------------------
1352 (define_expand "one_cmplsi2"
1353   [(set (match_operand:SI 0 "register_operand" "")
1354         (not:SI (match_operand:SI 1 "register_operand" "")))]
1355   ""
1356   "")
1358 (define_insn ""
1359   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1360         (not:SI (match_operand:SI 1 "register_operand" "0,0")))]
1361   "TARGET_AM33"
1362   "not %0"
1363   [(set_attr "cc" "set_znv")])
1365 (define_insn ""
1366   [(set (match_operand:SI 0 "register_operand" "=dx")
1367         (not:SI (match_operand:SI 1 "register_operand" "0")))]
1368   ""
1369   "not %0"
1370   [(set_attr "cc" "set_znv")])
1372 ;; -----------------------------------------------------------------
1373 ;; BIT FIELDS
1374 ;; -----------------------------------------------------------------
1377 ;; These set/clear memory in byte sized chunks.
1379 ;; They are no smaller/faster than loading the value into a register
1380 ;; and storing the register, but they don't need a scratch register
1381 ;; which may allow for better code generation.
1382 (define_insn ""
1383   [(set (match_operand:QI 0 "nonimmediate_operand" "=R,d") (const_int 0))]
1384   ""
1385   "@
1386   bclr 255,%A0
1387   clr %0"
1388   [(set_attr "cc" "clobber")])
1390 (define_insn ""
1391   [(set (match_operand:QI 0 "nonimmediate_operand" "=R,d") (const_int -1))]
1392   ""
1393   "@
1394   bset 255,%A0
1395   mov -1,%0"
1396   [(set_attr "cc" "clobber,none_0hit")])
1398 (define_insn ""
1399   [(set (match_operand:QI 0 "nonimmediate_operand" "+R,d")
1400         (subreg:QI
1401           (and:SI (subreg:SI (match_dup 0) 0)
1402                   (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
1403   ""
1404   "@
1405   bclr %N1,%A0
1406   and %1,%0"
1407   [(set_attr "cc" "clobber,set_znv")])
1409 (define_insn ""
1410   [(set (match_operand:QI 0 "memory_operand" "=R,T")
1411         (and:QI
1412          (match_dup 0)
1413          (not:QI (match_operand:QI 1 "nonmemory_operand" "i,d"))))]
1414   ""
1415   "@
1416   bclr %U1,%A0
1417   bclr %1,%0"
1418   [(set_attr "cc" "clobber,clobber")])
1420 (define_insn ""
1421   [(set (match_operand:QI 0 "nonimmediate_operand" "+R,d")
1422         (subreg:QI
1423           (ior:SI (subreg:SI (match_dup 0) 0)
1424                   (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
1425   ""
1426   "@
1427   bset %U1,%A0
1428   or %1,%0"
1429   [(set_attr "cc" "clobber,set_znv")])
1431 (define_expand "iorqi3"
1432   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1433         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
1434                 (match_operand:QI 2 "nonmemory_operand" "")))]
1435   ""
1436   "")
1438 (define_insn ""
1439   [(set (match_operand:QI 0 "nonimmediate_operand" "=R,T,r")
1440         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
1441                 ;; This constraint should really be nonmemory_operand,
1442                 ;; but making it general_operand, along with the
1443                 ;; condition that not both input operands are MEMs, it
1444                 ;; here helps combine do a better job.
1445                 (match_operand:QI 2 "general_operand" "i,d,ir")))]
1446   "TARGET_AM33 &&
1447    (GET_CODE (operands[2]) != MEM || GET_CODE (operands[1]) != MEM)"
1448   "@
1449   bset %U2,%A0
1450   bset %2,%0
1451   or %2,%0"
1452   [(set_attr "cc" "clobber,clobber,set_znv")])
1454 (define_insn ""
1455   [(set (match_operand:QI 0 "nonimmediate_operand" "=R,T,d")
1456         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
1457                 ;; This constraint should really be nonmemory_operand,
1458                 ;; but making it general_operand, along with the
1459                 ;; condition that not both input operands are MEMs, it
1460                 ;; here helps combine do a better job.
1461                 (match_operand:QI 2 "general_operand" "i,d,id")))]
1462   "GET_CODE (operands[2]) != MEM || GET_CODE (operands[1]) != MEM"
1463   "@
1464   bset %U2,%A0
1465   bset %2,%0
1466   or %2,%0"
1467   [(set_attr "cc" "clobber,clobber,set_znv")])
1469 (define_insn ""
1470   [(set (cc0)
1471      (zero_extract:SI (match_operand:SI 0 "register_operand" "dx")
1472                       (match_operand 1 "const_int_operand" "")
1473                       (match_operand 2 "const_int_operand" "")))]
1474   ""
1475   "*
1477   int len = INTVAL (operands[1]);
1478   int bit = INTVAL (operands[2]);
1479   int mask = 0;
1480   rtx xoperands[2];
1482   while (len > 0)
1483     {
1484       mask |= (1 << bit);
1485       bit++;
1486       len--;
1487     }
1489   xoperands[0] = operands[0];
1490   xoperands[1] = GEN_INT (trunc_int_for_mode (mask, SImode));
1491   output_asm_insn (\"btst %1,%0\", xoperands);
1492   return \"\";
1494   [(set_attr "cc" "clobber")])
1496 (define_insn ""
1497   [(set (cc0)
1498      (zero_extract:SI (match_operand:QI 0 "general_operand" "R,dx")
1499                       (match_operand 1 "const_int_operand" "")
1500                       (match_operand 2 "const_int_operand" "")))]
1501   "mask_ok_for_mem_btst (INTVAL (operands[1]), INTVAL (operands[2]))"
1502   "*
1504   int len = INTVAL (operands[1]);
1505   int bit = INTVAL (operands[2]);
1506   int mask = 0;
1507   rtx xoperands[2];
1509   while (len > 0)
1510     {
1511       mask |= (1 << bit);
1512       bit++;
1513       len--;
1514     }
1516   /* If the source operand is not a reg (ie it is memory), then extract the
1517      bits from mask that we actually want to test.  Note that the mask will
1518      never cross a byte boundary.  */
1519   if (!REG_P (operands[0]))
1520     {
1521       if (mask & 0xff)
1522         mask = mask & 0xff;
1523       else if (mask & 0xff00)
1524         mask = (mask >> 8) & 0xff;
1525       else if (mask & 0xff0000)
1526         mask = (mask >> 16) & 0xff;
1527       else if (mask & 0xff000000)
1528         mask = (mask >> 24) & 0xff;
1529     }
1530   
1531   xoperands[0] = operands[0];
1532   xoperands[1] = GEN_INT (trunc_int_for_mode (mask, SImode));
1533   if (GET_CODE (operands[0]) == REG)
1534     output_asm_insn (\"btst %1,%0\", xoperands);
1535   else
1536     output_asm_insn (\"btst %U1,%A0\", xoperands);
1537   return \"\";
1539   [(set_attr "cc" "clobber")])
1541 (define_insn ""
1542   [(set (cc0) (and:SI (match_operand:SI 0 "register_operand" "dx")
1543                       (match_operand:SI 1 "const_int_operand" "")))]
1544   ""
1545   "btst %1,%0"
1546   [(set_attr "cc" "clobber")])
1548 (define_insn ""
1549   [(set (cc0)
1550      (and:SI
1551        (subreg:SI (match_operand:QI 0 "general_operand" "R,dx") 0)
1552        (match_operand:SI 1 "const_8bit_operand" "")))]
1553   ""
1554   "@
1555   btst %U1,%A0
1556   btst %1,%0"
1557   [(set_attr "cc" "clobber")])
1560 ;; ----------------------------------------------------------------------
1561 ;; JUMP INSTRUCTIONS
1562 ;; ----------------------------------------------------------------------
1564 ;; Conditional jump instructions
1566 (define_expand "ble"
1567   [(set (pc)
1568         (if_then_else (le (cc0)
1569                           (const_int 0))
1570                       (label_ref (match_operand 0 "" ""))
1571                       (pc)))]
1572   ""
1573   "")
1575 (define_expand "bleu"
1576   [(set (pc)
1577         (if_then_else (leu (cc0)
1578                            (const_int 0))
1579                       (label_ref (match_operand 0 "" ""))
1580                       (pc)))]
1581   ""
1582   "")
1584 (define_expand "bge"
1585   [(set (pc)
1586         (if_then_else (ge (cc0)
1587                           (const_int 0))
1588                       (label_ref (match_operand 0 "" ""))
1589                       (pc)))]
1590   ""
1591   "")
1593 (define_expand "bgeu"
1594   [(set (pc)
1595         (if_then_else (geu (cc0)
1596                            (const_int 0))
1597                       (label_ref (match_operand 0 "" ""))
1598                       (pc)))]
1599   ""
1600   "")
1602 (define_expand "blt"
1603   [(set (pc)
1604         (if_then_else (lt (cc0)
1605                           (const_int 0))
1606                       (label_ref (match_operand 0 "" ""))
1607                       (pc)))]
1608   ""
1609   "")
1611 (define_expand "bltu"
1612   [(set (pc)
1613         (if_then_else (ltu (cc0)
1614                            (const_int 0))
1615                       (label_ref (match_operand 0 "" ""))
1616                       (pc)))]
1617   ""
1618   "")
1620 (define_expand "bgt"
1621   [(set (pc)
1622         (if_then_else (gt (cc0)
1623                           (const_int 0))
1624                       (label_ref (match_operand 0 "" ""))
1625                       (pc)))]
1626   ""
1627   "")
1629 (define_expand "bgtu"
1630   [(set (pc)
1631         (if_then_else (gtu (cc0)
1632                            (const_int 0))
1633                       (label_ref (match_operand 0 "" ""))
1634                       (pc)))]
1635   ""
1636   "")
1638 (define_expand "beq"
1639   [(set (pc)
1640         (if_then_else (eq (cc0)
1641                           (const_int 0))
1642                       (label_ref (match_operand 0 "" ""))
1643                       (pc)))]
1644   ""
1645   "")
1647 (define_expand "bne"
1648   [(set (pc)
1649         (if_then_else (ne (cc0)
1650                           (const_int 0))
1651                       (label_ref (match_operand 0 "" ""))
1652                       (pc)))]
1653   ""
1654   "")
1656 (define_insn ""
1657   [(set (pc)
1658         (if_then_else (match_operator 1 "comparison_operator"
1659                                       [(cc0) (const_int 0)])
1660                       (label_ref (match_operand 0 "" ""))
1661                       (pc)))]
1662   ""
1663   "*
1665   if (cc_status.mdep.fpCC)
1666     return \"fb%b1 %0\";
1667   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1668       && (GET_CODE (operands[1]) == GT
1669           || GET_CODE (operands[1]) == GE
1670           || GET_CODE (operands[1]) == LE
1671           || GET_CODE (operands[1]) == LT))
1672     return 0;
1673   return \"b%b1 %0\";
1675  [(set_attr "cc" "none")])
1677 (define_insn ""
1678   [(set (pc)
1679         (if_then_else (match_operator 1 "comparison_operator"
1680                                       [(cc0) (const_int 0)])
1681                       (pc)
1682                       (label_ref (match_operand 0 "" ""))))]
1683   ""
1684   "*
1686   if (cc_status.mdep.fpCC)
1687     return \"fb%B1 %0\";
1688   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1689       && (GET_CODE (operands[1]) == GT
1690           || GET_CODE (operands[1]) == GE
1691           || GET_CODE (operands[1]) == LE
1692           || GET_CODE (operands[1]) == LT))
1693     return 0;
1694   return \"b%B1 %0\";
1696  [(set_attr "cc" "none")])
1698 ;; Unconditional and other jump instructions.
1700 (define_insn "jump"
1701   [(set (pc)
1702         (label_ref (match_operand 0 "" "")))]
1703   ""
1704   "jmp %l0"
1705  [(set_attr "cc" "none")])
1707 (define_insn "indirect_jump"
1708   [(set (pc) (match_operand:SI 0 "register_operand" "a"))]
1709   ""
1710   "jmp (%0)"
1711   [(set_attr "cc" "none")])
1713 (define_expand "builtin_setjmp_receiver"
1714   [(match_operand 0 "" "")]
1715   "flag_pic"
1716   "
1718   if (flag_pic)
1719     emit_insn (gen_GOTaddr2picreg ());
1721   DONE;
1724 (define_expand "casesi"
1725   [(match_operand:SI 0 "register_operand" "")
1726    (match_operand:SI 1 "immediate_operand" "")
1727    (match_operand:SI 2 "immediate_operand" "")
1728    (match_operand 3 "" "") (match_operand 4 "" "")]
1729   ""
1730   "
1732   rtx table = gen_reg_rtx (SImode);
1733   rtx index = gen_reg_rtx (SImode);
1734   rtx addr = gen_reg_rtx (Pmode);
1736   emit_move_insn (table, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
1737   emit_move_insn (index, plus_constant (operands[0], - INTVAL (operands[1])));
1738   emit_insn (gen_cmpsi (index, operands[2]));
1739   emit_jump_insn (gen_bgtu (operands[4]));
1740   emit_move_insn (index, gen_rtx_ASHIFT (SImode, index, GEN_INT (2)));
1741   emit_move_insn (addr, gen_rtx_MEM (SImode,
1742                                      gen_rtx_PLUS (SImode, table, index)));
1743   if (flag_pic)
1744     emit_move_insn (addr, gen_rtx_PLUS (SImode, addr, table));
1746   emit_jump_insn (gen_tablejump (addr, operands[3]));
1747   DONE;
1750 (define_insn "tablejump"
1751   [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1752    (use (label_ref (match_operand 1 "" "")))]
1753   ""
1754   "jmp (%0)"
1755   [(set_attr "cc" "none")])
1757 ;; Call subroutine with no return value.
1759 (define_expand "call"
1760   [(call (match_operand:QI 0 "general_operand" "")
1761          (match_operand:SI 1 "general_operand" ""))]
1762   ""
1763   "
1765   if (flag_pic && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
1766     {
1767       if (MN10300_GLOBAL_P (XEXP (operands[0], 0)))
1768         {
1769           /* The PLT code won't run on AM30, but then, there's no
1770              shared library support for AM30 either, so we just assume
1771              the linker is going to adjust all @PLT relocs to the
1772              actual symbols.  */
1773           emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
1774           XEXP (operands[0], 0) = gen_sym2PLT (XEXP (operands[0], 0));
1775         }
1776       else
1777         XEXP (operands[0], 0) = gen_sym2PIC (XEXP (operands[0], 0));
1778     }
1779   if (! call_address_operand (XEXP (operands[0], 0), VOIDmode))
1780     XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
1781   emit_call_insn (gen_call_internal (XEXP (operands[0], 0), operands[1]));
1782   DONE;
1785 (define_insn "call_internal"
1786   [(call (mem:QI (match_operand:SI 0 "call_address_operand" "aS"))
1787          (match_operand:SI 1 "general_operand" "g"))]
1788   ""
1789   "*
1791   if (REG_P (operands[0]))
1792     return \"calls %C0\";
1793   else
1794     return \"call %C0,[],0\";
1796   [(set_attr "cc" "clobber")])
1798 ;; Call subroutine, returning value in operand 0
1799 ;; (which must be a hard register).
1801 (define_expand "call_value"
1802   [(set (match_operand 0 "" "")
1803         (call (match_operand:QI 1 "general_operand" "")
1804               (match_operand:SI 2 "general_operand" "")))]
1805   ""
1806   "
1808   if (flag_pic && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
1809     {
1810       if (MN10300_GLOBAL_P (XEXP (operands[1], 0)))
1811         {
1812           /* The PLT code won't run on AM30, but then, there's no
1813              shared library support for AM30 either, so we just assume
1814              the linker is going to adjust all @PLT relocs to the
1815              actual symbols.  */
1816           emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
1817           XEXP (operands[1], 0) = gen_sym2PLT (XEXP (operands[1], 0));
1818         }
1819       else
1820         XEXP (operands[1], 0) = gen_sym2PIC (XEXP (operands[1], 0));
1821     }
1822   if (! call_address_operand (XEXP (operands[1], 0), VOIDmode))
1823     XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
1824   emit_call_insn (gen_call_value_internal (operands[0],
1825                                            XEXP (operands[1], 0),
1826                                            operands[2]));
1827   DONE;
1830 (define_insn "call_value_internal"
1831   [(set (match_operand 0 "" "=dax")
1832         (call (mem:QI (match_operand:SI 1 "call_address_operand" "aS"))
1833               (match_operand:SI 2 "general_operand" "g")))]
1834   ""
1835   "*
1837   if (REG_P (operands[1]))
1838     return \"calls %C1\";
1839   else
1840     return \"call %C1,[],0\";
1842   [(set_attr "cc" "clobber")])
1844 (define_expand "untyped_call"
1845   [(parallel [(call (match_operand 0 "" "")
1846                     (const_int 0))
1847               (match_operand 1 "" "")
1848               (match_operand 2 "" "")])]
1849   ""
1850   "
1852   int i;
1854   emit_call_insn (gen_call (operands[0], const0_rtx));
1856   for (i = 0; i < XVECLEN (operands[2], 0); i++)
1857     {
1858       rtx set = XVECEXP (operands[2], 0, i);
1859       emit_move_insn (SET_DEST (set), SET_SRC (set));
1860     }
1861   DONE;
1864 (define_insn "nop"
1865   [(const_int 0)]
1866   ""
1867   "nop"
1868   [(set_attr "cc" "none")])
1870 ;; ----------------------------------------------------------------------
1871 ;; EXTEND INSTRUCTIONS
1872 ;; ----------------------------------------------------------------------
1874 (define_expand "zero_extendqisi2"
1875   [(set (match_operand:SI 0 "general_operand" "")
1876         (zero_extend:SI
1877          (match_operand:QI 1 "general_operand" "")))]
1878   ""
1879   "")
1881 (define_insn ""
1882   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx,!dax,!dax,!dax")
1883         (zero_extend:SI
1884          (match_operand:QI 1 "general_operand" "0,dax,m,0,dax,m")))]
1885   "TARGET_AM33"
1886   "@
1887   extbu %0
1888   mov %1,%0\;extbu %0
1889   movbu %1,%0
1890   extbu %0
1891   mov %1,%0\;extbu %0
1892   movbu %1,%0"
1893   [(set_attr "cc" "none_0hit")])
1895 (define_insn ""
1896   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx")
1897         (zero_extend:SI
1898          (match_operand:QI 1 "general_operand" "0,d,m")))]
1899   ""
1900   "@
1901   extbu %0
1902   mov %1,%0\;extbu %0
1903   movbu %1,%0"
1904   [(set_attr "cc" "none_0hit")])
1906 (define_expand "zero_extendhisi2"
1907   [(set (match_operand:SI 0 "general_operand" "")
1908         (zero_extend:SI
1909          (match_operand:HI 1 "general_operand" "")))]
1910   ""
1911   "")
1913 (define_insn ""
1914   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx,!dax,!dax,!dax")
1915         (zero_extend:SI
1916          (match_operand:HI 1 "general_operand" "0,dax,m,0,dax,m")))]
1917   "TARGET_AM33"
1918   "@
1919   exthu %0
1920   mov %1,%0\;exthu %0
1921   movhu %1,%0
1922   exthu %0
1923   mov %1,%0\;exthu %0
1924   movhu %1,%0"
1925   [(set_attr "cc" "none_0hit")])
1927 (define_insn ""
1928   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx")
1929         (zero_extend:SI
1930          (match_operand:HI 1 "general_operand" "0,dx,m")))]
1931   ""
1932   "@
1933   exthu %0
1934   mov %1,%0\;exthu %0
1935   movhu %1,%0"
1936   [(set_attr "cc" "none_0hit")])
1938 ;;- sign extension instructions
1940 (define_expand "extendqisi2"
1941   [(set (match_operand:SI 0 "general_operand" "")
1942         (sign_extend:SI
1943          (match_operand:QI 1 "general_operand" "")))]
1944   ""
1945   "")
1947 (define_insn ""
1948   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,!dax,!dax")
1949         (sign_extend:SI
1950          (match_operand:QI 1 "general_operand" "0,dx,0,dax")))]
1951   "TARGET_AM33"
1952   "@
1953   extb %0
1954   mov %1,%0\;extb %0
1955   extb %0
1956   mov %1,%0\;extb %0"
1957   [(set_attr "cc" "none_0hit")])
1959 (define_insn ""
1960   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx")
1961         (sign_extend:SI
1962          (match_operand:QI 1 "general_operand" "0,dx")))]
1963   ""
1964   "@
1965   extb %0
1966   mov %1,%0\;extb %0"
1967   [(set_attr "cc" "none_0hit")])
1969 (define_expand "extendhisi2"
1970   [(set (match_operand:SI 0 "general_operand" "")
1971         (sign_extend:SI
1972          (match_operand:HI 1 "general_operand" "")))]
1973   ""
1974   "")
1976 (define_insn ""
1977   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,!dax,!dax")
1978         (sign_extend:SI
1979          (match_operand:HI 1 "general_operand" "0,dax,0,dax")))]
1980   "TARGET_AM33"
1981   "@
1982   exth %0
1983   mov %1,%0\;exth %0
1984   exth %0
1985   mov %1,%0\;exth %0"
1986   [(set_attr "cc" "none_0hit")])
1988 (define_insn ""
1989   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx")
1990         (sign_extend:SI
1991          (match_operand:HI 1 "general_operand" "0,dx")))]
1992   ""
1993   "@
1994   exth %0
1995   mov %1,%0\;exth %0"
1996   [(set_attr "cc" "none_0hit")])
1998 ;; ----------------------------------------------------------------------
1999 ;; SHIFTS
2000 ;; ----------------------------------------------------------------------
2002 (define_expand "ashlsi3"
2003   [(set (match_operand:SI 0 "register_operand" "")
2004         (ashift:SI
2005          (match_operand:SI 1 "register_operand" "")
2006          (match_operand:QI 2 "nonmemory_operand" "")))]
2007   ""
2008   "")
2010 (define_insn ""
2011   [(set (match_operand:SI 0 "register_operand" "=dax,dx,!dax")
2012         (ashift:SI
2013          (match_operand:SI 1 "register_operand" "0,0,dax")
2014          (match_operand:QI 2 "nonmemory_operand" "J,dxi,dax")))]
2015   "TARGET_AM33"
2016   "*
2018   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 1)
2019     return \"add %0,%0\";
2021   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 2)
2022     return \"asl2 %0\";
2024   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 3
2025       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS)
2026     return \"asl2 %0\;add %0,%0\";
2028   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 4
2029       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS)
2030     return \"asl2 %0\;asl2 %0\";
2032   if (true_regnum (operands[1]) == true_regnum (operands[0]))
2033     return \"asl %S2,%0\";
2035   if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
2036       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
2037       && true_regnum (operands[0]) != true_regnum (operands[2]))
2038     return \"mov %1,%0\;asl %S2,%0\";
2039   return \"asl %2,%1,%0\";
2041   [(set_attr "cc" "set_zn")])
2043 (define_insn ""
2044   [(set (match_operand:SI 0 "register_operand" "=dax,dx,dx,dx,dx")
2045         (ashift:SI
2046          (match_operand:SI 1 "register_operand" "0,0,0,0,0")
2047          (match_operand:QI 2 "nonmemory_operand" "J,K,M,L,dxi")))]
2048   ""
2049   "@
2050   add %0,%0
2051   asl2 %0
2052   asl2 %0\;add %0,%0
2053   asl2 %0\;asl2 %0
2054   asl %S2,%0"
2055   [(set_attr "cc" "set_zn")])
2057 (define_expand "lshrsi3"
2058   [(set (match_operand:SI 0 "register_operand" "")
2059         (lshiftrt:SI
2060          (match_operand:SI 1 "register_operand" "")
2061          (match_operand:QI 2 "nonmemory_operand" "")))]
2062   ""
2063   "")
2065 (define_insn ""
2066   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
2067         (lshiftrt:SI
2068          (match_operand:SI 1 "register_operand" "0,dax")
2069          (match_operand:QI 2 "nonmemory_operand" "dxi,dax")))]
2070   "TARGET_AM33"
2071   "*
2073   if (true_regnum (operands[1]) == true_regnum (operands[0]))
2074     return \"lsr %S2,%0\";
2076   if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
2077       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
2078       && true_regnum (operands[0]) != true_regnum (operands[2]))
2079     return \"mov %1,%0\;lsr %S2,%0\";
2080   return \"lsr %2,%1,%0\";
2082   [(set_attr "cc" "set_zn")])
2084 (define_insn ""
2085   [(set (match_operand:SI 0 "register_operand" "=dx")
2086         (lshiftrt:SI
2087          (match_operand:SI 1 "register_operand" "0")
2088          (match_operand:QI 2 "nonmemory_operand" "dxi")))]
2089   ""
2090   "lsr %S2,%0"
2091   [(set_attr "cc" "set_zn")])
2093 (define_expand "ashrsi3"
2094   [(set (match_operand:SI 0 "register_operand" "")
2095         (ashiftrt:SI
2096          (match_operand:SI 1 "register_operand" "")
2097          (match_operand:QI 2 "nonmemory_operand" "")))]
2098   ""
2099   "")
2101 (define_insn ""
2102   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
2103         (ashiftrt:SI
2104          (match_operand:SI 1 "register_operand" "0,dax")
2105          (match_operand:QI 2 "nonmemory_operand" "dxi,dax")))]
2106   "TARGET_AM33"
2107   "*
2109   if (true_regnum (operands[1]) == true_regnum (operands[0]))
2110     return \"asr %S2,%0\";
2112   if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
2113       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
2114       && true_regnum (operands[0]) != true_regnum (operands[2]))
2115     return \"mov %1,%0\;asr %S2,%0\";
2116   return \"asr %2,%1,%0\";
2118   [(set_attr "cc" "set_zn")])
2120 (define_insn ""
2121   [(set (match_operand:SI 0 "register_operand" "=dx")
2122         (ashiftrt:SI
2123          (match_operand:SI 1 "register_operand" "0")
2124          (match_operand:QI 2 "nonmemory_operand" "dxi")))]
2125   ""
2126   "asr %S2,%0"
2127   [(set_attr "cc" "set_zn")])
2129 ;; ----------------------------------------------------------------------
2130 ;; FP INSTRUCTIONS
2131 ;; ----------------------------------------------------------------------
2133 ;; The mn103 series does not have floating point instructions, but since
2134 ;; FP values are held in integer regs, we can clear the high bit easily
2135 ;; which gives us an efficient inline floating point absolute value.
2137 ;; Similarly for negation of a FP value.
2140 (define_expand "absdf2"
2141   [(set (match_operand:DF 0 "register_operand" "")
2142         (abs:DF (match_operand:DF 1 "register_operand" "")))]
2143   ""
2144   "
2146   rtx target, result, insns;
2148   start_sequence ();
2149   target = operand_subword (operands[0], 1, 1, DFmode);
2150   result = expand_binop (SImode, and_optab,
2151                          operand_subword_force (operands[1], 1, DFmode),
2152                          GEN_INT (0x7fffffff), target, 0, OPTAB_WIDEN);
2154   if (result == 0)
2155     abort ();
2157   if (result != target)
2158     emit_move_insn (result, target);
2160   emit_move_insn (operand_subword (operands[0], 0, 1, DFmode),
2161                   operand_subword_force (operands[1], 0, DFmode));
2163   insns = get_insns ();
2164   end_sequence ();
2166   emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
2167   DONE;
2170 (define_expand "abssf2"
2171   [(set (match_operand:SF 0 "register_operand" "")
2172         (abs:SF (match_operand:SF 1 "register_operand" "")))]
2173   ""
2174   "
2176   rtx result;
2177   rtx target;
2179   if (TARGET_AM33_2)
2180     {
2181       emit_insn (gen_abssf2_am33_2 (operands[0], operands[1]));
2182       DONE;
2183     }
2185   target = operand_subword_force (operands[0], 0, SFmode);
2186   result = expand_binop (SImode, and_optab,
2187                          operand_subword_force (operands[1], 0, SFmode),
2188                          GEN_INT (0x7fffffff), target, 0, OPTAB_WIDEN);
2189   if (result == 0)
2190     abort ();
2192   if (result != target)
2193     emit_move_insn (result, target);
2195   /* Make a place for REG_EQUAL.  */
2196   emit_move_insn (operands[0], operands[0]);
2197   DONE;
2201 (define_insn "abssf2_am33_2"
2202   [(set (match_operand:SF 0 "register_operand" "=f,f")
2203         (abs:SF (match_operand:SF 1 "register_operand" "0,?f")))]
2204   "TARGET_AM33_2"
2205   "@
2206    fabs %0
2207    fabs %1, %0"
2208   [(set_attr "cc" "none_0hit")])
2210 (define_expand "negdf2"
2211   [(set (match_operand:DF 0 "register_operand" "")
2212         (neg:DF (match_operand:DF 1 "register_operand" "")))]
2213   ""
2214   "
2216   rtx target, result, insns;
2218   start_sequence ();
2219   target = operand_subword (operands[0], 1, 1, DFmode);
2220   result = expand_binop (SImode, xor_optab,
2221                          operand_subword_force (operands[1], 1, DFmode),
2222                          GEN_INT (trunc_int_for_mode (0x80000000, SImode)),
2223                          target, 0, OPTAB_WIDEN);
2225   if (result == 0)
2226     abort ();
2228   if (result != target)
2229     emit_move_insn (result, target);
2231   emit_move_insn (operand_subword (operands[0], 0, 1, DFmode),
2232                   operand_subword_force (operands[1], 0, DFmode));
2234   insns = get_insns ();
2235   end_sequence ();
2237   emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
2238   DONE;
2241 (define_expand "negsf2"
2242   [(set (match_operand:SF 0 "register_operand" "")
2243         (neg:SF (match_operand:SF 1 "register_operand" "")))]
2244   ""
2245   "
2247   rtx result;
2248   rtx target;
2250   if (TARGET_AM33_2)
2251     {
2252       emit_insn (gen_negsf2_am33_2 (operands[0], operands[1]));
2253       DONE;
2254     }
2256   target = operand_subword_force (operands[0], 0, SFmode);
2257   result = expand_binop (SImode, xor_optab,
2258                          operand_subword_force (operands[1], 0, SFmode),
2259                          GEN_INT (trunc_int_for_mode (0x80000000, SImode)),
2260                          target, 0, OPTAB_WIDEN);
2261   if (result == 0)
2262     abort ();
2264   if (result != target)
2265     emit_move_insn (result, target);
2267   /* Make a place for REG_EQUAL.  */
2268   emit_move_insn (operands[0], operands[0]);
2269   DONE;
2272 (define_insn "negsf2_am33_2"
2273   [(set (match_operand:SF 0 "register_operand" "=f,f")
2274         (neg:SF (match_operand:SF 1 "register_operand" "0,?f")))]
2275   "TARGET_AM33_2"
2276   "@
2277    fneg %0
2278    fneg %1, %0"
2279   [(set_attr "cc" "none_0hit")])
2281 (define_expand "sqrtsf2"
2282   [(set (match_operand:SF 0 "register_operand" "")
2283         (sqrt:SF (match_operand:SF 1 "register_operand" "")))]
2284   "TARGET_AM33_2 && flag_unsafe_math_optimizations"
2285   "
2287   rtx scratch = gen_reg_rtx (SFmode);
2288   emit_insn (gen_rsqrtsf2 (scratch, operands[1], CONST1_RTX (SFmode)));
2289   emit_insn (gen_divsf3 (operands[0], force_reg (SFmode, CONST1_RTX (SFmode)),
2290                          scratch));
2291   DONE;
2294 (define_insn "rsqrtsf2"
2295   [(set (match_operand:SF 0 "register_operand" "=f,f")
2296         (div:SF (match_operand:SF 2 "const_1f_operand" "F,F")
2297                 (sqrt:SF (match_operand:SF 1 "register_operand" "0,?f"))))]
2298   "TARGET_AM33_2"
2299   "@
2300    frsqrt %0
2301    frsqrt %1, %0"
2302   [(set_attr "cc" "none_0hit")])
2304 (define_insn "addsf3"
2305   [(set (match_operand:SF 0 "register_operand" "=f,f")
2306         (plus:SF (match_operand:SF 1 "register_operand" "%0,f")
2307                  (match_operand:SF 2 "general_operand" "f,?fF")))]
2308   "TARGET_AM33_2"
2309   "@
2310    fadd %2, %0
2311    fadd %2, %1, %0"
2312   [(set_attr "cc" "none_0hit")])
2314 (define_insn "subsf3"
2315   [(set (match_operand:SF 0 "register_operand" "=f,f")
2316         (minus:SF (match_operand:SF 1 "register_operand" "0,f")
2317                   (match_operand:SF 2 "general_operand" "f,?fF")))]
2318   "TARGET_AM33_2"
2319   "@
2320    fsub %2, %0
2321    fsub %2, %1, %0"
2322   [(set_attr "cc" "none_0hit")])
2324 (define_insn "mulsf3"
2325   [(set (match_operand:SF 0 "register_operand" "=f,f")
2326         (mult:SF (match_operand:SF 1 "register_operand" "%0,f")
2327                  (match_operand:SF 2 "general_operand" "f,?fF")))]
2328   "TARGET_AM33_2"
2329   "@
2330    fmul %2, %0
2331    fmul %2, %1, %0"
2332   [(set_attr "cc" "none_0hit")])
2334 (define_insn "divsf3"
2335   [(set (match_operand:SF 0 "register_operand" "=f,f")
2336         (div:SF (match_operand:SF 1 "register_operand" "0,f")
2337                 (match_operand:SF 2 "general_operand" "f,?fF")))]
2338   "TARGET_AM33_2"
2339   "@
2340    fdiv %2, %0
2341    fdiv %2, %1, %0"
2342   [(set_attr "cc" "none_0hit")])
2344 (define_insn "fmaddsf4"
2345   [(set (match_operand:SF 0 "register_operand" "=A")
2346         (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
2347                           (match_operand:SF 2 "register_operand" "f"))
2348                  (match_operand:SF 3 "register_operand" "f")))]
2349   "TARGET_AM33_2"
2350   "fmadd %1, %2, %3, %0"
2351   [(set_attr "cc" "none_0hit")])
2353 (define_insn "fmsubsf4"
2354   [(set (match_operand:SF 0 "register_operand" "=A")
2355         (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
2356                            (match_operand:SF 2 "register_operand" "f"))
2357                   (match_operand:SF 3 "register_operand" "f")))]
2358   "TARGET_AM33_2"
2359   "fmsub %1, %2, %3, %0"
2360   [(set_attr "cc" "none_0hit")])
2362 (define_insn "fnmaddsf4"
2363   [(set (match_operand:SF 0 "register_operand" "=A")
2364         (minus:SF (match_operand:SF 3 "register_operand" "f")
2365                   (mult:SF (match_operand:SF 1 "register_operand" "%f")
2366                            (match_operand:SF 2 "register_operand" "f"))))]
2367   "TARGET_AM33_2"
2368   "fnmadd %1, %2, %3, %0"
2369   [(set_attr "cc" "none_0hit")])
2371 (define_insn "fnmsubsf4"
2372   [(set (match_operand:SF 0 "register_operand" "=A")
2373         (minus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
2374                                    (match_operand:SF 2 "register_operand" "f")))
2375                   (match_operand:SF 3 "register_operand" "f")))]
2376   "TARGET_AM33_2"
2377   "fnmsub %1, %2, %3, %0"
2378   [(set_attr "cc" "none_0hit")])
2381 ;; ----------------------------------------------------------------------
2382 ;; PROLOGUE/EPILOGUE
2383 ;; ----------------------------------------------------------------------
2384 (define_expand "prologue"
2385   [(const_int 0)]
2386   ""
2387   "expand_prologue (); DONE;")
2389 (define_expand "epilogue"
2390   [(return)]
2391   ""
2392   "
2394   expand_epilogue ();
2395   DONE;
2398 (define_insn "return_internal"
2399   [(const_int 2)
2400    (return)]
2401   ""
2402   "rets"
2403   [(set_attr "cc" "clobber")])
2405 ;; This insn restores the callee saved registers and does a return, it
2406 ;; can also deallocate stack space.
2407 (define_insn "return_internal_regs"
2408   [(const_int 0)
2409    (match_operand:SI 0  "const_int_operand" "i")
2410    (return)]
2411   ""
2412   "*
2414   fputs (\"\\tret \", asm_out_file);
2415   mn10300_print_reg_list (asm_out_file, mn10300_get_live_callee_saved_regs ());
2416   fprintf (asm_out_file, \",%d\\n\", (int) INTVAL (operands[0]));
2417   return \"\";
2419   [(set_attr "cc" "clobber")])
2421 ;; This instruction matches one generated by mn10300_gen_multiple_store()
2422 (define_insn "store_movm"
2423   [(match_parallel 0 "store_multiple_operation"
2424     [(set (reg:SI 9) (plus:SI (reg:SI 9) (match_operand 1 "" "")))])]
2425   ""
2426   "*
2428   fputs (\"\\tmovm \", asm_out_file);
2429   mn10300_print_reg_list (asm_out_file,
2430                           store_multiple_operation (operands[0], VOIDmode));
2431   fprintf (asm_out_file, \",(sp)\\n\");
2432   return \"\";
2434   [(set_attr "cc" "clobber")])
2435   
2436 (define_insn "return"
2437   [(return)]
2438   "can_use_return_insn ()"
2439   "*
2441   rtx next = next_active_insn (insn);
2443   if (next
2444       && GET_CODE (next) == JUMP_INSN
2445       && GET_CODE (PATTERN (next)) == RETURN)
2446     return \"\";
2447   else
2448     return \"rets\";
2450   [(set_attr "cc" "clobber")])
2452 ;; Try to combine consecutive updates of the stack pointer (or any
2453 ;; other register for that matter).
2454 (define_peephole
2455   [(set (match_operand:SI 0 "register_operand" "=dxay")
2456         (plus:SI (match_dup 0)
2457                  (match_operand 1 "const_int_operand" "")))
2458    (set (match_dup 0)
2459         (plus:SI (match_dup 0)
2460                  (match_operand 2 "const_int_operand" "")))]
2461   ""
2462   "*
2464   operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]));
2465   return \"add %1,%0\";
2467   [(set_attr "cc" "clobber")])
2470 ;; We had patterns to check eq/ne, but the they don't work because
2471 ;; 0x80000000 + 0x80000000 = 0x0 with a carry out.
2473 ;; The Z flag and C flag would be set, and we have no way to
2474 ;; check for the Z flag set and C flag clear.
2476 ;; This will work on the mn10200 because we can check the ZX flag
2477 ;; if the comparison is in HImode.
2478 (define_peephole
2479   [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2480    (set (pc) (if_then_else (ge (cc0) (const_int 0))
2481                            (match_operand 1 "" "")
2482                            (pc)))]
2483   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2484   "add %0,%0\;bcc %1"
2485   [(set_attr "cc" "clobber")])
2487 (define_peephole
2488   [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2489    (set (pc) (if_then_else (lt (cc0) (const_int 0))
2490                            (match_operand 1 "" "")
2491                            (pc)))]
2492   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2493   "add %0,%0\;bcs %1"
2494   [(set_attr "cc" "clobber")])
2496 (define_peephole
2497   [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2498    (set (pc) (if_then_else (ge (cc0) (const_int 0))
2499                            (pc)
2500                            (match_operand 1 "" "")))]
2501   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2502   "add %0,%0\;bcs %1"
2503   [(set_attr "cc" "clobber")])
2505 (define_peephole
2506   [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2507    (set (pc) (if_then_else (lt (cc0) (const_int 0))
2508                            (pc)
2509                            (match_operand 1 "" "")))]
2510   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2511   "add %0,%0\;bcc %1"
2512   [(set_attr "cc" "clobber")])
2514 (define_expand "int_label"
2515   [(unspec [(match_operand:SI 0 "" "")] UNSPEC_INT_LABEL)]
2516   "" "")
2518 (define_expand "GOTaddr2picreg"
2519   [(match_dup 0)]
2520   "" "
2522   /* It would be nice to be able to have int_label keep track of the
2523      counter and all, but if we add C code to it, we'll get an insn
2524      back, and we just want the pattern.  */
2525   operands[0] = gen_int_label (GEN_INT (mn10300_unspec_int_label_counter++));
2526   if (TARGET_AM33)
2527     emit_insn (gen_am33_loadPC (operands[0]));
2528   else
2529     emit_insn (gen_mn10300_loadPC (operands[0]));
2530   emit_insn (gen_add_GOT_to_pic_reg (operands[0]));
2531   DONE;
2535 (define_insn "am33_loadPC"
2536   [(parallel
2537     [(set (reg:SI PIC_REG) (pc))
2538      (use (match_operand 0 "" ""))])]
2539   "TARGET_AM33"
2540   "%0:\;mov pc,a2")
2543 (define_insn_and_split "mn10300_loadPC"
2544   [(parallel
2545     [(set (reg:SI PIC_REG) (pc))
2546      (use (match_operand 0 "" ""))])]
2547   ""
2548   "#"
2549   "reload_completed"
2550   [(match_operand 0 "" "")]
2551   "
2553   rtx sp_reg = gen_rtx_REG (SImode, SP_REG);
2554   int need_stack_space = (get_frame_size () == 0
2555                           && current_function_outgoing_args_size == 0);
2557   if (need_stack_space)
2558     emit_move_insn (sp_reg, plus_constant (sp_reg, -4));
2560   emit_insn (gen_call_next_insn (operands[0]));
2562   if (need_stack_space)
2563     emit_insn (gen_pop_pic_reg ());
2564   else
2565     emit_move_insn (pic_offset_table_rtx, gen_rtx_MEM (SImode, sp_reg));
2567   DONE;
2570 (define_insn "call_next_insn"
2571   [(parallel
2572     [(set (mem:SI (reg:SI SP_REG)) (pc))
2573      (use (match_operand 0 "" ""))])]
2574   "reload_completed"
2575   "calls %0\;%0:")
2577 (define_expand "add_GOT_to_pic_reg"
2578   [(set (reg:SI PIC_REG)
2579         (plus:SI
2580          (reg:SI PIC_REG)
2581          (const
2582           (unspec [(minus:SI
2583                     (match_dup 1)
2584                     (const (minus:SI
2585                             (const (match_operand:SI 0 "" ""))
2586                             (pc))))
2587                   ] UNSPEC_PIC))))]
2588   ""
2589   "
2591   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
2594 (define_expand "symGOT2reg"
2595   [(match_operand:SI 0 "" "")
2596    (match_operand:SI 1 "" "")]
2597   ""
2598   "
2600   rtx insn = emit_insn (gen_symGOT2reg_i (operands[0], operands[1]));
2602   RTX_UNCHANGING_P (SET_SRC (PATTERN (insn))) = 1;
2604   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
2605                                         REG_NOTES (insn));
2607   DONE;
2610 (define_expand "symGOT2reg_i"
2611   [(set (match_operand:SI 0 "" "")
2612         (mem:SI (plus:SI (reg:SI PIC_REG)
2613                          (const (unspec [(match_operand:SI 1 "" "")]
2614                                         UNSPEC_GOT)))))]
2615   ""
2616   "")
2618 (define_expand "symGOTOFF2reg"
2619   [(match_operand:SI 0 "" "") (match_operand:SI 1 "" "")]
2620   ""
2621   "
2623   rtx insn = emit_insn (gen_symGOTOFF2reg_i (operands[0], operands[1]));
2625   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
2626                                         REG_NOTES (insn));
2628   DONE;
2631 (define_expand "symGOTOFF2reg_i"
2632   [(set (match_operand:SI 0 "" "")
2633         (const (unspec [(match_operand:SI 1 "" "")] UNSPEC_GOTOFF)))
2634   (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI PIC_REG)))]
2635   ""
2636   "")
2638 (define_expand "sym2PIC"
2639   [(unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC)]
2640   "" "")
2642 (define_expand "sym2PLT"
2643   [(unspec [(match_operand:SI 0 "" "")] UNSPEC_PLT)]
2644   "" "")