* config/alpha/alpha.md, arm/arm.c, darwin.c, frv/frv.md,
[official-gcc.git] / gcc / config / mn10300 / mn10300.md
blob5c5bc8de5dc213203a3dc1d7efa16a939368e2ad
1 ;; GCC machine description for Matsushita MN10300
2 ;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
3 ;; Free Software Foundation, Inc.
4 ;; Contributed by Jeff Law (law@cygnus.com).
6 ;; This file is part of GCC.
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 2, or (at your option)
11 ;; any later version.
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING.  If not, write to
20 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
21 ;; Boston, MA 02110-1301, 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 ;; clobber - value of cc is unknown
37 (define_attr "cc" "none,none_0hit,set_znv,set_zn,compare,clobber"
38   (const_string "clobber"))
40 (define_constants [
41   (PIC_REG      6)
42   (SP_REG       9)
44   (UNSPEC_INT_LABEL     0)
45   (UNSPEC_PIC           1)
46   (UNSPEC_GOT           2)
47   (UNSPEC_GOTOFF        3)
48   (UNSPEC_PLT           4)
51 (include "predicates.md")
53 ;; ----------------------------------------------------------------------
54 ;; MOVE INSTRUCTIONS
55 ;; ----------------------------------------------------------------------
57 ;; movqi
59 (define_expand "movqi"
60   [(set (match_operand:QI 0 "general_operand" "")
61         (match_operand:QI 1 "general_operand" ""))]
62   ""
63   "
65   /* One of the ops has to be in a register */
66   if (!register_operand (operand0, QImode)
67       && !register_operand (operand1, QImode))
68     operands[1] = copy_to_mode_reg (QImode, operand1);
69 }")
71 (define_insn ""
72   [(set (match_operand:QI 0 "nonimmediate_operand" "=d*x*a*f,d*x,d*x*a,d*x*a,m,*f,d*x*a")
73         (match_operand:QI 1 "general_operand" "0,I,d*xai,m,d*xa,d*xa*f,*f"))]
74   "TARGET_AM33
75    && (register_operand (operands[0], QImode)
76        || register_operand (operands[1], QImode))"
77   "*
79   switch (which_alternative)
80     {
81     case 0:
82       return \"nop\";
83     case 1:
84       return \"clr %0\";
85     case 2:
86       if (GET_CODE (operands[1]) == CONST_DOUBLE)
87         {
88           rtx xoperands[2];
89           xoperands[0] = operands[0];
90           xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
91           output_asm_insn (\"mov %1,%0\", xoperands);
92           return \"\";
93         }
95       if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
96           && GET_CODE (operands[1]) == CONST_INT)
97         {
98           HOST_WIDE_INT val = INTVAL (operands[1]);
100           if (((val & 0x80) && ! (val & 0xffffff00))
101               || ((val & 0x800000) && ! (val & 0xff000000)))
102             return \"movu %1,%0\";
103         }
104       return \"mov %1,%0\";
105     case 3:
106     case 4:
107       return \"movbu %1,%0\";
108     case 5:
109     case 6:
110       return \"fmov %1,%0\";
111     default:
112       gcc_unreachable ();
113     }
115   [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
117 (define_insn ""
118   [(set (match_operand:QI 0 "nonimmediate_operand" "=d*a,d,d*a,d,m")
119         (match_operand:QI 1 "general_operand" "0,I,dai,m,d"))]
120   "register_operand (operands[0], QImode)
121    || register_operand (operands[1], QImode)"
122   "*
124   switch (which_alternative)
125     {
126     case 0:
127       return \"nop\";
128     case 1:
129       return \"clr %0\";
130     case 2:
131       if (GET_CODE (operands[1]) == CONST_DOUBLE)
132         {
133           rtx xoperands[2];
134           xoperands[0] = operands[0];
135           xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
136           output_asm_insn (\"mov %1,%0\", xoperands);
137           return \"\";
138         }
140       return \"mov %1,%0\";
141     case 3:
142     case 4:
143       return \"movbu %1,%0\";
144     default:
145       gcc_unreachable ();
146     }
148   [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit")])
150 ;; movhi
152 (define_expand "movhi"
153   [(set (match_operand:HI 0 "general_operand" "")
154         (match_operand:HI 1 "general_operand" ""))]
155   ""
156   "
158   /* One of the ops has to be in a register */
159   if (!register_operand (operand1, HImode)
160       && !register_operand (operand0, HImode))
161     operands[1] = copy_to_mode_reg (HImode, operand1);
164 (define_insn ""
165   [(set (match_operand:HI 0 "nonimmediate_operand" "=d*x*a*f,d*x,d*x*a,d*x*a,m,*f,d*x*a")
166         (match_operand:HI 1 "general_operand" "0,I,d*x*ai,m,d*x*a,d*x*a*f,*f"))]
167   "TARGET_AM33
168    && (register_operand (operands[0], HImode)
169        || register_operand (operands[1], HImode))"
170   "*
172   switch (which_alternative)
173     {
174     case 0:
175       return \"nop\";
176     case 1:
177       return \"clr %0\";
178     case 2:
179       if (GET_CODE (operands[1]) == CONST_DOUBLE)
180         {
181           rtx xoperands[2];
182           xoperands[0] = operands[0];
183           xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
184           output_asm_insn (\"mov %1,%0\", xoperands);
185           return \"\";
186         }
188       if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
189           && GET_CODE (operands[1]) == CONST_INT)
190         {
191           HOST_WIDE_INT val = INTVAL (operands[1]);
193           if (((val & 0x80) && ! (val & 0xffffff00))
194               || ((val & 0x800000) && ! (val & 0xff000000)))
195             return \"movu %1,%0\";
196         }
197       return \"mov %1,%0\";
198     case 3:
199     case 4:
200       return \"movhu %1,%0\";
201     case 5:
202     case 6:
203       return \"fmov %1,%0\";
204     default:
205       gcc_unreachable ();
206     }
208   [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
210 (define_insn ""
211   [(set (match_operand:HI 0 "nonimmediate_operand" "=d*a,d,d*a,d,m")
212         (match_operand:HI 1 "general_operand" "0,I,dai,m,d"))]
213   "register_operand (operands[0], HImode)
214    || register_operand (operands[1], HImode)"
215   "*
217   switch (which_alternative)
218     {
219     case 0:
220       return \"nop\";
221     case 1:
222       return \"clr %0\";
223     case 2:
224       if (GET_CODE (operands[1]) == CONST_DOUBLE)
225         {
226           rtx xoperands[2];
227           xoperands[0] = operands[0];
228           xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
229           output_asm_insn (\"mov %1,%0\", xoperands);
230           return \"\";
231         }
232       return \"mov %1,%0\";
233     case 3:
234     case 4:
235       return \"movhu %1,%0\";
236     default:
237       gcc_unreachable ();
238     }
240   [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit")])
242 ;; movsi and helpers
244 ;; We use this to handle addition of two values when one operand is the
245 ;; stack pointer and the other is a memory reference of some kind.  Reload
246 ;; does not handle them correctly without this expander.
247 (define_expand "reload_insi"
248   [(set (match_operand:SI 0 "register_operand" "=a")
249         (match_operand:SI 1 "impossible_plus_operand" ""))
250    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
251   ""
252   "
254   if (XEXP (operands[1], 0) == stack_pointer_rtx)
255     {
256       if (GET_CODE (XEXP (operands[1], 1)) == SUBREG
257           && (GET_MODE_SIZE (GET_MODE (XEXP (operands[1], 1)))
258               > GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (operands[1], 1))))))
259         emit_move_insn (operands[2],
260                         gen_rtx_ZERO_EXTEND
261                         (GET_MODE (XEXP (operands[1], 1)),
262                          SUBREG_REG (XEXP (operands[1], 1))));
263       else
264         emit_move_insn (operands[2], XEXP (operands[1], 1));
265       emit_move_insn (operands[0], XEXP (operands[1], 0));
266     }
267   else
268     {
269       if (GET_CODE (XEXP (operands[1], 0)) == SUBREG
270           && (GET_MODE_SIZE (GET_MODE (XEXP (operands[1], 0)))
271               > GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (operands[1], 0))))))
272         emit_move_insn (operands[2],
273                         gen_rtx_ZERO_EXTEND
274                         (GET_MODE (XEXP (operands[1], 0)),
275                          SUBREG_REG (XEXP (operands[1], 0))));
276       else
277         emit_move_insn (operands[2], XEXP (operands[1], 0));
278       emit_move_insn (operands[0], XEXP (operands[1], 1));
279     }
280   emit_insn (gen_addsi3 (operands[0], operands[0], operands[2]));
281   DONE;
284 (define_insn "pop_pic_reg"
285   [(set (reg:SI PIC_REG)
286         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
287   "reload_completed"
288   "movm (sp),[a2]")
290 (define_expand "movsi"
291   [(set (match_operand:SI 0 "general_operand" "")
292         (match_operand:SI 1 "general_operand" ""))]
293   ""
294   "
296   /* One of the ops has to be in a register */
297   if (!register_operand (operand1, SImode)
298       && !register_operand (operand0, SImode))
299     operands[1] = copy_to_mode_reg (SImode, operand1);
300   if (flag_pic)
301     {
302       rtx temp;
303       if (SYMBOLIC_CONST_P (operands[1]))
304         {
305           if (GET_CODE (operands[0]) == MEM)
306             operands[1] = force_reg (Pmode, operands[1]);
307           else
308             {
309               temp = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
310               operands[1] = legitimize_pic_address (operands[1], temp);
311             }
312         }
313       else if (GET_CODE (operands[1]) == CONST
314                && GET_CODE (XEXP (operands[1], 0)) == PLUS
315                && SYMBOLIC_CONST_P (XEXP (XEXP (operands[1], 0), 0)))
316         {
317           temp = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
318           temp = legitimize_pic_address (XEXP (XEXP (operands[1], 0), 0),
319                                          temp);
320           operands[1] = expand_binop (SImode, add_optab, temp,
321                                       XEXP (XEXP (operands[1], 0), 1),
322                                       no_new_pseudos ? temp
323                                       : gen_reg_rtx (Pmode),
324                                       0, OPTAB_LIB_WIDEN);
325         }
326     }
329 (define_insn ""
330   [(set (match_operand:SI 0 "nonimmediate_operand"
331                                 "=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax,axR,!*y,*f,*f,dxaQ")
332         (match_operand:SI 1 "general_operand"
333                                 "0,0,I,I,dx,ax,dx,ax,dixm,aixm,dixm,aixm,!*y,axR,0,dxaQi*f,*f"))]
334   "register_operand (operands[0], SImode)
335    || register_operand (operands[1], SImode)"
336   "*
338   switch (which_alternative)
339     {
340     case 0:
341     case 1:
342       return \"nop\";
343     case 2:
344       return \"clr %0\";
345     case 3:
346     case 4:
347     case 5:
348     case 6:
349     case 7:
350     case 8:
351     case 9:
352     case 10:
353     case 11:
354     case 12:
355     case 13:
356       if (GET_CODE (operands[1]) == CONST_DOUBLE)
357         {
358           rtx xoperands[2];
359           xoperands[0] = operands[0];
360           xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
361           output_asm_insn (\"mov %1,%0\", xoperands);
362           return \"\";
363         }
365       if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
366           && GET_CODE (operands[1]) == CONST_INT)
367         {
368           HOST_WIDE_INT val = INTVAL (operands[1]);
370           if (((val & 0x80) && ! (val & 0xffffff00))
371               || ((val & 0x800000) && ! (val & 0xff000000)))
372             return \"movu %1,%0\";
373         }
374       return \"mov %1,%0\";
375     case 14:
376       return \"nop\";
377     case 15:
378     case 16:
379       return \"fmov %1,%0\";
380     default:
381       gcc_unreachable ();
382     }
384   [(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")])
386 (define_expand "movsf"
387   [(set (match_operand:SF 0 "general_operand" "")
388         (match_operand:SF 1 "general_operand" ""))]
389   ""
390   "
392   /* One of the ops has to be in a register */
393   if (!register_operand (operand1, SFmode)
394       && !register_operand (operand0, SFmode))
395     operands[1] = copy_to_mode_reg (SFmode, operand1);
398 (define_insn ""
399   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,dx,ax,dx,a,f,dxaQ,daxm,dax")
400         (match_operand:SF 1 "general_operand" "0,0,0,G,G,fdxaQF,f,dax,daxFm"))]
401   "register_operand (operands[0], SFmode)
402    || register_operand (operands[1], SFmode)"
403   "*
405   switch (which_alternative)
406     {
407     case 0:
408     case 1:
409     case 2:
410       return \"nop\";
411     case 3:
412       return \"clr %0\";
413     /* case 4: below */
414     case 5:
415     case 6:
416       return \"fmov %1, %0\";
417     case 4:
418     case 7:
419     case 8:
420       if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
421           && GET_CODE (operands[1]) == CONST_INT)
422         {
423           HOST_WIDE_INT val = INTVAL (operands[1]);
425           if (((val & 0x80) && ! (val & 0xffffff00))
426               || ((val & 0x800000) && ! (val & 0xff000000)))
427             return \"movu %1,%0\";
428         }
429       return \"mov %1,%0\";
430     default:
431       gcc_unreachable ();
432     }
434   [(set_attr "cc" "none,none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
436 (define_expand "movdi"
437   [(set (match_operand:DI 0 "general_operand" "")
438         (match_operand:DI 1 "general_operand" ""))]
439   ""
440   "
442   /* One of the ops has to be in a register */
443   if (!register_operand (operand1, DImode)
444       && !register_operand (operand0, DImode))
445     operands[1] = copy_to_mode_reg (DImode, operand1);
448 (define_insn ""
449   [(set (match_operand:DI 0 "nonimmediate_operand"
450                                 "=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax,*f,*f,*f,dxa,*f,Q")
451         (match_operand:DI 1 "general_operand"
452                                 "0,0,I,I,dx,ax,dx,ax,dxim,axim,dxim,axim,0,*f,dxai,*f,Q,*f"))]
453   "register_operand (operands[0], DImode)
454    || register_operand (operands[1], DImode)"
455   "*
457   long val[2];
458   REAL_VALUE_TYPE rv;
460   switch (which_alternative)
461     {
462       case 0:
463       case 1:
464         return \"nop\";
466       case 2:
467         return \"clr %L0\;clr %H0\";
469       case 3:
470         if (rtx_equal_p (operands[0], operands[1]))
471           return \"sub %L1,%L0\;mov %L0,%H0\";
472         else
473           return \"mov %1,%L0\;mov %L0,%H0\";
474       case 4:
475       case 5:
476       case 6:
477       case 7:
478       case 8:
479       case 9:
480       case 10:
481       case 11:
482         if (GET_CODE (operands[1]) == CONST_INT)
483           {
484             rtx low, high;
485             split_double (operands[1], &low, &high);
486             val[0] = INTVAL (low);
487             val[1] = INTVAL (high);
488           }
489         if (GET_CODE (operands[1]) == CONST_DOUBLE)
490           {
491             if (GET_MODE (operands[1]) == DFmode)
492               {
493                 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
494                 REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
495               }
496             else if (GET_MODE (operands[1]) == VOIDmode
497                      || GET_MODE (operands[1]) == DImode)
498               {
499                 val[0] = CONST_DOUBLE_LOW (operands[1]);
500                 val[1] = CONST_DOUBLE_HIGH (operands[1]);
501               }
502           }
504         if (GET_CODE (operands[1]) == MEM
505             && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
506           {
507             rtx temp = operands[0];
509             while (GET_CODE (temp) == SUBREG)
510               temp = SUBREG_REG (temp);
512             gcc_assert (GET_CODE (temp) == REG);
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 %L1,%L0\", 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 %H1,%H0\", 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       gcc_unreachable ();
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             gcc_assert (GET_CODE (temp) == REG);
725             if (reg_overlap_mentioned_p (gen_rtx_REG (SImode, REGNO (temp)),
726                                          XEXP (operands[1], 0)))
727               return \"mov %H1,%H0\;mov %L1,%L0\";
728             else
729               return \"mov %L1,%L0\;mov %H1,%H0\";
730               
731           }
732         else if (GET_CODE (operands[1]) == MEM
733                  && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
734                  && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
735           {
736             rtx xoperands[2];
738             xoperands[0] = operands[0];
739             xoperands[1] = XEXP (operands[1], 0);
741             output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\",
742                              xoperands);
743             return \"\";
744           }
745         else
746           {
747             if ((GET_CODE (operands[1]) == CONST_INT
748                  || GET_CODE (operands[1]) == CONST_DOUBLE)
749                 && val[0] == 0)
750               {
751                 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
752                   output_asm_insn (\"clr %L0\", operands);
753                 else
754                   output_asm_insn (\"mov %L1,%L0\", operands);
755               }
756             else if ((GET_CODE (operands[1]) == CONST_INT
757                       || GET_CODE (operands[1]) == CONST_DOUBLE)
758                      && (REGNO_REG_CLASS (true_regnum (operands[0]))
759                          == EXTENDED_REGS)
760                      && (((val[0] & 0x80) && ! (val[0] & 0xffffff00))
761                          || ((val[0] & 0x800000) && ! (val[0] & 0xff000000))))
762               output_asm_insn (\"movu %L1,%L0\", operands);
763             else
764               output_asm_insn (\"mov %L1,%L0\", operands);
766             if ((GET_CODE (operands[1]) == CONST_INT
767                  || GET_CODE (operands[1]) == CONST_DOUBLE)
768                 && val[1] == 0)
769               {
770                 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
771                   output_asm_insn (\"clr %H0\", operands);
772                 else
773                   output_asm_insn (\"mov %H1,%H0\", operands);
774               }
775             else if ((GET_CODE (operands[1]) == CONST_INT
776                       || GET_CODE (operands[1]) == CONST_DOUBLE)
777                      && val[0] == val[1])
778               output_asm_insn (\"mov %L0,%H0\", operands);
779             else if ((GET_CODE (operands[1]) == CONST_INT
780                       || GET_CODE (operands[1]) == CONST_DOUBLE)
781                      && (REGNO_REG_CLASS (true_regnum (operands[0]))
782                          == EXTENDED_REGS)
783                      && (((val[1] & 0x80) && ! (val[1] & 0xffffff00))
784                          || ((val[1] & 0x800000) && ! (val[1] & 0xff000000))))
785               output_asm_insn (\"movu %H1,%H0\", operands);
786             else
787               output_asm_insn (\"mov %H1,%H0\", operands);
788             return \"\";
789           }
790     default:
791       gcc_unreachable ();
792     }
794   [(set (attr "cc")
795         (cond
796          [
797          (lt (symbol_ref "which_alternative") (const_int 3)
798              ) (const_string "none")
799          (eq (symbol_ref "which_alternative") (const_int 3)
800              ) (const_string "clobber")
801          (eq (symbol_ref "which_alternative") (const_int 9)
802              ) (if_then_else
803                 (ne (symbol_ref "rtx_equal_p (operands[0], operands[1])")
804                     (const_int 0)) (const_string "clobber")
805                     (const_string "none_0hit"))
806          (ior (eq (symbol_ref "which_alternative") (const_int 14))
807               (eq (symbol_ref "which_alternative") (const_int 15))
808               ) (if_then_else
809                  (ne (symbol_ref "mn10300_wide_const_load_uses_clr
810                                   (operands)")
811                      (const_int 0)) (const_string "clobber")
812                      (const_string "none_0hit"))
813          ] (const_string "none_0hit")))])
817 ;; ----------------------------------------------------------------------
818 ;; TEST INSTRUCTIONS
819 ;; ----------------------------------------------------------------------
821 ;; Go ahead and define tstsi so we can eliminate redundant tst insns
822 ;; when we start trying to optimize this port.
823 (define_insn "tstsi"
824   [(set (cc0) (match_operand:SI 0 "register_operand" "dax"))]
825   ""
826   "* return output_tst (operands[0], insn);"
827   [(set_attr "cc" "set_znv")])
829 (define_insn ""
830   [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "dx,!a")))]
831   "TARGET_AM33"
832   "* return output_tst (operands[0], insn);"
833   [(set_attr "cc" "set_znv")])
835 (define_insn ""
836   [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "dx")))]
837   ""
838   "* return output_tst (operands[0], insn);"
839   [(set_attr "cc" "set_znv")])
841 (define_insn ""
842   [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "dx,!a")))]
843   "TARGET_AM33"
844   "* return output_tst (operands[0], insn);"
845   [(set_attr "cc" "set_znv")])
847 (define_insn ""
848   [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "dx")))]
849   ""
850   "* return output_tst (operands[0], insn);"
851   [(set_attr "cc" "set_znv")])
853 ;; Ordinarily, the cmp instruction will set the Z bit of cc0 to 1 if
854 ;; its operands hold equal values, but the operands of a cmp
855 ;; instruction must be distinct registers.  In the case where we'd
856 ;; like to compare a register to itself, we can achieve this effect
857 ;; with a btst 0,d0 instead.  (This will not alter the contents of d0
858 ;; but will have the proper effect on cc0.  Using d0 is arbitrary; any
859 ;; data register would work.)
861 ;; Even though the first alternative would be preferable if it can
862 ;; possibly match, reload must not be given the opportunity to attempt
863 ;; to use it.  It assumes that such matches can only occur when one of
864 ;; the operands is used for input and the other for output.  Since
865 ;; this is not the case, it abort()s.  Indeed, such a reload cannot be
866 ;; possibly satisfied, so just mark the alternative with a `!', so
867 ;; that it is not considered by reload.
869 (define_insn "cmpsi"
870   [(set (cc0)
871         (compare (match_operand:SI 0 "register_operand" "!*d*a*x,dax")
872                  (match_operand:SI 1 "nonmemory_operand" "*0,daxi")))]
873   ""
874   "@
875   btst 0,d0
876   cmp %1,%0"
877   [(set_attr "cc" "compare,compare")])
879 (define_insn "cmpsf"
880   [(set (cc0)
881         (compare (match_operand:SF 0 "register_operand" "f,f")
882                  (match_operand:SF 1 "nonmemory_operand" "f,F")))]
883   "TARGET_AM33_2"
884   "fcmp %1,%0"
885   [(set_attr "cc" "compare,compare")])
887 ;; ----------------------------------------------------------------------
888 ;; ADD INSTRUCTIONS
889 ;; ----------------------------------------------------------------------
891 (define_expand "addsi3"
892   [(set (match_operand:SI 0 "register_operand" "")
893         (plus:SI (match_operand:SI 1 "register_operand" "")
894                  (match_operand:SI 2 "nonmemory_operand" "")))]
895   ""
896   "")
898 (define_insn ""
899   [(set (match_operand:SI 0 "register_operand" "=dx,a,x,a,dax,!*y,!dax")
900         (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,dax")
901                  (match_operand:SI 2 "nonmemory_operand" "J,J,L,L,daxi,i,dax")))]
902   "TARGET_AM33"
903   "*
905   switch (which_alternative)
906     {
907     case 0:
908     case 1:
909       return \"inc %0\";
910     case 2:
911     case 3:
912       return \"inc4 %0\";
913     case 4:
914     case 5:
915       return \"add %2,%0\";
916     case 6:
917       {
918         enum reg_class src1_class, src2_class, dst_class;
920         src1_class = REGNO_REG_CLASS (true_regnum (operands[1]));
921         src2_class = REGNO_REG_CLASS (true_regnum (operands[2]));
922         dst_class = REGNO_REG_CLASS (true_regnum (operands[0]));
923         
924         /* I'm not sure if this can happen or not.  Might as well be prepared
925           and generate the best possible code if it does happen.  */
926         if (true_regnum (operands[0]) == true_regnum (operands[1]))
927           return \"add %2,%0\";
928         if (true_regnum (operands[0]) == true_regnum (operands[2]))
929           return \"add %1,%0\";
931         /* Catch cases where no extended register was used.  These should be
932            handled just like the mn10300.  */
933         if (src1_class != EXTENDED_REGS
934             && src2_class != EXTENDED_REGS
935             && dst_class != EXTENDED_REGS)
936           {
937             /* We have to copy one of the sources into the destination, then
938                add the other source to the destination.
940                Carefully select which source to copy to the destination; a naive
941                implementation will waste a byte when the source classes are 
942                different and the destination is an address register.  Selecting
943                the lowest cost register copy will optimize this sequence.  */
944             if (REGNO_REG_CLASS (true_regnum (operands[1]))
945                 == REGNO_REG_CLASS (true_regnum (operands[0])))
946               return \"mov %1,%0\;add %2,%0\";
947             return \"mov %2,%0\;add %1,%0\";
948           }
950         /* At least one register is an extended register.  */
952         /* The three operand add instruction on the am33 is a win iff the
953            output register is an extended register, or if both source
954            registers are extended registers.  */
955         if (dst_class == EXTENDED_REGS
956             || src1_class == src2_class)
957           return \"add %2,%1,%0\";
959       /* It is better to copy one of the sources to the destination, then
960          perform a 2 address add.  The destination in this case must be
961          an address or data register and one of the sources must be an
962          extended register and the remaining source must not be an extended
963          register.
965          The best code for this case is to copy the extended reg to the
966          destination, then emit a two address add.  */
967       if (src1_class == EXTENDED_REGS)
968         return \"mov %1,%0\;add %2,%0\";
969       return \"mov %2,%0\;add %1,%0\";
970       }
971     default:
972       gcc_unreachable ();
973     }
975   [(set_attr "cc" "set_zn,none_0hit,set_zn,none_0hit,set_zn,none_0hit,set_zn")])
977 (define_insn ""
978   [(set (match_operand:SI 0 "register_operand" "=dx,a,a,dax,!*y,!dax")
979         (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,dax")
980                  (match_operand:SI 2 "nonmemory_operand" "J,J,L,daxi,i,dax")))]
981   ""
982   "*
984   switch (which_alternative)
985     {
986     case 0:
987     case 1:
988       return \"inc %0\";
989     case 2:
990       return \"inc4 %0\";
991     case 3:
992     case 4:
993       return \"add %2,%0\";
994     case 5:
995       /* I'm not sure if this can happen or not.  Might as well be prepared
996          and generate the best possible code if it does happen.  */
997       if (true_regnum (operands[0]) == true_regnum (operands[1]))
998         return \"add %2,%0\";
999       if (true_regnum (operands[0]) == true_regnum (operands[2]))
1000         return \"add %1,%0\";
1002       /* We have to copy one of the sources into the destination, then add
1003          the other source to the destination.
1005          Carefully select which source to copy to the destination; a naive
1006          implementation will waste a byte when the source classes are different
1007          and the destination is an address register.  Selecting the lowest
1008          cost register copy will optimize this sequence.  */
1009       if (REGNO_REG_CLASS (true_regnum (operands[1]))
1010           == REGNO_REG_CLASS (true_regnum (operands[0])))
1011         return \"mov %1,%0\;add %2,%0\";
1012       return \"mov %2,%0\;add %1,%0\";
1013     default:
1014       gcc_unreachable ();
1015     }
1017   [(set_attr "cc" "set_zn,none_0hit,none_0hit,set_zn,none_0hit,set_zn")])
1019 ;; ----------------------------------------------------------------------
1020 ;; SUBTRACT INSTRUCTIONS
1021 ;; ----------------------------------------------------------------------
1023 (define_expand "subsi3"
1024   [(set (match_operand:SI 0 "register_operand" "")
1025         (minus:SI (match_operand:SI 1 "register_operand" "")
1026                   (match_operand:SI 2 "nonmemory_operand" "")))]
1027   ""
1028   "")
1030 (define_insn ""
1031   [(set (match_operand:SI 0 "register_operand" "=dax,!dax")
1032         (minus:SI (match_operand:SI 1 "register_operand" "0,dax")
1033                   (match_operand:SI 2 "nonmemory_operand" "daxi,dax")))]
1034   "TARGET_AM33"
1035   "*
1037   if (true_regnum (operands[0]) == true_regnum (operands[1]))
1038     return \"sub %2,%0\";
1039   else
1040     {
1041       enum reg_class src1_class, src2_class, dst_class;
1043       src1_class = REGNO_REG_CLASS (true_regnum (operands[1]));
1044       src2_class = REGNO_REG_CLASS (true_regnum (operands[2]));
1045       dst_class = REGNO_REG_CLASS (true_regnum (operands[0]));
1047       /* If no extended registers are used, then the best way to handle
1048          this is to copy the first source operand into the destination
1049          and emit a two address subtraction.  */
1050       if (src1_class != EXTENDED_REGS
1051           && src2_class != EXTENDED_REGS
1052           && dst_class != EXTENDED_REGS
1053           && true_regnum (operands[0]) != true_regnum (operands[2]))
1054         return \"mov %1,%0\;sub %2,%0\";
1055       return \"sub %2,%1,%0\";
1056     }
1058   [(set_attr "cc" "set_zn")])
1060 (define_insn ""
1061   [(set (match_operand:SI 0 "register_operand" "=dax")
1062         (minus:SI (match_operand:SI 1 "register_operand" "0")
1063                   (match_operand:SI 2 "nonmemory_operand" "daxi")))]
1064   ""
1065   "sub %2,%0"
1066   [(set_attr "cc" "set_zn")])
1068 (define_expand "negsi2"
1069   [(set (match_operand:SI 0 "register_operand" "")
1070         (neg:SI (match_operand:SI 1 "register_operand" "")))]
1071   ""
1072   "
1074   rtx target = gen_reg_rtx (SImode);
1076   emit_move_insn (target, const0_rtx);
1077   emit_insn (gen_subsi3 (target, target, operands[1]));
1078   emit_move_insn (operands[0], target);
1079   DONE;
1082 ;; ----------------------------------------------------------------------
1083 ;; MULTIPLY INSTRUCTIONS
1084 ;; ----------------------------------------------------------------------
1086 (define_insn "mulsidi3"
1087   [(set (match_operand:DI 0 "register_operand" "=dax")
1088         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "dax"))
1089                  (sign_extend:DI (match_operand:SI 2 "register_operand" "dax"))))]
1090   "TARGET_AM33"
1091   "mul %1,%2,%H0,%L0"
1092   [(set_attr "cc" "set_zn")])
1094 (define_insn "umulsidi3"
1095   [(set (match_operand:DI 0 "register_operand" "=dax")
1096         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "dax"))
1097                  (zero_extend:DI (match_operand:SI 2 "register_operand" "dax"))))]
1098   "TARGET_AM33"
1099   "mulu %1,%2,%H0,%L0"
1100   [(set_attr "cc" "set_zn")])
1102 (define_expand "mulsi3"
1103   [(set (match_operand:SI 0 "register_operand" "")
1104         (mult:SI (match_operand:SI 1 "register_operand" "")
1105                  (match_operand:SI 2 "register_operand" "")))]
1106   ""
1107   "")
1109 (define_insn ""
1110   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1111         (mult:SI (match_operand:SI 1 "register_operand" "%0,0")
1112                  (match_operand:SI 2 "nonmemory_operand" "dx,daxi")))]
1113   "TARGET_AM33"
1114   "*
1116   if (TARGET_MULT_BUG)
1117     return \"nop\;nop\;mul %2,%0\";
1118   else
1119     return \"mul %2,%0\";
1121   [(set_attr "cc" "set_zn")])
1122   
1123 (define_insn ""
1124   [(set (match_operand:SI 0 "register_operand" "=dx")
1125         (mult:SI (match_operand:SI 1 "register_operand" "%0")
1126                  (match_operand:SI 2 "register_operand" "dx")))]
1127   ""
1128   "*
1130   if (TARGET_MULT_BUG)
1131     return \"nop\;nop\;mul %2,%0\";
1132   else
1133     return \"mul %2,%0\";
1135   [(set_attr "cc" "set_zn")])
1137 (define_insn "udivmodsi4"
1138   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx")
1139         (udiv:SI (match_operand:SI 1 "general_operand" "0")
1140                  (match_operand:SI 2 "general_operand" "dx")))
1141    (set (match_operand:SI 3 "nonimmediate_operand" "=&d")
1142         (umod:SI (match_dup 1) (match_dup 2)))]
1143   ""
1144   "*
1146   output_asm_insn (\"sub %3,%3\;mov %3,mdr\", operands);
1148   if (find_reg_note (insn, REG_UNUSED, operands[3]))
1149     return \"divu %2,%0\";
1150   else
1151     return \"divu %2,%0\;mov mdr,%3\";
1153   [(set_attr "cc" "set_zn")])
1155 (define_insn "divmodsi4"
1156   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx")
1157         (div:SI (match_operand:SI 1 "general_operand" "0")
1158                  (match_operand:SI 2 "general_operand" "dx")))
1159    (set (match_operand:SI 3 "nonimmediate_operand" "=d")
1160         (mod:SI (match_dup 1) (match_dup 2)))]
1161   ""
1162   "*
1164   if (find_reg_note (insn, REG_UNUSED, operands[3]))
1165     return \"ext %0\;div %2,%0\";
1166   else
1167     return \"ext %0\;div %2,%0\;mov mdr,%3\";
1169   [(set_attr "cc" "set_zn")])
1172 ;; ----------------------------------------------------------------------
1173 ;; AND INSTRUCTIONS
1174 ;; ----------------------------------------------------------------------
1176 (define_expand "andsi3"
1177   [(set (match_operand:SI 0 "register_operand" "")
1178         (and:SI (match_operand:SI 1 "register_operand" "")
1179                 (match_operand:SI 2 "nonmemory_operand" "")))]
1180   ""
1181   "")
1183 (define_insn ""
1184   [(set (match_operand:SI 0 "register_operand" "=dx,dx,!dax")
1185         (and:SI (match_operand:SI 1 "register_operand" "%0,0,dax")
1186                 (match_operand:SI 2 "nonmemory_operand" "N,dxi,dax")))]
1187   "TARGET_AM33"
1188   "*
1190   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff)
1191     return \"extbu %0\";
1192   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xffff)
1193     return \"exthu %0\";
1194   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x7fffffff)
1195     return \"add %0,%0\;lsr 1,%0\";
1196   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x3fffffff)
1197     return \"asl2 %0\;lsr 2,%0\";
1198   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x1fffffff)
1199     return \"add %0,%0\;asl2 %0\;lsr 3,%0\";
1200   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x0fffffff)
1201     return \"asl2 %0\;asl2 %0\;lsr 4,%0\";
1202   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffe)
1203     return \"lsr 1,%0\;add %0,%0\";
1204   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffc)
1205     return \"lsr 2,%0\;asl2 %0\";
1206   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff8)
1207     return \"lsr 3,%0\;add %0,%0\;asl2 %0\";
1208   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff0)
1209     return \"lsr 4,%0\;asl2 %0\;asl2 %0\";
1210   if (REG_P (operands[2]) && REG_P (operands[1])
1211       && true_regnum (operands[0]) != true_regnum (operands[1])
1212       && true_regnum (operands[0]) != true_regnum (operands[2])
1213       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1214       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1215       && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
1216     return \"mov %1,%0\;and %2,%0\";
1217   if (REG_P (operands[2]) && REG_P (operands[1])
1218       && true_regnum (operands[0]) != true_regnum (operands[1])
1219       && true_regnum (operands[0]) != true_regnum (operands[2]))
1220     return \"and %1,%2,%0\";
1221   if (REG_P (operands[2]) && REG_P (operands[0])
1222       && true_regnum (operands[2]) == true_regnum (operands[0]))
1223     return \"and %1,%0\";
1224   return \"and %2,%0\";
1226   [(set (attr "cc")
1227         (cond
1228          [
1229          (eq (symbol_ref "which_alternative") (const_int 0)
1230              ) (const_string "none_0hit")
1231          (ne (symbol_ref "GET_CODE (operands[2]) == CONST_INT
1232                           && (INTVAL (operands[2]) == 0x7fffffff
1233                               || INTVAL (operands[2]) == 0x3fffffff
1234                               || INTVAL (operands[2]) == 0x1fffffff
1235                               || INTVAL (operands[2]) == 0x0fffffff
1236                               || INTVAL (operands[2]) == 0xfffffffe
1237                               || INTVAL (operands[2]) == 0xfffffffc
1238                               || INTVAL (operands[2]) == 0xfffffff8
1239                               || INTVAL (operands[2]) == 0xfffffff0)")
1240              (const_int 0)) (const_string "set_zn")
1241           ] (const_string "set_znv")))])
1243 (define_insn ""
1244   [(set (match_operand:SI 0 "register_operand" "=dx,dx")
1245         (and:SI (match_operand:SI 1 "register_operand" "%0,0")
1246                 (match_operand:SI 2 "nonmemory_operand" "N,dxi")))]
1247   ""
1248   "*
1250   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff)
1251     return \"extbu %0\";
1252   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xffff)
1253     return \"exthu %0\";
1254   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x7fffffff)
1255     return \"add %0,%0\;lsr 1,%0\";
1256   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x3fffffff)
1257     return \"asl2 %0\;lsr 2,%0\";
1258   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x1fffffff)
1259     return \"add %0,%0\;asl2 %0\;lsr 3,%0\";
1260   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x0fffffff)
1261     return \"asl2 %0\;asl2 %0\;lsr 4,%0\";
1262   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffe)
1263     return \"lsr 1,%0\;add %0,%0\";
1264   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffc)
1265     return \"lsr 2,%0\;asl2 %0\";
1266   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff8)
1267     return \"lsr 3,%0\;add %0,%0\;asl2 %0\";
1268   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff0)
1269     return \"lsr 4,%0\;asl2 %0\;asl2 %0\";
1270   return \"and %2,%0\";
1272   [(set (attr "cc")
1273         (cond
1274          [
1275          (eq (symbol_ref "which_alternative") (const_int 0)
1276              ) (const_string "none_0hit")
1277          ;; Shifts don't set the V flag, but bitwise operations clear
1278          ;; it (which correctly reflects the absence of overflow in a
1279          ;; compare-with-zero that might follow).  As for the
1280          ;; 0xfffffffe case, the add may overflow, so we can't use the
1281          ;; V flag.
1282          (ne (symbol_ref "GET_CODE (operands[2]) == CONST_INT
1283                           && (INTVAL (operands[2]) == 0x7fffffff
1284                               || INTVAL (operands[2]) == 0x3fffffff
1285                               || INTVAL (operands[2]) == 0x1fffffff
1286                               || INTVAL (operands[2]) == 0x0fffffff
1287                               || INTVAL (operands[2]) == 0xfffffffe
1288                               || INTVAL (operands[2]) == 0xfffffffc
1289                               || INTVAL (operands[2]) == 0xfffffff8
1290                               || INTVAL (operands[2]) == 0xfffffff0)")
1291              (const_int 0)) (const_string "set_zn")
1292           ] (const_string "set_znv")))])
1294 ;; ----------------------------------------------------------------------
1295 ;; OR INSTRUCTIONS
1296 ;; ----------------------------------------------------------------------
1298 (define_expand "iorsi3"
1299   [(set (match_operand:SI 0 "register_operand" "")
1300         (ior:SI (match_operand:SI 1 "register_operand" "")
1301                 (match_operand:SI 2 "nonmemory_operand" "")))]
1302   ""
1303   "")
1305 (define_insn ""
1306   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1307         (ior:SI (match_operand:SI 1 "register_operand" "%0,dax")
1308                 (match_operand:SI 2 "nonmemory_operand" "dxi,dax")))]
1309   "TARGET_AM33"
1310   "*
1312   if (REG_P (operands[2]) && REG_P (operands[1])
1313       && true_regnum (operands[0]) != true_regnum (operands[1])
1314       && true_regnum (operands[0]) != true_regnum (operands[2])
1315       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1316       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1317       && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
1318     return \"mov %1,%0\;or %2,%0\";
1319   if (REG_P (operands[2]) && REG_P (operands[1])
1320       && true_regnum (operands[0]) != true_regnum (operands[1])
1321       && true_regnum (operands[0]) != true_regnum (operands[2]))
1322     return \"or %1,%2,%0\";
1323   if (REG_P (operands[2]) && REG_P (operands[0])
1324       && true_regnum (operands[2]) == true_regnum (operands[0]))
1325     return \"or %1,%0\";
1326   return \"or %2,%0\";
1328   [(set_attr "cc" "set_znv")])
1330 (define_insn ""
1331   [(set (match_operand:SI 0 "register_operand" "=dx")
1332         (ior:SI (match_operand:SI 1 "register_operand" "%0")
1333                 (match_operand:SI 2 "nonmemory_operand" "dxi")))]
1334   ""
1335   "or %2,%0"
1336   [(set_attr "cc" "set_znv")])
1338 ;; ----------------------------------------------------------------------
1339 ;; XOR INSTRUCTIONS
1340 ;; ----------------------------------------------------------------------
1342 (define_expand "xorsi3"
1343   [(set (match_operand:SI 0 "register_operand" "")
1344         (xor:SI (match_operand:SI 1 "register_operand" "")
1345                 (match_operand:SI 2 "nonmemory_operand" "")))]
1346   ""
1347   "")
1349 (define_insn ""
1350   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1351         (xor:SI (match_operand:SI 1 "register_operand" "%0,dax")
1352                 (match_operand:SI 2 "nonmemory_operand" "dxi,dax")))]
1353   "TARGET_AM33"
1354   "*
1356   if (REG_P (operands[2]) && REG_P (operands[1])
1357       && true_regnum (operands[0]) != true_regnum (operands[1])
1358       && true_regnum (operands[0]) != true_regnum (operands[2])
1359       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1360       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1361       && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
1362     return \"mov %1,%0\;xor %2,%0\";
1363   if (REG_P (operands[2]) && REG_P (operands[1])
1364       && true_regnum (operands[0]) != true_regnum (operands[1])
1365       && true_regnum (operands[0]) != true_regnum (operands[2]))
1366     return \"xor %1,%2,%0\";
1367   if (REG_P (operands[2]) && REG_P (operands[0])
1368       && true_regnum (operands[2]) == true_regnum (operands[0]))
1369     return \"xor %1,%0\";
1370   return \"xor %2,%0\";
1372   [(set_attr "cc" "set_znv")])
1374 (define_insn ""
1375   [(set (match_operand:SI 0 "register_operand" "=dx")
1376         (xor:SI (match_operand:SI 1 "register_operand" "%0")
1377                 (match_operand:SI 2 "nonmemory_operand" "dxi")))]
1378   ""
1379   "xor %2,%0"
1380   [(set_attr "cc" "set_znv")])
1382 ;; ----------------------------------------------------------------------
1383 ;; NOT INSTRUCTIONS
1384 ;; ----------------------------------------------------------------------
1386 (define_expand "one_cmplsi2"
1387   [(set (match_operand:SI 0 "register_operand" "")
1388         (not:SI (match_operand:SI 1 "register_operand" "")))]
1389   ""
1390   "")
1392 (define_insn ""
1393   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1394         (not:SI (match_operand:SI 1 "register_operand" "0,0")))]
1395   "TARGET_AM33"
1396   "not %0"
1397   [(set_attr "cc" "set_znv")])
1399 (define_insn ""
1400   [(set (match_operand:SI 0 "register_operand" "=dx")
1401         (not:SI (match_operand:SI 1 "register_operand" "0")))]
1402   ""
1403   "not %0"
1404   [(set_attr "cc" "set_znv")])
1406 ;; -----------------------------------------------------------------
1407 ;; BIT FIELDS
1408 ;; -----------------------------------------------------------------
1411 ;; These set/clear memory in byte sized chunks.
1413 ;; They are no smaller/faster than loading the value into a register
1414 ;; and storing the register, but they don't need a scratch register
1415 ;; which may allow for better code generation.
1416 (define_insn ""
1417   [(set (match_operand:QI 0 "nonimmediate_operand" "=R,d") (const_int 0))]
1418   ""
1419   "@
1420   bclr 255,%A0
1421   clr %0"
1422   [(set_attr "cc" "clobber")])
1424 (define_insn ""
1425   [(set (match_operand:QI 0 "nonimmediate_operand" "=R,d") (const_int -1))]
1426   ""
1427   "@
1428   bset 255,%A0
1429   mov -1,%0"
1430   [(set_attr "cc" "clobber,none_0hit")])
1432 (define_insn ""
1433   [(set (match_operand:QI 0 "nonimmediate_operand" "+R,d")
1434         (subreg:QI
1435           (and:SI (subreg:SI (match_dup 0) 0)
1436                   (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
1437   ""
1438   "@
1439   bclr %N1,%A0
1440   and %1,%0"
1441   [(set_attr "cc" "clobber,set_znv")])
1443 (define_insn ""
1444   [(set (match_operand:QI 0 "memory_operand" "=R,T")
1445         (and:QI
1446          (match_dup 0)
1447          (not:QI (match_operand:QI 1 "nonmemory_operand" "i,d"))))]
1448   ""
1449   "@
1450   bclr %U1,%A0
1451   bclr %1,%0"
1452   [(set_attr "cc" "clobber,clobber")])
1454 (define_insn ""
1455   [(set (match_operand:QI 0 "nonimmediate_operand" "+R,d")
1456         (subreg:QI
1457           (ior:SI (subreg:SI (match_dup 0) 0)
1458                   (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
1459   ""
1460   "@
1461   bset %U1,%A0
1462   or %1,%0"
1463   [(set_attr "cc" "clobber,set_znv")])
1465 (define_expand "iorqi3"
1466   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1467         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
1468                 (match_operand:QI 2 "nonmemory_operand" "")))]
1469   ""
1470   "")
1472 (define_insn ""
1473   [(set (match_operand:QI 0 "nonimmediate_operand" "=R,T,r")
1474         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
1475                 ;; This constraint should really be nonmemory_operand,
1476                 ;; but making it general_operand, along with the
1477                 ;; condition that not both input operands are MEMs, it
1478                 ;; here helps combine do a better job.
1479                 (match_operand:QI 2 "general_operand" "i,d,ir")))]
1480   "TARGET_AM33 &&
1481    (GET_CODE (operands[2]) != MEM || GET_CODE (operands[1]) != MEM)"
1482   "@
1483   bset %U2,%A0
1484   bset %2,%0
1485   or %2,%0"
1486   [(set_attr "cc" "clobber,clobber,set_znv")])
1488 (define_insn ""
1489   [(set (match_operand:QI 0 "nonimmediate_operand" "=R,T,d")
1490         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
1491                 ;; This constraint should really be nonmemory_operand,
1492                 ;; but making it general_operand, along with the
1493                 ;; condition that not both input operands are MEMs, it
1494                 ;; here helps combine do a better job.
1495                 (match_operand:QI 2 "general_operand" "i,d,id")))]
1496   "GET_CODE (operands[2]) != MEM || GET_CODE (operands[1]) != MEM"
1497   "@
1498   bset %U2,%A0
1499   bset %2,%0
1500   or %2,%0"
1501   [(set_attr "cc" "clobber,clobber,set_znv")])
1503 (define_insn ""
1504   [(set (cc0)
1505      (zero_extract:SI (match_operand:SI 0 "register_operand" "dx")
1506                       (match_operand 1 "const_int_operand" "")
1507                       (match_operand 2 "const_int_operand" "")))]
1508   ""
1509   "*
1511   int len = INTVAL (operands[1]);
1512   int bit = INTVAL (operands[2]);
1513   int mask = 0;
1514   rtx xoperands[2];
1516   while (len > 0)
1517     {
1518       mask |= (1 << bit);
1519       bit++;
1520       len--;
1521     }
1523   xoperands[0] = operands[0];
1524   xoperands[1] = GEN_INT (trunc_int_for_mode (mask, SImode));
1525   output_asm_insn (\"btst %1,%0\", xoperands);
1526   return \"\";
1528   [(set_attr "cc" "clobber")])
1530 (define_insn ""
1531   [(set (cc0)
1532      (zero_extract:SI (match_operand:QI 0 "general_operand" "R,dx")
1533                       (match_operand 1 "const_int_operand" "")
1534                       (match_operand 2 "const_int_operand" "")))]
1535   "mask_ok_for_mem_btst (INTVAL (operands[1]), INTVAL (operands[2]))"
1536   "*
1538   int len = INTVAL (operands[1]);
1539   int bit = INTVAL (operands[2]);
1540   int mask = 0;
1541   rtx xoperands[2];
1543   while (len > 0)
1544     {
1545       mask |= (1 << bit);
1546       bit++;
1547       len--;
1548     }
1550   /* If the source operand is not a reg (i.e. it is memory), then extract the
1551      bits from mask that we actually want to test.  Note that the mask will
1552      never cross a byte boundary.  */
1553   if (!REG_P (operands[0]))
1554     {
1555       if (mask & 0xff)
1556         mask = mask & 0xff;
1557       else if (mask & 0xff00)
1558         mask = (mask >> 8) & 0xff;
1559       else if (mask & 0xff0000)
1560         mask = (mask >> 16) & 0xff;
1561       else if (mask & 0xff000000)
1562         mask = (mask >> 24) & 0xff;
1563     }
1564   
1565   xoperands[0] = operands[0];
1566   xoperands[1] = GEN_INT (trunc_int_for_mode (mask, SImode));
1567   if (GET_CODE (operands[0]) == REG)
1568     output_asm_insn (\"btst %1,%0\", xoperands);
1569   else
1570     output_asm_insn (\"btst %U1,%A0\", xoperands);
1571   return \"\";
1573   [(set_attr "cc" "clobber")])
1575 (define_insn ""
1576   [(set (cc0) (and:SI (match_operand:SI 0 "register_operand" "dx")
1577                       (match_operand:SI 1 "const_int_operand" "")))]
1578   ""
1579   "btst %1,%0"
1580   [(set_attr "cc" "clobber")])
1582 (define_insn ""
1583   [(set (cc0)
1584      (and:SI
1585        (subreg:SI (match_operand:QI 0 "general_operand" "R,dx") 0)
1586        (match_operand:SI 1 "const_8bit_operand" "")))]
1587   ""
1588   "@
1589   btst %U1,%A0
1590   btst %1,%0"
1591   [(set_attr "cc" "clobber")])
1594 ;; ----------------------------------------------------------------------
1595 ;; JUMP INSTRUCTIONS
1596 ;; ----------------------------------------------------------------------
1598 ;; Conditional jump instructions
1600 (define_expand "ble"
1601   [(set (pc)
1602         (if_then_else (le (cc0)
1603                           (const_int 0))
1604                       (label_ref (match_operand 0 "" ""))
1605                       (pc)))]
1606   ""
1607   "")
1609 (define_expand "bleu"
1610   [(set (pc)
1611         (if_then_else (leu (cc0)
1612                            (const_int 0))
1613                       (label_ref (match_operand 0 "" ""))
1614                       (pc)))]
1615   ""
1616   "")
1618 (define_expand "bge"
1619   [(set (pc)
1620         (if_then_else (ge (cc0)
1621                           (const_int 0))
1622                       (label_ref (match_operand 0 "" ""))
1623                       (pc)))]
1624   ""
1625   "")
1627 (define_expand "bgeu"
1628   [(set (pc)
1629         (if_then_else (geu (cc0)
1630                            (const_int 0))
1631                       (label_ref (match_operand 0 "" ""))
1632                       (pc)))]
1633   ""
1634   "")
1636 (define_expand "blt"
1637   [(set (pc)
1638         (if_then_else (lt (cc0)
1639                           (const_int 0))
1640                       (label_ref (match_operand 0 "" ""))
1641                       (pc)))]
1642   ""
1643   "")
1645 (define_expand "bltu"
1646   [(set (pc)
1647         (if_then_else (ltu (cc0)
1648                            (const_int 0))
1649                       (label_ref (match_operand 0 "" ""))
1650                       (pc)))]
1651   ""
1652   "")
1654 (define_expand "bgt"
1655   [(set (pc)
1656         (if_then_else (gt (cc0)
1657                           (const_int 0))
1658                       (label_ref (match_operand 0 "" ""))
1659                       (pc)))]
1660   ""
1661   "")
1663 (define_expand "bgtu"
1664   [(set (pc)
1665         (if_then_else (gtu (cc0)
1666                            (const_int 0))
1667                       (label_ref (match_operand 0 "" ""))
1668                       (pc)))]
1669   ""
1670   "")
1672 (define_expand "beq"
1673   [(set (pc)
1674         (if_then_else (eq (cc0)
1675                           (const_int 0))
1676                       (label_ref (match_operand 0 "" ""))
1677                       (pc)))]
1678   ""
1679   "")
1681 (define_expand "bne"
1682   [(set (pc)
1683         (if_then_else (ne (cc0)
1684                           (const_int 0))
1685                       (label_ref (match_operand 0 "" ""))
1686                       (pc)))]
1687   ""
1688   "")
1690 (define_insn ""
1691   [(set (pc)
1692         (if_then_else (match_operator 1 "comparison_operator"
1693                                       [(cc0) (const_int 0)])
1694                       (label_ref (match_operand 0 "" ""))
1695                       (pc)))]
1696   ""
1697   "*
1699   if (cc_status.mdep.fpCC)
1700     return \"fb%b1 %0\";
1701   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1702       && (GET_CODE (operands[1]) == GT
1703           || GET_CODE (operands[1]) == GE
1704           || GET_CODE (operands[1]) == LE
1705           || GET_CODE (operands[1]) == LT))
1706     return 0;
1707   return \"b%b1 %0\";
1709  [(set_attr "cc" "none")])
1711 (define_insn ""
1712   [(set (pc)
1713         (if_then_else (match_operator 1 "comparison_operator"
1714                                       [(cc0) (const_int 0)])
1715                       (pc)
1716                       (label_ref (match_operand 0 "" ""))))]
1717   ""
1718   "*
1720   if (cc_status.mdep.fpCC)
1721     return \"fb%B1 %0\";
1722   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1723       && (GET_CODE (operands[1]) == GT
1724           || GET_CODE (operands[1]) == GE
1725           || GET_CODE (operands[1]) == LE
1726           || GET_CODE (operands[1]) == LT))
1727     return 0;
1728   return \"b%B1 %0\";
1730  [(set_attr "cc" "none")])
1732 ;; Unconditional and other jump instructions.
1734 (define_insn "jump"
1735   [(set (pc)
1736         (label_ref (match_operand 0 "" "")))]
1737   ""
1738   "jmp %l0"
1739  [(set_attr "cc" "none")])
1741 (define_insn "indirect_jump"
1742   [(set (pc) (match_operand:SI 0 "register_operand" "a"))]
1743   ""
1744   "jmp (%0)"
1745   [(set_attr "cc" "none")])
1747 (define_expand "builtin_setjmp_receiver"
1748   [(match_operand 0 "" "")]
1749   "flag_pic"
1750   "
1752   if (flag_pic)
1753     emit_insn (gen_GOTaddr2picreg ());
1755   DONE;
1758 (define_expand "casesi"
1759   [(match_operand:SI 0 "register_operand" "")
1760    (match_operand:SI 1 "immediate_operand" "")
1761    (match_operand:SI 2 "immediate_operand" "")
1762    (match_operand 3 "" "") (match_operand 4 "" "")]
1763   ""
1764   "
1766   rtx table = gen_reg_rtx (SImode);
1767   rtx index = gen_reg_rtx (SImode);
1768   rtx addr = gen_reg_rtx (Pmode);
1770   emit_move_insn (table, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
1771   emit_move_insn (index, plus_constant (operands[0], - INTVAL (operands[1])));
1772   emit_insn (gen_cmpsi (index, operands[2]));
1773   emit_jump_insn (gen_bgtu (operands[4]));
1774   emit_move_insn (index, gen_rtx_ASHIFT (SImode, index, const2_rtx));
1775   emit_move_insn (addr, gen_rtx_MEM (SImode,
1776                                      gen_rtx_PLUS (SImode, table, index)));
1777   if (flag_pic)
1778     emit_move_insn (addr, gen_rtx_PLUS (SImode, addr, table));
1780   emit_jump_insn (gen_tablejump (addr, operands[3]));
1781   DONE;
1784 (define_insn "tablejump"
1785   [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1786    (use (label_ref (match_operand 1 "" "")))]
1787   ""
1788   "jmp (%0)"
1789   [(set_attr "cc" "none")])
1791 ;; Call subroutine with no return value.
1793 (define_expand "call"
1794   [(call (match_operand:QI 0 "general_operand" "")
1795          (match_operand:SI 1 "general_operand" ""))]
1796   ""
1797   "
1799   if (flag_pic && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
1800     {
1801       if (MN10300_GLOBAL_P (XEXP (operands[0], 0)))
1802         {
1803           /* The PLT code won't run on AM30, but then, there's no
1804              shared library support for AM30 either, so we just assume
1805              the linker is going to adjust all @PLT relocs to the
1806              actual symbols.  */
1807           emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
1808           XEXP (operands[0], 0) = gen_sym2PLT (XEXP (operands[0], 0));
1809         }
1810       else
1811         XEXP (operands[0], 0) = gen_sym2PIC (XEXP (operands[0], 0));
1812     }
1813   if (! call_address_operand (XEXP (operands[0], 0), VOIDmode))
1814     XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
1815   emit_call_insn (gen_call_internal (XEXP (operands[0], 0), operands[1]));
1816   DONE;
1819 (define_insn "call_internal"
1820   [(call (mem:QI (match_operand:SI 0 "call_address_operand" "aS"))
1821          (match_operand:SI 1 "general_operand" "g"))]
1822   ""
1823   "*
1825   if (REG_P (operands[0]))
1826     return \"calls %C0\";
1827   else
1828     return \"call %C0,[],0\";
1830   [(set_attr "cc" "clobber")])
1832 ;; Call subroutine, returning value in operand 0
1833 ;; (which must be a hard register).
1835 (define_expand "call_value"
1836   [(set (match_operand 0 "" "")
1837         (call (match_operand:QI 1 "general_operand" "")
1838               (match_operand:SI 2 "general_operand" "")))]
1839   ""
1840   "
1842   if (flag_pic && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
1843     {
1844       if (MN10300_GLOBAL_P (XEXP (operands[1], 0)))
1845         {
1846           /* The PLT code won't run on AM30, but then, there's no
1847              shared library support for AM30 either, so we just assume
1848              the linker is going to adjust all @PLT relocs to the
1849              actual symbols.  */
1850           emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
1851           XEXP (operands[1], 0) = gen_sym2PLT (XEXP (operands[1], 0));
1852         }
1853       else
1854         XEXP (operands[1], 0) = gen_sym2PIC (XEXP (operands[1], 0));
1855     }
1856   if (! call_address_operand (XEXP (operands[1], 0), VOIDmode))
1857     XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
1858   emit_call_insn (gen_call_value_internal (operands[0],
1859                                            XEXP (operands[1], 0),
1860                                            operands[2]));
1861   DONE;
1864 (define_insn "call_value_internal"
1865   [(set (match_operand 0 "" "=dax")
1866         (call (mem:QI (match_operand:SI 1 "call_address_operand" "aS"))
1867               (match_operand:SI 2 "general_operand" "g")))]
1868   ""
1869   "*
1871   if (REG_P (operands[1]))
1872     return \"calls %C1\";
1873   else
1874     return \"call %C1,[],0\";
1876   [(set_attr "cc" "clobber")])
1878 (define_expand "untyped_call"
1879   [(parallel [(call (match_operand 0 "" "")
1880                     (const_int 0))
1881               (match_operand 1 "" "")
1882               (match_operand 2 "" "")])]
1883   ""
1884   "
1886   int i;
1888   emit_call_insn (gen_call (operands[0], const0_rtx));
1890   for (i = 0; i < XVECLEN (operands[2], 0); i++)
1891     {
1892       rtx set = XVECEXP (operands[2], 0, i);
1893       emit_move_insn (SET_DEST (set), SET_SRC (set));
1894     }
1895   DONE;
1898 (define_insn "nop"
1899   [(const_int 0)]
1900   ""
1901   "nop"
1902   [(set_attr "cc" "none")])
1904 ;; ----------------------------------------------------------------------
1905 ;; EXTEND INSTRUCTIONS
1906 ;; ----------------------------------------------------------------------
1908 (define_expand "zero_extendqisi2"
1909   [(set (match_operand:SI 0 "general_operand" "")
1910         (zero_extend:SI
1911          (match_operand:QI 1 "general_operand" "")))]
1912   ""
1913   "")
1915 (define_insn ""
1916   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx,!dax,!dax,!dax")
1917         (zero_extend:SI
1918          (match_operand:QI 1 "general_operand" "0,dax,m,0,dax,m")))]
1919   "TARGET_AM33"
1920   "@
1921   extbu %0
1922   mov %1,%0\;extbu %0
1923   movbu %1,%0
1924   extbu %0
1925   mov %1,%0\;extbu %0
1926   movbu %1,%0"
1927   [(set_attr "cc" "none_0hit")])
1929 (define_insn ""
1930   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx")
1931         (zero_extend:SI
1932          (match_operand:QI 1 "general_operand" "0,d,m")))]
1933   ""
1934   "@
1935   extbu %0
1936   mov %1,%0\;extbu %0
1937   movbu %1,%0"
1938   [(set_attr "cc" "none_0hit")])
1940 (define_expand "zero_extendhisi2"
1941   [(set (match_operand:SI 0 "general_operand" "")
1942         (zero_extend:SI
1943          (match_operand:HI 1 "general_operand" "")))]
1944   ""
1945   "")
1947 (define_insn ""
1948   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx,!dax,!dax,!dax")
1949         (zero_extend:SI
1950          (match_operand:HI 1 "general_operand" "0,dax,m,0,dax,m")))]
1951   "TARGET_AM33"
1952   "@
1953   exthu %0
1954   mov %1,%0\;exthu %0
1955   movhu %1,%0
1956   exthu %0
1957   mov %1,%0\;exthu %0
1958   movhu %1,%0"
1959   [(set_attr "cc" "none_0hit")])
1961 (define_insn ""
1962   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx")
1963         (zero_extend:SI
1964          (match_operand:HI 1 "general_operand" "0,dx,m")))]
1965   ""
1966   "@
1967   exthu %0
1968   mov %1,%0\;exthu %0
1969   movhu %1,%0"
1970   [(set_attr "cc" "none_0hit")])
1972 ;;- sign extension instructions
1974 (define_expand "extendqisi2"
1975   [(set (match_operand:SI 0 "general_operand" "")
1976         (sign_extend:SI
1977          (match_operand:QI 1 "general_operand" "")))]
1978   ""
1979   "")
1981 (define_insn ""
1982   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,!dax,!dax")
1983         (sign_extend:SI
1984          (match_operand:QI 1 "general_operand" "0,dx,0,dax")))]
1985   "TARGET_AM33"
1986   "@
1987   extb %0
1988   mov %1,%0\;extb %0
1989   extb %0
1990   mov %1,%0\;extb %0"
1991   [(set_attr "cc" "none_0hit")])
1993 (define_insn ""
1994   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx")
1995         (sign_extend:SI
1996          (match_operand:QI 1 "general_operand" "0,dx")))]
1997   ""
1998   "@
1999   extb %0
2000   mov %1,%0\;extb %0"
2001   [(set_attr "cc" "none_0hit")])
2003 (define_expand "extendhisi2"
2004   [(set (match_operand:SI 0 "general_operand" "")
2005         (sign_extend:SI
2006          (match_operand:HI 1 "general_operand" "")))]
2007   ""
2008   "")
2010 (define_insn ""
2011   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,!dax,!dax")
2012         (sign_extend:SI
2013          (match_operand:HI 1 "general_operand" "0,dax,0,dax")))]
2014   "TARGET_AM33"
2015   "@
2016   exth %0
2017   mov %1,%0\;exth %0
2018   exth %0
2019   mov %1,%0\;exth %0"
2020   [(set_attr "cc" "none_0hit")])
2022 (define_insn ""
2023   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx")
2024         (sign_extend:SI
2025          (match_operand:HI 1 "general_operand" "0,dx")))]
2026   ""
2027   "@
2028   exth %0
2029   mov %1,%0\;exth %0"
2030   [(set_attr "cc" "none_0hit")])
2032 ;; ----------------------------------------------------------------------
2033 ;; SHIFTS
2034 ;; ----------------------------------------------------------------------
2036 (define_expand "ashlsi3"
2037   [(set (match_operand:SI 0 "register_operand" "")
2038         (ashift:SI
2039          (match_operand:SI 1 "register_operand" "")
2040          (match_operand:QI 2 "nonmemory_operand" "")))]
2041   ""
2042   "")
2044 (define_insn ""
2045   [(set (match_operand:SI 0 "register_operand" "=dax,dx,!dax")
2046         (ashift:SI
2047          (match_operand:SI 1 "register_operand" "0,0,dax")
2048          (match_operand:QI 2 "nonmemory_operand" "J,dxi,dax")))]
2049   "TARGET_AM33"
2050   "*
2052   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 1)
2053     return \"add %0,%0\";
2055   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 2)
2056     return \"asl2 %0\";
2058   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 3
2059       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS)
2060     return \"asl2 %0\;add %0,%0\";
2062   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 4
2063       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS)
2064     return \"asl2 %0\;asl2 %0\";
2066   if (true_regnum (operands[1]) == true_regnum (operands[0]))
2067     return \"asl %S2,%0\";
2069   if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
2070       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
2071       && true_regnum (operands[0]) != true_regnum (operands[2]))
2072     return \"mov %1,%0\;asl %S2,%0\";
2073   return \"asl %2,%1,%0\";
2075   [(set_attr "cc" "set_zn")])
2077 (define_insn ""
2078   [(set (match_operand:SI 0 "register_operand" "=dax,dx,dx,dx,dx")
2079         (ashift:SI
2080          (match_operand:SI 1 "register_operand" "0,0,0,0,0")
2081          (match_operand:QI 2 "nonmemory_operand" "J,K,M,L,dxi")))]
2082   ""
2083   "@
2084   add %0,%0
2085   asl2 %0
2086   asl2 %0\;add %0,%0
2087   asl2 %0\;asl2 %0
2088   asl %S2,%0"
2089   [(set_attr "cc" "set_zn")])
2091 (define_expand "lshrsi3"
2092   [(set (match_operand:SI 0 "register_operand" "")
2093         (lshiftrt:SI
2094          (match_operand:SI 1 "register_operand" "")
2095          (match_operand:QI 2 "nonmemory_operand" "")))]
2096   ""
2097   "")
2099 (define_insn ""
2100   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
2101         (lshiftrt:SI
2102          (match_operand:SI 1 "register_operand" "0,dax")
2103          (match_operand:QI 2 "nonmemory_operand" "dxi,dax")))]
2104   "TARGET_AM33"
2105   "*
2107   if (true_regnum (operands[1]) == true_regnum (operands[0]))
2108     return \"lsr %S2,%0\";
2110   if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
2111       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
2112       && true_regnum (operands[0]) != true_regnum (operands[2]))
2113     return \"mov %1,%0\;lsr %S2,%0\";
2114   return \"lsr %2,%1,%0\";
2116   [(set_attr "cc" "set_zn")])
2118 (define_insn ""
2119   [(set (match_operand:SI 0 "register_operand" "=dx")
2120         (lshiftrt:SI
2121          (match_operand:SI 1 "register_operand" "0")
2122          (match_operand:QI 2 "nonmemory_operand" "dxi")))]
2123   ""
2124   "lsr %S2,%0"
2125   [(set_attr "cc" "set_zn")])
2127 (define_expand "ashrsi3"
2128   [(set (match_operand:SI 0 "register_operand" "")
2129         (ashiftrt:SI
2130          (match_operand:SI 1 "register_operand" "")
2131          (match_operand:QI 2 "nonmemory_operand" "")))]
2132   ""
2133   "")
2135 (define_insn ""
2136   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
2137         (ashiftrt:SI
2138          (match_operand:SI 1 "register_operand" "0,dax")
2139          (match_operand:QI 2 "nonmemory_operand" "dxi,dax")))]
2140   "TARGET_AM33"
2141   "*
2143   if (true_regnum (operands[1]) == true_regnum (operands[0]))
2144     return \"asr %S2,%0\";
2146   if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
2147       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
2148       && true_regnum (operands[0]) != true_regnum (operands[2]))
2149     return \"mov %1,%0\;asr %S2,%0\";
2150   return \"asr %2,%1,%0\";
2152   [(set_attr "cc" "set_zn")])
2154 (define_insn ""
2155   [(set (match_operand:SI 0 "register_operand" "=dx")
2156         (ashiftrt:SI
2157          (match_operand:SI 1 "register_operand" "0")
2158          (match_operand:QI 2 "nonmemory_operand" "dxi")))]
2159   ""
2160   "asr %S2,%0"
2161   [(set_attr "cc" "set_zn")])
2163 ;; ----------------------------------------------------------------------
2164 ;; FP INSTRUCTIONS
2165 ;; ----------------------------------------------------------------------
2167 ;; The mn103 series does not have floating point instructions, but since
2168 ;; FP values are held in integer regs, we can clear the high bit easily
2169 ;; which gives us an efficient inline floating point absolute value.
2171 ;; Similarly for negation of a FP value.
2174 (define_expand "absdf2"
2175   [(set (match_operand:DF 0 "register_operand" "")
2176         (abs:DF (match_operand:DF 1 "register_operand" "")))]
2177   ""
2178   "
2180   rtx target, result, insns;
2182   start_sequence ();
2183   target = operand_subword (operands[0], 1, 1, DFmode);
2184   result = expand_binop (SImode, and_optab,
2185                          operand_subword_force (operands[1], 1, DFmode),
2186                          GEN_INT (0x7fffffff), target, 0, OPTAB_WIDEN);
2188   gcc_assert (result);
2190   if (result != target)
2191     emit_move_insn (result, target);
2193   emit_move_insn (operand_subword (operands[0], 0, 1, DFmode),
2194                   operand_subword_force (operands[1], 0, DFmode));
2196   insns = get_insns ();
2197   end_sequence ();
2199   emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
2200   DONE;
2203 (define_expand "abssf2"
2204   [(set (match_operand:SF 0 "register_operand" "")
2205         (abs:SF (match_operand:SF 1 "register_operand" "")))]
2206   ""
2207   "
2209   rtx result;
2210   rtx target;
2212   if (TARGET_AM33_2)
2213     {
2214       emit_insn (gen_abssf2_am33_2 (operands[0], operands[1]));
2215       DONE;
2216     }
2218   target = operand_subword_force (operands[0], 0, SFmode);
2219   result = expand_binop (SImode, and_optab,
2220                          operand_subword_force (operands[1], 0, SFmode),
2221                          GEN_INT (0x7fffffff), target, 0, OPTAB_WIDEN);
2222   gcc_assert (result);
2224   if (result != target)
2225     emit_move_insn (result, target);
2227   /* Make a place for REG_EQUAL.  */
2228   emit_move_insn (operands[0], operands[0]);
2229   DONE;
2233 (define_insn "abssf2_am33_2"
2234   [(set (match_operand:SF 0 "register_operand" "=f,f")
2235         (abs:SF (match_operand:SF 1 "register_operand" "0,?f")))]
2236   "TARGET_AM33_2"
2237   "@
2238    fabs %0
2239    fabs %1, %0"
2240   [(set_attr "cc" "none_0hit")])
2242 (define_expand "negdf2"
2243   [(set (match_operand:DF 0 "register_operand" "")
2244         (neg:DF (match_operand:DF 1 "register_operand" "")))]
2245   ""
2246   "
2248   rtx target, result, insns;
2250   start_sequence ();
2251   target = operand_subword (operands[0], 1, 1, DFmode);
2252   result = expand_binop (SImode, xor_optab,
2253                          operand_subword_force (operands[1], 1, DFmode),
2254                          GEN_INT (trunc_int_for_mode (0x80000000, SImode)),
2255                          target, 0, OPTAB_WIDEN);
2257   gcc_assert (result);
2259   if (result != target)
2260     emit_move_insn (result, target);
2262   emit_move_insn (operand_subword (operands[0], 0, 1, DFmode),
2263                   operand_subword_force (operands[1], 0, DFmode));
2265   insns = get_insns ();
2266   end_sequence ();
2268   emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
2269   DONE;
2272 (define_expand "negsf2"
2273   [(set (match_operand:SF 0 "register_operand" "")
2274         (neg:SF (match_operand:SF 1 "register_operand" "")))]
2275   ""
2276   "
2278   rtx result;
2279   rtx target;
2281   if (TARGET_AM33_2)
2282     {
2283       emit_insn (gen_negsf2_am33_2 (operands[0], operands[1]));
2284       DONE;
2285     }
2287   target = operand_subword_force (operands[0], 0, SFmode);
2288   result = expand_binop (SImode, xor_optab,
2289                          operand_subword_force (operands[1], 0, SFmode),
2290                          GEN_INT (trunc_int_for_mode (0x80000000, SImode)),
2291                          target, 0, OPTAB_WIDEN);
2292   gcc_assert (result);
2294   if (result != target)
2295     emit_move_insn (result, target);
2297   /* Make a place for REG_EQUAL.  */
2298   emit_move_insn (operands[0], operands[0]);
2299   DONE;
2302 (define_insn "negsf2_am33_2"
2303   [(set (match_operand:SF 0 "register_operand" "=f,f")
2304         (neg:SF (match_operand:SF 1 "register_operand" "0,?f")))]
2305   "TARGET_AM33_2"
2306   "@
2307    fneg %0
2308    fneg %1, %0"
2309   [(set_attr "cc" "none_0hit")])
2311 (define_expand "sqrtsf2"
2312   [(set (match_operand:SF 0 "register_operand" "")
2313         (sqrt:SF (match_operand:SF 1 "register_operand" "")))]
2314   "TARGET_AM33_2 && flag_unsafe_math_optimizations"
2315   "
2317   rtx scratch = gen_reg_rtx (SFmode);
2318   emit_insn (gen_rsqrtsf2 (scratch, operands[1], CONST1_RTX (SFmode)));
2319   emit_insn (gen_divsf3 (operands[0], force_reg (SFmode, CONST1_RTX (SFmode)),
2320                          scratch));
2321   DONE;
2324 (define_insn "rsqrtsf2"
2325   [(set (match_operand:SF 0 "register_operand" "=f,f")
2326         (div:SF (match_operand:SF 2 "const_1f_operand" "F,F")
2327                 (sqrt:SF (match_operand:SF 1 "register_operand" "0,?f"))))]
2328   "TARGET_AM33_2"
2329   "@
2330    frsqrt %0
2331    frsqrt %1, %0"
2332   [(set_attr "cc" "none_0hit")])
2334 (define_insn "addsf3"
2335   [(set (match_operand:SF 0 "register_operand" "=f,f")
2336         (plus:SF (match_operand:SF 1 "register_operand" "%0,f")
2337                  (match_operand:SF 2 "general_operand" "f,?fF")))]
2338   "TARGET_AM33_2"
2339   "@
2340    fadd %2, %0
2341    fadd %2, %1, %0"
2342   [(set_attr "cc" "none_0hit")])
2344 (define_insn "subsf3"
2345   [(set (match_operand:SF 0 "register_operand" "=f,f")
2346         (minus:SF (match_operand:SF 1 "register_operand" "0,f")
2347                   (match_operand:SF 2 "general_operand" "f,?fF")))]
2348   "TARGET_AM33_2"
2349   "@
2350    fsub %2, %0
2351    fsub %2, %1, %0"
2352   [(set_attr "cc" "none_0hit")])
2354 (define_insn "mulsf3"
2355   [(set (match_operand:SF 0 "register_operand" "=f,f")
2356         (mult:SF (match_operand:SF 1 "register_operand" "%0,f")
2357                  (match_operand:SF 2 "general_operand" "f,?fF")))]
2358   "TARGET_AM33_2"
2359   "@
2360    fmul %2, %0
2361    fmul %2, %1, %0"
2362   [(set_attr "cc" "none_0hit")])
2364 (define_insn "divsf3"
2365   [(set (match_operand:SF 0 "register_operand" "=f,f")
2366         (div:SF (match_operand:SF 1 "register_operand" "0,f")
2367                 (match_operand:SF 2 "general_operand" "f,?fF")))]
2368   "TARGET_AM33_2"
2369   "@
2370    fdiv %2, %0
2371    fdiv %2, %1, %0"
2372   [(set_attr "cc" "none_0hit")])
2374 (define_insn "fmaddsf4"
2375   [(set (match_operand:SF 0 "register_operand" "=A")
2376         (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
2377                           (match_operand:SF 2 "register_operand" "f"))
2378                  (match_operand:SF 3 "register_operand" "f")))]
2379   "TARGET_AM33_2"
2380   "fmadd %1, %2, %3, %0"
2381   [(set_attr "cc" "none_0hit")])
2383 (define_insn "fmsubsf4"
2384   [(set (match_operand:SF 0 "register_operand" "=A")
2385         (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
2386                            (match_operand:SF 2 "register_operand" "f"))
2387                   (match_operand:SF 3 "register_operand" "f")))]
2388   "TARGET_AM33_2"
2389   "fmsub %1, %2, %3, %0"
2390   [(set_attr "cc" "none_0hit")])
2392 (define_insn "fnmaddsf4"
2393   [(set (match_operand:SF 0 "register_operand" "=A")
2394         (minus:SF (match_operand:SF 3 "register_operand" "f")
2395                   (mult:SF (match_operand:SF 1 "register_operand" "%f")
2396                            (match_operand:SF 2 "register_operand" "f"))))]
2397   "TARGET_AM33_2"
2398   "fnmadd %1, %2, %3, %0"
2399   [(set_attr "cc" "none_0hit")])
2401 (define_insn "fnmsubsf4"
2402   [(set (match_operand:SF 0 "register_operand" "=A")
2403         (minus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
2404                                    (match_operand:SF 2 "register_operand" "f")))
2405                   (match_operand:SF 3 "register_operand" "f")))]
2406   "TARGET_AM33_2"
2407   "fnmsub %1, %2, %3, %0"
2408   [(set_attr "cc" "none_0hit")])
2411 ;; ----------------------------------------------------------------------
2412 ;; PROLOGUE/EPILOGUE
2413 ;; ----------------------------------------------------------------------
2414 (define_expand "prologue"
2415   [(const_int 0)]
2416   ""
2417   "expand_prologue (); DONE;")
2419 (define_expand "epilogue"
2420   [(return)]
2421   ""
2422   "
2424   expand_epilogue ();
2425   DONE;
2428 (define_insn "return_internal"
2429   [(const_int 2)
2430    (return)]
2431   ""
2432   "rets"
2433   [(set_attr "cc" "clobber")])
2435 ;; This insn restores the callee saved registers and does a return, it
2436 ;; can also deallocate stack space.
2437 (define_insn "return_internal_regs"
2438   [(const_int 0)
2439    (match_operand:SI 0  "const_int_operand" "i")
2440    (return)]
2441   ""
2442   "*
2444   fputs (\"\\tret \", asm_out_file);
2445   mn10300_print_reg_list (asm_out_file, mn10300_get_live_callee_saved_regs ());
2446   fprintf (asm_out_file, \",%d\\n\", (int) INTVAL (operands[0]));
2447   return \"\";
2449   [(set_attr "cc" "clobber")])
2451 ;; This instruction matches one generated by mn10300_gen_multiple_store()
2452 (define_insn "store_movm"
2453   [(match_parallel 0 "store_multiple_operation"
2454     [(set (reg:SI 9) (plus:SI (reg:SI 9) (match_operand 1 "" "")))])]
2455   ""
2456   "*
2458   fputs (\"\\tmovm \", asm_out_file);
2459   mn10300_print_reg_list (asm_out_file,
2460                           store_multiple_operation (operands[0], VOIDmode));
2461   fprintf (asm_out_file, \",(sp)\\n\");
2462   return \"\";
2464   [(set_attr "cc" "clobber")])
2465   
2466 (define_insn "return"
2467   [(return)]
2468   "can_use_return_insn ()"
2469   "*
2471   rtx next = next_active_insn (insn);
2473   if (next
2474       && GET_CODE (next) == JUMP_INSN
2475       && GET_CODE (PATTERN (next)) == RETURN)
2476     return \"\";
2477   else
2478     return \"rets\";
2480   [(set_attr "cc" "clobber")])
2482 ;; Try to combine consecutive updates of the stack pointer (or any
2483 ;; other register for that matter).
2484 (define_peephole
2485   [(set (match_operand:SI 0 "register_operand" "=dxay")
2486         (plus:SI (match_dup 0)
2487                  (match_operand 1 "const_int_operand" "")))
2488    (set (match_dup 0)
2489         (plus:SI (match_dup 0)
2490                  (match_operand 2 "const_int_operand" "")))]
2491   ""
2492   "*
2494   operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]));
2495   return \"add %1,%0\";
2497   [(set_attr "cc" "clobber")])
2500 ;; We had patterns to check eq/ne, but the they don't work because
2501 ;; 0x80000000 + 0x80000000 = 0x0 with a carry out.
2503 ;; The Z flag and C flag would be set, and we have no way to
2504 ;; check for the Z flag set and C flag clear.
2506 ;; This will work on the mn10200 because we can check the ZX flag
2507 ;; if the comparison is in HImode.
2508 (define_peephole
2509   [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2510    (set (pc) (if_then_else (ge (cc0) (const_int 0))
2511                            (match_operand 1 "" "")
2512                            (pc)))]
2513   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2514   "add %0,%0\;bcc %1"
2515   [(set_attr "cc" "clobber")])
2517 (define_peephole
2518   [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2519    (set (pc) (if_then_else (lt (cc0) (const_int 0))
2520                            (match_operand 1 "" "")
2521                            (pc)))]
2522   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2523   "add %0,%0\;bcs %1"
2524   [(set_attr "cc" "clobber")])
2526 (define_peephole
2527   [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2528    (set (pc) (if_then_else (ge (cc0) (const_int 0))
2529                            (pc)
2530                            (match_operand 1 "" "")))]
2531   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2532   "add %0,%0\;bcs %1"
2533   [(set_attr "cc" "clobber")])
2535 (define_peephole
2536   [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2537    (set (pc) (if_then_else (lt (cc0) (const_int 0))
2538                            (pc)
2539                            (match_operand 1 "" "")))]
2540   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2541   "add %0,%0\;bcc %1"
2542   [(set_attr "cc" "clobber")])
2544 (define_expand "int_label"
2545   [(unspec [(match_operand:SI 0 "" "")] UNSPEC_INT_LABEL)]
2546   "" "")
2548 (define_expand "GOTaddr2picreg"
2549   [(match_dup 0)]
2550   "" "
2552   /* It would be nice to be able to have int_label keep track of the
2553      counter and all, but if we add C code to it, we'll get an insn
2554      back, and we just want the pattern.  */
2555   operands[0] = gen_int_label (GEN_INT (mn10300_unspec_int_label_counter++));
2556   if (TARGET_AM33)
2557     emit_insn (gen_am33_loadPC (operands[0]));
2558   else
2559     emit_insn (gen_mn10300_loadPC (operands[0]));
2560   emit_insn (gen_add_GOT_to_pic_reg (operands[0]));
2561   DONE;
2565 (define_insn "am33_loadPC"
2566   [(parallel
2567     [(set (reg:SI PIC_REG) (pc))
2568      (use (match_operand 0 "" ""))])]
2569   "TARGET_AM33"
2570   "%0:\;mov pc,a2")
2573 (define_insn_and_split "mn10300_loadPC"
2574   [(parallel
2575     [(set (reg:SI PIC_REG) (pc))
2576      (use (match_operand 0 "" ""))])]
2577   ""
2578   "#"
2579   "reload_completed"
2580   [(match_operand 0 "" "")]
2581   "
2583   rtx sp_reg = gen_rtx_REG (SImode, SP_REG);
2584   int need_stack_space = (get_frame_size () == 0
2585                           && current_function_outgoing_args_size == 0);
2587   if (need_stack_space)
2588     emit_move_insn (sp_reg, plus_constant (sp_reg, -4));
2590   emit_insn (gen_call_next_insn (operands[0]));
2592   if (need_stack_space)
2593     emit_insn (gen_pop_pic_reg ());
2594   else
2595     emit_move_insn (pic_offset_table_rtx, gen_rtx_MEM (SImode, sp_reg));
2597   DONE;
2600 (define_insn "call_next_insn"
2601   [(parallel
2602     [(set (mem:SI (reg:SI SP_REG)) (pc))
2603      (use (match_operand 0 "" ""))])]
2604   "reload_completed"
2605   "calls %0\;%0:")
2607 (define_expand "add_GOT_to_pic_reg"
2608   [(set (reg:SI PIC_REG)
2609         (plus:SI
2610          (reg:SI PIC_REG)
2611          (const
2612           (unspec [(minus:SI
2613                     (match_dup 1)
2614                     (const (minus:SI
2615                             (const (match_operand:SI 0 "" ""))
2616                             (pc))))
2617                   ] UNSPEC_PIC))))]
2618   ""
2619   "
2621   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
2624 (define_expand "symGOT2reg"
2625   [(match_operand:SI 0 "" "")
2626    (match_operand:SI 1 "" "")]
2627   ""
2628   "
2630   rtx insn = emit_insn (gen_symGOT2reg_i (operands[0], operands[1]));
2632   MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
2634   set_unique_reg_note (insn, REG_EQUAL, operands[1]);
2636   DONE;
2639 (define_expand "symGOT2reg_i"
2640   [(set (match_operand:SI 0 "" "")
2641         (mem:SI (plus:SI (reg:SI PIC_REG)
2642                          (const (unspec [(match_operand:SI 1 "" "")]
2643                                         UNSPEC_GOT)))))]
2644   ""
2645   "")
2647 (define_expand "symGOTOFF2reg"
2648   [(match_operand:SI 0 "" "") (match_operand:SI 1 "" "")]
2649   ""
2650   "
2652   rtx insn = emit_insn (gen_symGOTOFF2reg_i (operands[0], operands[1]));
2654   set_unique_reg_note (insn, REG_EQUAL, operands[1]);
2656   DONE;
2659 (define_expand "symGOTOFF2reg_i"
2660   [(set (match_operand:SI 0 "" "")
2661         (const (unspec [(match_operand:SI 1 "" "")] UNSPEC_GOTOFF)))
2662   (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI PIC_REG)))]
2663   ""
2664   "")
2666 (define_expand "sym2PIC"
2667   [(unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC)]
2668   "" "")
2670 (define_expand "sym2PLT"
2671   [(unspec [(match_operand:SI 0 "" "")] UNSPEC_PLT)]
2672   "" "")