2008-05-30 Vladimir Makarov <vmakarov@redhat.com>
[official-gcc.git] / gcc / config / mn10300 / mn10300.md
blob57c51625b227eb77a13b0e76f3372d6065f0b5aa
1 ;; GCC machine description for Matsushita MN10300
2 ;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
3 ;; 2007 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 3, 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 COPYING3.  If not see
20 ;; <http://www.gnu.org/licenses/>.
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 ;; Condition code settings.
28 ;; none - insn does not affect cc
29 ;; none_0hit - insn does not affect cc but it does modify operand 0
30 ;;      This attribute is used to keep track of when operand 0 changes.
31 ;;      See the description of NOTICE_UPDATE_CC for more info.
32 ;; set_znv - insn sets z,n,v to usable values; c is unusable.
33 ;; set_zn  - insn sets z,n to usable values; v,c are unusable.
34 ;; compare - compare instruction
35 ;; clobber - value of cc is unknown
36 (define_attr "cc" "none,none_0hit,set_znv,set_zn,compare,clobber"
37   (const_string "clobber"))
39 (define_constants [
40   (PIC_REG      6)
41   (SP_REG       9)
43   (UNSPEC_INT_LABEL     0)
44   (UNSPEC_PIC           1)
45   (UNSPEC_GOT           2)
46   (UNSPEC_GOTOFF        3)
47   (UNSPEC_PLT           4)
50 (include "predicates.md")
51 (include "constraints.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 = (!can_create_pseudo_p ()
310                       ? operands[0]
311                       : gen_reg_rtx (Pmode));
312               operands[1] = legitimize_pic_address (operands[1], temp);
313             }
314         }
315       else if (GET_CODE (operands[1]) == CONST
316                && GET_CODE (XEXP (operands[1], 0)) == PLUS
317                && SYMBOLIC_CONST_P (XEXP (XEXP (operands[1], 0), 0)))
318         {
319           temp = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
320           temp = legitimize_pic_address (XEXP (XEXP (operands[1], 0), 0),
321                                          temp);
322           operands[1] = expand_binop (SImode, add_optab, temp,
323                                       XEXP (XEXP (operands[1], 0), 1),
324                                       (!can_create_pseudo_p ()
325                                        ? temp
326                                        : gen_reg_rtx (Pmode)),
327                                       0, OPTAB_LIB_WIDEN);
328         }
329     }
332 (define_insn ""
333   [(set (match_operand:SI 0 "nonimmediate_operand"
334                                 "=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax,axR,!*y,*f,*f,dxaQ")
335         (match_operand:SI 1 "general_operand"
336                                 "0,0,I,I,dx,ax,dx,ax,dixm,aixm,dixm,aixm,!*y,axR,0,dxaQi*f,*f"))]
337   "register_operand (operands[0], SImode)
338    || register_operand (operands[1], SImode)"
339   "*
341   switch (which_alternative)
342     {
343     case 0:
344     case 1:
345       return \"nop\";
346     case 2:
347       return \"clr %0\";
348     case 3:
349     case 4:
350     case 5:
351     case 6:
352     case 7:
353     case 8:
354     case 9:
355     case 10:
356     case 11:
357     case 12:
358     case 13:
359       if (GET_CODE (operands[1]) == CONST_DOUBLE)
360         {
361           rtx xoperands[2];
362           xoperands[0] = operands[0];
363           xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
364           output_asm_insn (\"mov %1,%0\", xoperands);
365           return \"\";
366         }
368       if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
369           && GET_CODE (operands[1]) == CONST_INT)
370         {
371           HOST_WIDE_INT val = INTVAL (operands[1]);
373           if (((val & 0x80) && ! (val & 0xffffff00))
374               || ((val & 0x800000) && ! (val & 0xff000000)))
375             return \"movu %1,%0\";
376         }
377       return \"mov %1,%0\";
378     case 14:
379       return \"nop\";
380     case 15:
381     case 16:
382       return \"fmov %1,%0\";
383     default:
384       gcc_unreachable ();
385     }
387   [(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")])
389 (define_expand "movsf"
390   [(set (match_operand:SF 0 "general_operand" "")
391         (match_operand:SF 1 "general_operand" ""))]
392   ""
393   "
395   /* One of the ops has to be in a register */
396   if (!register_operand (operand1, SFmode)
397       && !register_operand (operand0, SFmode))
398     operands[1] = copy_to_mode_reg (SFmode, operand1);
401 (define_insn ""
402   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,dx,ax,dx,a,f,dxaQ,daxm,dax")
403         (match_operand:SF 1 "general_operand" "0,0,0,G,G,fdxaQF,f,dax,daxFm"))]
404   "register_operand (operands[0], SFmode)
405    || register_operand (operands[1], SFmode)"
406   "*
408   switch (which_alternative)
409     {
410     case 0:
411     case 1:
412     case 2:
413       return \"nop\";
414     case 3:
415       return \"clr %0\";
416     /* case 4: below */
417     case 5:
418     case 6:
419       return \"fmov %1, %0\";
420     case 4:
421     case 7:
422     case 8:
423       if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
424           && GET_CODE (operands[1]) == CONST_INT)
425         {
426           HOST_WIDE_INT val = INTVAL (operands[1]);
428           if (((val & 0x80) && ! (val & 0xffffff00))
429               || ((val & 0x800000) && ! (val & 0xff000000)))
430             return \"movu %1,%0\";
431         }
432       return \"mov %1,%0\";
433     default:
434       gcc_unreachable ();
435     }
437   [(set_attr "cc" "none,none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
439 (define_expand "movdi"
440   [(set (match_operand:DI 0 "general_operand" "")
441         (match_operand:DI 1 "general_operand" ""))]
442   ""
443   "
445   /* One of the ops has to be in a register */
446   if (!register_operand (operand1, DImode)
447       && !register_operand (operand0, DImode))
448     operands[1] = copy_to_mode_reg (DImode, operand1);
451 (define_insn ""
452   [(set (match_operand:DI 0 "nonimmediate_operand"
453                                 "=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax,*f,*f,*f,dxa,*f,Q")
454         (match_operand:DI 1 "general_operand"
455                                 "0,0,I,I,dx,ax,dx,ax,dxim,axim,dxim,axim,0,*f,dxai,*f,Q,*f"))]
456   "register_operand (operands[0], DImode)
457    || register_operand (operands[1], DImode)"
458   "*
460   long val[2];
461   REAL_VALUE_TYPE rv;
463   switch (which_alternative)
464     {
465       case 0:
466       case 1:
467         return \"nop\";
469       case 2:
470         return \"clr %L0\;clr %H0\";
472       case 3:
473         if (rtx_equal_p (operands[0], operands[1]))
474           return \"sub %L1,%L0\;mov %L0,%H0\";
475         else
476           return \"mov %1,%L0\;mov %L0,%H0\";
477       case 4:
478       case 5:
479       case 6:
480       case 7:
481       case 8:
482       case 9:
483       case 10:
484       case 11:
485         if (GET_CODE (operands[1]) == CONST_INT)
486           {
487             rtx low, high;
488             split_double (operands[1], &low, &high);
489             val[0] = INTVAL (low);
490             val[1] = INTVAL (high);
491           }
492         if (GET_CODE (operands[1]) == CONST_DOUBLE)
493           {
494             if (GET_MODE (operands[1]) == DFmode)
495               {
496                 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
497                 REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
498               }
499             else if (GET_MODE (operands[1]) == VOIDmode
500                      || GET_MODE (operands[1]) == DImode)
501               {
502                 val[0] = CONST_DOUBLE_LOW (operands[1]);
503                 val[1] = CONST_DOUBLE_HIGH (operands[1]);
504               }
505           }
507         if (GET_CODE (operands[1]) == MEM
508             && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
509           {
510             rtx temp = operands[0];
512             while (GET_CODE (temp) == SUBREG)
513               temp = SUBREG_REG (temp);
515             gcc_assert (GET_CODE (temp) == REG);
517             if (reg_overlap_mentioned_p (gen_rtx_REG (SImode, REGNO (temp)),
518                                          XEXP (operands[1], 0)))
519               return \"mov %H1,%H0\;mov %L1,%L0\";
520             else
521               return \"mov %L1,%L0\;mov %H1,%H0\";
523           }
524         else if (GET_CODE (operands[1]) == MEM
525                  && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
526                  && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
527           {
528             rtx xoperands[2];
530             xoperands[0] = operands[0];
531             xoperands[1] = XEXP (operands[1], 0);
533             output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\",
534                              xoperands);
535             return \"\";
536           }
537         else
538           {
539             if ((GET_CODE (operands[1]) == CONST_INT
540                  || GET_CODE (operands[1]) == CONST_DOUBLE)
541                 && val[0] == 0)
542               {
543                 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
544                   output_asm_insn (\"clr %L0\", operands);
545                 else
546                   output_asm_insn (\"mov %L1,%L0\", operands);
547               }
548             else if ((GET_CODE (operands[1]) == CONST_INT
549                       || GET_CODE (operands[1]) == CONST_DOUBLE)
550                      && (REGNO_REG_CLASS (true_regnum (operands[0]))
551                          == EXTENDED_REGS)
552                      && (((val[0] & 0x80) && ! (val[0] & 0xffffff00))
553                          || ((val[0] & 0x800000) && ! (val[0] & 0xff000000))))
554               output_asm_insn (\"movu %L1,%L0\", operands);
555             else
556               output_asm_insn (\"mov %L1,%L0\", operands);
558             if ((GET_CODE (operands[1]) == CONST_INT
559                  || GET_CODE (operands[1]) == CONST_DOUBLE)
560                 && val[1] == 0)
561               {
562                 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
563                   output_asm_insn (\"clr %H0\", operands);
564                 else
565                   output_asm_insn (\"mov %H1,%H0\", operands);
566               }
567             else if ((GET_CODE (operands[1]) == CONST_INT
568                       || GET_CODE (operands[1]) == CONST_DOUBLE)
569                      && val[0] == val[1])
570               output_asm_insn (\"mov %L0,%H0\", operands);
571             else if ((GET_CODE (operands[1]) == CONST_INT
572                       || GET_CODE (operands[1]) == CONST_DOUBLE)
573                      && (REGNO_REG_CLASS (true_regnum (operands[0]))
574                          == EXTENDED_REGS)
575                      && (((val[1] & 0x80) && ! (val[1] & 0xffffff00))
576                          || ((val[1] & 0x800000) && ! (val[1] & 0xff000000))))
577               output_asm_insn (\"movu %H1,%H0\", operands);
578             else
579               output_asm_insn (\"mov %H1,%H0\", operands);
580             return \"\";
581           }
582       case 12:
583         return \"nop\";
584       case 13:
585       case 14:
586       case 15:
587         return \"fmov %L1, %L0\;fmov %H1, %H0\";
588       case 16:
589         if (GET_CODE (operands[1]) == MEM
590             && GET_CODE (XEXP (operands[1], 0)) == CONST_INT
591             && (INTVAL (XEXP (operands[1], 0)) & 7) == 0)
592           return \"fmov %D1, %D0\";
593         else
594           return \"fmov %L1, %L0\;fmov %H1, %H0\";
595       case 17:
596         if (GET_CODE (operands[0]) == MEM
597             && GET_CODE (XEXP (operands[0], 0)) == CONST_INT
598             && (INTVAL (XEXP (operands[0], 0)) & 7) == 0)
599           return \"fmov %D1, %D0\";
600         else
601           return \"fmov %L1, %L0\;fmov %H1, %H0\";
602     default:
603       gcc_unreachable ();
604     }
606   [(set (attr "cc")
607         (cond
608          [
609          (ior (lt (symbol_ref "which_alternative") (const_int 2))
610               (eq (symbol_ref "which_alternative") (const_int 12))
611               ) (const_string "none")
612          (eq (symbol_ref "which_alternative") (const_int 2)
613              ) (const_string "clobber")
614          (eq (symbol_ref "which_alternative") (const_int 3)
615              ) (if_then_else
616                 (ne (symbol_ref "rtx_equal_p (operands[0], operands[1])")
617                     (const_int 0)) (const_string "clobber")
618                     (const_string "none_0hit"))
619          (ior (eq (symbol_ref "which_alternative") (const_int 8))
620               (eq (symbol_ref "which_alternative") (const_int 9))
621               ) (if_then_else
622                  (ne (symbol_ref "mn10300_wide_const_load_uses_clr
623                                   (operands)")
624                      (const_int 0)) (const_string "clobber")
625                      (const_string "none_0hit"))
626          ] (const_string "none_0hit")))])
628 (define_expand "movdf"
629   [(set (match_operand:DF 0 "general_operand" "")
630         (match_operand:DF 1 "general_operand" ""))]
631   ""
632   "
634   /* One of the ops has to be in a register */
635   if (!register_operand (operand1, DFmode)
636       && !register_operand (operand0, DFmode))
637     operands[1] = copy_to_mode_reg (DFmode, operand1);
640 (define_insn ""
641   [(set (match_operand:DF 0 "nonimmediate_operand"
642                                 "=f,dx,ax,dx,f,f,dxa,f,Q,a,dxm,dxm,axm,axm,dx,dx,ax,ax")
643         (match_operand:DF 1 "general_operand"
644                                 "0,0,0,G,f,dxaF,f,Q,f,G,dx,ax,dx,ax,dxFm,axFm,dxFm,axFm"))]
645   "register_operand (operands[0], DFmode)
646    || register_operand (operands[1], DFmode)"
647   "*
649   long val[2];
650   REAL_VALUE_TYPE rv;
652   switch (which_alternative)
653     {
654       case 0:
655       case 1:
656       case 2:
657         return \"nop\";
659       case 3:
660         return \"clr %L0\;clr %H0\";
662       case 4:
663       case 5:
664       case 6:
665         return \"fmov %L1, %L0\;fmov %H1, %H0\";
667       case 7:
668         if (GET_CODE (operands[1]) == MEM
669             && GET_CODE (XEXP (operands[1], 0)) == CONST_INT
670             && (INTVAL (XEXP (operands[1], 0)) & 7) == 0)
671           return \"fmov %D1, %D0\";
672         else
673           return \"fmov %L1, %L0\;fmov %H1, %H0\";
675       case 8:
676         if (GET_CODE (operands[0]) == MEM
677             && GET_CODE (XEXP (operands[0], 0)) == CONST_INT
678             && (INTVAL (XEXP (operands[0], 0)) & 7) == 0)
679           return \"fmov %D1, %D0\";
680         else
681           return \"fmov %L1, %L0\;fmov %H1, %H0\";
683       case 9:
684          if (rtx_equal_p (operands[0], operands[1]))
685            return \"sub %L1,%L0\;mov %L0,%H0\";
686          else
687            return \"mov %1,%L0\;mov %L0,%H0\";
688       case 10:
689       case 11:
690       case 12:
691       case 13:
692       case 14:
693       case 15:
694       case 16:
695       case 17:
696         if (GET_CODE (operands[1]) == CONST_INT)
697           {
698             rtx low, high;
699             split_double (operands[1], &low, &high);
700             val[0] = INTVAL (low);
701             val[1] = INTVAL (high);
702           }
703         if (GET_CODE (operands[1]) == CONST_DOUBLE)
704           {
705             if (GET_MODE (operands[1]) == DFmode)
706               {
707                 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
708                 REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
709               }
710             else if (GET_MODE (operands[1]) == VOIDmode
711                      || GET_MODE (operands[1]) == DImode)
712               {
713                 val[0] = CONST_DOUBLE_LOW (operands[1]);
714                 val[1] = CONST_DOUBLE_HIGH (operands[1]);
715               }
716           }
718         if (GET_CODE (operands[1]) == MEM
719             && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
720           {
721             rtx temp = operands[0];
723             while (GET_CODE (temp) == SUBREG)
724               temp = SUBREG_REG (temp);
726             gcc_assert (GET_CODE (temp) == REG);
728             if (reg_overlap_mentioned_p (gen_rtx_REG (SImode, REGNO (temp)),
729                                          XEXP (operands[1], 0)))
730               return \"mov %H1,%H0\;mov %L1,%L0\";
731             else
732               return \"mov %L1,%L0\;mov %H1,%H0\";
734           }
735         else if (GET_CODE (operands[1]) == MEM
736                  && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
737                  && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
738           {
739             rtx xoperands[2];
741             xoperands[0] = operands[0];
742             xoperands[1] = XEXP (operands[1], 0);
744             output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\",
745                              xoperands);
746             return \"\";
747           }
748         else
749           {
750             if ((GET_CODE (operands[1]) == CONST_INT
751                  || GET_CODE (operands[1]) == CONST_DOUBLE)
752                 && val[0] == 0)
753               {
754                 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
755                   output_asm_insn (\"clr %L0\", operands);
756                 else
757                   output_asm_insn (\"mov %L1,%L0\", operands);
758               }
759             else if ((GET_CODE (operands[1]) == CONST_INT
760                       || GET_CODE (operands[1]) == CONST_DOUBLE)
761                      && (REGNO_REG_CLASS (true_regnum (operands[0]))
762                          == EXTENDED_REGS)
763                      && (((val[0] & 0x80) && ! (val[0] & 0xffffff00))
764                          || ((val[0] & 0x800000) && ! (val[0] & 0xff000000))))
765               output_asm_insn (\"movu %L1,%L0\", operands);
766             else
767               output_asm_insn (\"mov %L1,%L0\", operands);
769             if ((GET_CODE (operands[1]) == CONST_INT
770                  || GET_CODE (operands[1]) == CONST_DOUBLE)
771                 && val[1] == 0)
772               {
773                 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
774                   output_asm_insn (\"clr %H0\", operands);
775                 else
776                   output_asm_insn (\"mov %H1,%H0\", operands);
777               }
778             else if ((GET_CODE (operands[1]) == CONST_INT
779                       || GET_CODE (operands[1]) == CONST_DOUBLE)
780                      && val[0] == val[1])
781               output_asm_insn (\"mov %L0,%H0\", operands);
782             else if ((GET_CODE (operands[1]) == CONST_INT
783                       || GET_CODE (operands[1]) == CONST_DOUBLE)
784                      && (REGNO_REG_CLASS (true_regnum (operands[0]))
785                          == EXTENDED_REGS)
786                      && (((val[1] & 0x80) && ! (val[1] & 0xffffff00))
787                          || ((val[1] & 0x800000) && ! (val[1] & 0xff000000))))
788               output_asm_insn (\"movu %H1,%H0\", operands);
789             else
790               output_asm_insn (\"mov %H1,%H0\", operands);
791             return \"\";
792           }
793     default:
794       gcc_unreachable ();
795     }
797   [(set (attr "cc")
798         (cond
799          [
800          (lt (symbol_ref "which_alternative") (const_int 3)
801              ) (const_string "none")
802          (eq (symbol_ref "which_alternative") (const_int 3)
803              ) (const_string "clobber")
804          (eq (symbol_ref "which_alternative") (const_int 9)
805              ) (if_then_else
806                 (ne (symbol_ref "rtx_equal_p (operands[0], operands[1])")
807                     (const_int 0)) (const_string "clobber")
808                     (const_string "none_0hit"))
809          (ior (eq (symbol_ref "which_alternative") (const_int 14))
810               (eq (symbol_ref "which_alternative") (const_int 15))
811               ) (if_then_else
812                  (ne (symbol_ref "mn10300_wide_const_load_uses_clr
813                                   (operands)")
814                      (const_int 0)) (const_string "clobber")
815                      (const_string "none_0hit"))
816          ] (const_string "none_0hit")))])
820 ;; ----------------------------------------------------------------------
821 ;; TEST INSTRUCTIONS
822 ;; ----------------------------------------------------------------------
824 ;; Go ahead and define tstsi so we can eliminate redundant tst insns
825 ;; when we start trying to optimize this port.
826 (define_insn "tstsi"
827   [(set (cc0) (match_operand:SI 0 "register_operand" "dax"))]
828   ""
829   "* return output_tst (operands[0], insn);"
830   [(set_attr "cc" "set_znv")])
832 (define_insn ""
833   [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "dx,!a")))]
834   "TARGET_AM33"
835   "* return output_tst (operands[0], insn);"
836   [(set_attr "cc" "set_znv")])
838 (define_insn ""
839   [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "dx")))]
840   ""
841   "* return output_tst (operands[0], insn);"
842   [(set_attr "cc" "set_znv")])
844 (define_insn ""
845   [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "dx,!a")))]
846   "TARGET_AM33"
847   "* return output_tst (operands[0], insn);"
848   [(set_attr "cc" "set_znv")])
850 (define_insn ""
851   [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "dx")))]
852   ""
853   "* return output_tst (operands[0], insn);"
854   [(set_attr "cc" "set_znv")])
856 ;; Ordinarily, the cmp instruction will set the Z bit of cc0 to 1 if
857 ;; its operands hold equal values, but the operands of a cmp
858 ;; instruction must be distinct registers.  In the case where we'd
859 ;; like to compare a register to itself, we can achieve this effect
860 ;; with a btst 0,d0 instead.  (This will not alter the contents of d0
861 ;; but will have the proper effect on cc0.  Using d0 is arbitrary; any
862 ;; data register would work.)
864 ;; Even though the first alternative would be preferable if it can
865 ;; possibly match, reload must not be given the opportunity to attempt
866 ;; to use it.  It assumes that such matches can only occur when one of
867 ;; the operands is used for input and the other for output.  Since
868 ;; this is not the case, it abort()s.  Indeed, such a reload cannot be
869 ;; possibly satisfied, so just mark the alternative with a `!', so
870 ;; that it is not considered by reload.
872 (define_insn "cmpsi"
873   [(set (cc0)
874         (compare (match_operand:SI 0 "register_operand" "!*d*a*x,dax")
875                  (match_operand:SI 1 "nonmemory_operand" "*0,daxi")))]
876   ""
877   "@
878   btst 0,d0
879   cmp %1,%0"
880   [(set_attr "cc" "compare,compare")])
882 (define_insn "cmpsf"
883   [(set (cc0)
884         (compare (match_operand:SF 0 "register_operand" "f,f")
885                  (match_operand:SF 1 "nonmemory_operand" "f,F")))]
886   "TARGET_AM33_2"
887   "fcmp %1,%0"
888   [(set_attr "cc" "compare,compare")])
890 ;; ----------------------------------------------------------------------
891 ;; ADD INSTRUCTIONS
892 ;; ----------------------------------------------------------------------
894 (define_expand "addsi3"
895   [(set (match_operand:SI 0 "register_operand" "")
896         (plus:SI (match_operand:SI 1 "register_operand" "")
897                  (match_operand:SI 2 "nonmemory_operand" "")))]
898   ""
899   "")
901 (define_insn ""
902   [(set (match_operand:SI 0 "register_operand" "=dx,a,x,a,dax,!*y,!dax")
903         (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,dax")
904                  (match_operand:SI 2 "nonmemory_operand" "J,J,L,L,daxi,i,dax")))]
905   "TARGET_AM33"
906   "*
908   switch (which_alternative)
909     {
910     case 0:
911     case 1:
912       return \"inc %0\";
913     case 2:
914     case 3:
915       return \"inc4 %0\";
916     case 4:
917     case 5:
918       return \"add %2,%0\";
919     case 6:
920       {
921         enum reg_class src1_class, src2_class, dst_class;
923         src1_class = REGNO_REG_CLASS (true_regnum (operands[1]));
924         src2_class = REGNO_REG_CLASS (true_regnum (operands[2]));
925         dst_class = REGNO_REG_CLASS (true_regnum (operands[0]));
927         /* I'm not sure if this can happen or not.  Might as well be prepared
928           and generate the best possible code if it does happen.  */
929         if (true_regnum (operands[0]) == true_regnum (operands[1]))
930           return \"add %2,%0\";
931         if (true_regnum (operands[0]) == true_regnum (operands[2]))
932           return \"add %1,%0\";
934         /* Catch cases where no extended register was used.  These should be
935            handled just like the mn10300.  */
936         if (src1_class != EXTENDED_REGS
937             && src2_class != EXTENDED_REGS
938             && dst_class != EXTENDED_REGS)
939           {
940             /* We have to copy one of the sources into the destination, then
941                add the other source to the destination.
943                Carefully select which source to copy to the destination; a naive
944                implementation will waste a byte when the source classes are
945                different and the destination is an address register.  Selecting
946                the lowest cost register copy will optimize this sequence.  */
947             if (REGNO_REG_CLASS (true_regnum (operands[1]))
948                 == REGNO_REG_CLASS (true_regnum (operands[0])))
949               return \"mov %1,%0\;add %2,%0\";
950             return \"mov %2,%0\;add %1,%0\";
951           }
953         /* At least one register is an extended register.  */
955         /* The three operand add instruction on the am33 is a win iff the
956            output register is an extended register, or if both source
957            registers are extended registers.  */
958         if (dst_class == EXTENDED_REGS
959             || src1_class == src2_class)
960           return \"add %2,%1,%0\";
962       /* It is better to copy one of the sources to the destination, then
963          perform a 2 address add.  The destination in this case must be
964          an address or data register and one of the sources must be an
965          extended register and the remaining source must not be an extended
966          register.
968          The best code for this case is to copy the extended reg to the
969          destination, then emit a two address add.  */
970       if (src1_class == EXTENDED_REGS)
971         return \"mov %1,%0\;add %2,%0\";
972       return \"mov %2,%0\;add %1,%0\";
973       }
974     default:
975       gcc_unreachable ();
976     }
978   [(set_attr "cc" "set_zn,none_0hit,set_zn,none_0hit,set_zn,none_0hit,set_zn")])
980 (define_insn ""
981   [(set (match_operand:SI 0 "register_operand" "=dx,a,a,dax,!*y,!dax")
982         (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,dax")
983                  (match_operand:SI 2 "nonmemory_operand" "J,J,L,daxi,i,dax")))]
984   ""
985   "*
987   switch (which_alternative)
988     {
989     case 0:
990     case 1:
991       return \"inc %0\";
992     case 2:
993       return \"inc4 %0\";
994     case 3:
995     case 4:
996       return \"add %2,%0\";
997     case 5:
998       /* I'm not sure if this can happen or not.  Might as well be prepared
999          and generate the best possible code if it does happen.  */
1000       if (true_regnum (operands[0]) == true_regnum (operands[1]))
1001         return \"add %2,%0\";
1002       if (true_regnum (operands[0]) == true_regnum (operands[2]))
1003         return \"add %1,%0\";
1005       /* We have to copy one of the sources into the destination, then add
1006          the other source to the destination.
1008          Carefully select which source to copy to the destination; a naive
1009          implementation will waste a byte when the source classes are different
1010          and the destination is an address register.  Selecting the lowest
1011          cost register copy will optimize this sequence.  */
1012       if (REGNO_REG_CLASS (true_regnum (operands[1]))
1013           == REGNO_REG_CLASS (true_regnum (operands[0])))
1014         return \"mov %1,%0\;add %2,%0\";
1015       return \"mov %2,%0\;add %1,%0\";
1016     default:
1017       gcc_unreachable ();
1018     }
1020   [(set_attr "cc" "set_zn,none_0hit,none_0hit,set_zn,none_0hit,set_zn")])
1022 ;; ----------------------------------------------------------------------
1023 ;; SUBTRACT INSTRUCTIONS
1024 ;; ----------------------------------------------------------------------
1026 (define_expand "subsi3"
1027   [(set (match_operand:SI 0 "register_operand" "")
1028         (minus:SI (match_operand:SI 1 "register_operand" "")
1029                   (match_operand:SI 2 "nonmemory_operand" "")))]
1030   ""
1031   "")
1033 (define_insn ""
1034   [(set (match_operand:SI 0 "register_operand" "=dax,!dax")
1035         (minus:SI (match_operand:SI 1 "register_operand" "0,dax")
1036                   (match_operand:SI 2 "nonmemory_operand" "daxi,dax")))]
1037   "TARGET_AM33"
1038   "*
1040   if (true_regnum (operands[0]) == true_regnum (operands[1]))
1041     return \"sub %2,%0\";
1042   else
1043     {
1044       enum reg_class src1_class, src2_class, dst_class;
1046       src1_class = REGNO_REG_CLASS (true_regnum (operands[1]));
1047       src2_class = REGNO_REG_CLASS (true_regnum (operands[2]));
1048       dst_class = REGNO_REG_CLASS (true_regnum (operands[0]));
1050       /* If no extended registers are used, then the best way to handle
1051          this is to copy the first source operand into the destination
1052          and emit a two address subtraction.  */
1053       if (src1_class != EXTENDED_REGS
1054           && src2_class != EXTENDED_REGS
1055           && dst_class != EXTENDED_REGS
1056           && true_regnum (operands[0]) != true_regnum (operands[2]))
1057         return \"mov %1,%0\;sub %2,%0\";
1058       return \"sub %2,%1,%0\";
1059     }
1061   [(set_attr "cc" "set_zn")])
1063 (define_insn ""
1064   [(set (match_operand:SI 0 "register_operand" "=dax")
1065         (minus:SI (match_operand:SI 1 "register_operand" "0")
1066                   (match_operand:SI 2 "nonmemory_operand" "daxi")))]
1067   ""
1068   "sub %2,%0"
1069   [(set_attr "cc" "set_zn")])
1071 (define_expand "negsi2"
1072   [(set (match_operand:SI 0 "register_operand" "")
1073         (neg:SI (match_operand:SI 1 "register_operand" "")))]
1074   ""
1075   "
1077   rtx target = gen_reg_rtx (SImode);
1079   emit_move_insn (target, const0_rtx);
1080   emit_insn (gen_subsi3 (target, target, operands[1]));
1081   emit_move_insn (operands[0], target);
1082   DONE;
1085 ;; ----------------------------------------------------------------------
1086 ;; MULTIPLY INSTRUCTIONS
1087 ;; ----------------------------------------------------------------------
1089 (define_insn "mulsidi3"
1090   [(set (match_operand:DI 0 "register_operand" "=dax")
1091         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "dax"))
1092                  (sign_extend:DI (match_operand:SI 2 "register_operand" "dax"))))]
1093   "TARGET_AM33"
1094   "mul %1,%2,%H0,%L0"
1095   [(set_attr "cc" "set_zn")])
1097 (define_insn "umulsidi3"
1098   [(set (match_operand:DI 0 "register_operand" "=dax")
1099         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "dax"))
1100                  (zero_extend:DI (match_operand:SI 2 "register_operand" "dax"))))]
1101   "TARGET_AM33"
1102   "mulu %1,%2,%H0,%L0"
1103   [(set_attr "cc" "set_zn")])
1105 (define_expand "mulsi3"
1106   [(set (match_operand:SI 0 "register_operand" "")
1107         (mult:SI (match_operand:SI 1 "register_operand" "")
1108                  (match_operand:SI 2 "register_operand" "")))]
1109   ""
1110   "")
1112 (define_insn ""
1113   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1114         (mult:SI (match_operand:SI 1 "register_operand" "%0,0")
1115                  (match_operand:SI 2 "nonmemory_operand" "dx,daxi")))]
1116   "TARGET_AM33"
1117   "*
1119   if (TARGET_MULT_BUG)
1120     return \"nop\;nop\;mul %2,%0\";
1121   else
1122     return \"mul %2,%0\";
1124   [(set_attr "cc" "set_zn")])
1126 (define_insn ""
1127   [(set (match_operand:SI 0 "register_operand" "=dx")
1128         (mult:SI (match_operand:SI 1 "register_operand" "%0")
1129                  (match_operand:SI 2 "register_operand" "dx")))]
1130   ""
1131   "*
1133   if (TARGET_MULT_BUG)
1134     return \"nop\;nop\;mul %2,%0\";
1135   else
1136     return \"mul %2,%0\";
1138   [(set_attr "cc" "set_zn")])
1140 (define_insn "udivmodsi4"
1141   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx")
1142         (udiv:SI (match_operand:SI 1 "general_operand" "0")
1143                  (match_operand:SI 2 "general_operand" "dx")))
1144    (set (match_operand:SI 3 "nonimmediate_operand" "=&d")
1145         (umod:SI (match_dup 1) (match_dup 2)))]
1146   ""
1147   "*
1149   output_asm_insn (\"sub %3,%3\;mov %3,mdr\", operands);
1151   if (find_reg_note (insn, REG_UNUSED, operands[3]))
1152     return \"divu %2,%0\";
1153   else
1154     return \"divu %2,%0\;mov mdr,%3\";
1156   [(set_attr "cc" "set_zn")])
1158 (define_insn "divmodsi4"
1159   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx")
1160         (div:SI (match_operand:SI 1 "general_operand" "0")
1161                  (match_operand:SI 2 "general_operand" "dx")))
1162    (set (match_operand:SI 3 "nonimmediate_operand" "=d")
1163         (mod:SI (match_dup 1) (match_dup 2)))]
1164   ""
1165   "*
1167   if (find_reg_note (insn, REG_UNUSED, operands[3]))
1168     return \"ext %0\;div %2,%0\";
1169   else
1170     return \"ext %0\;div %2,%0\;mov mdr,%3\";
1172   [(set_attr "cc" "set_zn")])
1175 ;; ----------------------------------------------------------------------
1176 ;; AND INSTRUCTIONS
1177 ;; ----------------------------------------------------------------------
1179 (define_expand "andsi3"
1180   [(set (match_operand:SI 0 "register_operand" "")
1181         (and:SI (match_operand:SI 1 "register_operand" "")
1182                 (match_operand:SI 2 "nonmemory_operand" "")))]
1183   ""
1184   "")
1186 (define_insn ""
1187   [(set (match_operand:SI 0 "register_operand" "=dx,dx,!dax")
1188         (and:SI (match_operand:SI 1 "register_operand" "%0,0,dax")
1189                 (match_operand:SI 2 "nonmemory_operand" "N,dxi,dax")))]
1190   "TARGET_AM33"
1191   "*
1193   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff)
1194     return \"extbu %0\";
1195   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xffff)
1196     return \"exthu %0\";
1197   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x7fffffff)
1198     return \"add %0,%0\;lsr 1,%0\";
1199   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x3fffffff)
1200     return \"asl2 %0\;lsr 2,%0\";
1201   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x1fffffff)
1202     return \"add %0,%0\;asl2 %0\;lsr 3,%0\";
1203   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x0fffffff)
1204     return \"asl2 %0\;asl2 %0\;lsr 4,%0\";
1205   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffe)
1206     return \"lsr 1,%0\;add %0,%0\";
1207   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffc)
1208     return \"lsr 2,%0\;asl2 %0\";
1209   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff8)
1210     return \"lsr 3,%0\;add %0,%0\;asl2 %0\";
1211   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff0)
1212     return \"lsr 4,%0\;asl2 %0\;asl2 %0\";
1213   if (REG_P (operands[2]) && REG_P (operands[1])
1214       && true_regnum (operands[0]) != true_regnum (operands[1])
1215       && true_regnum (operands[0]) != true_regnum (operands[2])
1216       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1217       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1218       && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
1219     return \"mov %1,%0\;and %2,%0\";
1220   if (REG_P (operands[2]) && REG_P (operands[1])
1221       && true_regnum (operands[0]) != true_regnum (operands[1])
1222       && true_regnum (operands[0]) != true_regnum (operands[2]))
1223     return \"and %1,%2,%0\";
1224   if (REG_P (operands[2]) && REG_P (operands[0])
1225       && true_regnum (operands[2]) == true_regnum (operands[0]))
1226     return \"and %1,%0\";
1227   return \"and %2,%0\";
1229   [(set (attr "cc")
1230         (cond
1231          [
1232          (eq (symbol_ref "which_alternative") (const_int 0)
1233              ) (const_string "none_0hit")
1234          (ne (symbol_ref "GET_CODE (operands[2]) == CONST_INT
1235                           && (INTVAL (operands[2]) == 0x7fffffff
1236                               || INTVAL (operands[2]) == 0x3fffffff
1237                               || INTVAL (operands[2]) == 0x1fffffff
1238                               || INTVAL (operands[2]) == 0x0fffffff
1239                               || INTVAL (operands[2]) == 0xfffffffe
1240                               || INTVAL (operands[2]) == 0xfffffffc
1241                               || INTVAL (operands[2]) == 0xfffffff8
1242                               || INTVAL (operands[2]) == 0xfffffff0)")
1243              (const_int 0)) (const_string "set_zn")
1244           ] (const_string "set_znv")))])
1246 (define_insn ""
1247   [(set (match_operand:SI 0 "register_operand" "=dx,dx")
1248         (and:SI (match_operand:SI 1 "register_operand" "%0,0")
1249                 (match_operand:SI 2 "nonmemory_operand" "N,dxi")))]
1250   ""
1251   "*
1253   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff)
1254     return \"extbu %0\";
1255   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xffff)
1256     return \"exthu %0\";
1257   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x7fffffff)
1258     return \"add %0,%0\;lsr 1,%0\";
1259   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x3fffffff)
1260     return \"asl2 %0\;lsr 2,%0\";
1261   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x1fffffff)
1262     return \"add %0,%0\;asl2 %0\;lsr 3,%0\";
1263   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x0fffffff)
1264     return \"asl2 %0\;asl2 %0\;lsr 4,%0\";
1265   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffe)
1266     return \"lsr 1,%0\;add %0,%0\";
1267   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffc)
1268     return \"lsr 2,%0\;asl2 %0\";
1269   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff8)
1270     return \"lsr 3,%0\;add %0,%0\;asl2 %0\";
1271   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff0)
1272     return \"lsr 4,%0\;asl2 %0\;asl2 %0\";
1273   return \"and %2,%0\";
1275   [(set (attr "cc")
1276         (cond
1277          [
1278          (eq (symbol_ref "which_alternative") (const_int 0)
1279              ) (const_string "none_0hit")
1280          ;; Shifts don't set the V flag, but bitwise operations clear
1281          ;; it (which correctly reflects the absence of overflow in a
1282          ;; compare-with-zero that might follow).  As for the
1283          ;; 0xfffffffe case, the add may overflow, so we can't use the
1284          ;; V flag.
1285          (ne (symbol_ref "GET_CODE (operands[2]) == CONST_INT
1286                           && (INTVAL (operands[2]) == 0x7fffffff
1287                               || INTVAL (operands[2]) == 0x3fffffff
1288                               || INTVAL (operands[2]) == 0x1fffffff
1289                               || INTVAL (operands[2]) == 0x0fffffff
1290                               || INTVAL (operands[2]) == 0xfffffffe
1291                               || INTVAL (operands[2]) == 0xfffffffc
1292                               || INTVAL (operands[2]) == 0xfffffff8
1293                               || INTVAL (operands[2]) == 0xfffffff0)")
1294              (const_int 0)) (const_string "set_zn")
1295           ] (const_string "set_znv")))])
1297 ;; ----------------------------------------------------------------------
1298 ;; OR INSTRUCTIONS
1299 ;; ----------------------------------------------------------------------
1301 (define_expand "iorsi3"
1302   [(set (match_operand:SI 0 "register_operand" "")
1303         (ior:SI (match_operand:SI 1 "register_operand" "")
1304                 (match_operand:SI 2 "nonmemory_operand" "")))]
1305   ""
1306   "")
1308 (define_insn ""
1309   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1310         (ior:SI (match_operand:SI 1 "register_operand" "%0,dax")
1311                 (match_operand:SI 2 "nonmemory_operand" "dxi,dax")))]
1312   "TARGET_AM33"
1313   "*
1315   if (REG_P (operands[2]) && REG_P (operands[1])
1316       && true_regnum (operands[0]) != true_regnum (operands[1])
1317       && true_regnum (operands[0]) != true_regnum (operands[2])
1318       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1319       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1320       && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
1321     return \"mov %1,%0\;or %2,%0\";
1322   if (REG_P (operands[2]) && REG_P (operands[1])
1323       && true_regnum (operands[0]) != true_regnum (operands[1])
1324       && true_regnum (operands[0]) != true_regnum (operands[2]))
1325     return \"or %1,%2,%0\";
1326   if (REG_P (operands[2]) && REG_P (operands[0])
1327       && true_regnum (operands[2]) == true_regnum (operands[0]))
1328     return \"or %1,%0\";
1329   return \"or %2,%0\";
1331   [(set_attr "cc" "set_znv")])
1333 (define_insn ""
1334   [(set (match_operand:SI 0 "register_operand" "=dx")
1335         (ior:SI (match_operand:SI 1 "register_operand" "%0")
1336                 (match_operand:SI 2 "nonmemory_operand" "dxi")))]
1337   ""
1338   "or %2,%0"
1339   [(set_attr "cc" "set_znv")])
1341 ;; ----------------------------------------------------------------------
1342 ;; XOR INSTRUCTIONS
1343 ;; ----------------------------------------------------------------------
1345 (define_expand "xorsi3"
1346   [(set (match_operand:SI 0 "register_operand" "")
1347         (xor:SI (match_operand:SI 1 "register_operand" "")
1348                 (match_operand:SI 2 "nonmemory_operand" "")))]
1349   ""
1350   "")
1352 (define_insn ""
1353   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1354         (xor:SI (match_operand:SI 1 "register_operand" "%0,dax")
1355                 (match_operand:SI 2 "nonmemory_operand" "dxi,dax")))]
1356   "TARGET_AM33"
1357   "*
1359   if (REG_P (operands[2]) && REG_P (operands[1])
1360       && true_regnum (operands[0]) != true_regnum (operands[1])
1361       && true_regnum (operands[0]) != true_regnum (operands[2])
1362       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1363       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1364       && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
1365     return \"mov %1,%0\;xor %2,%0\";
1366   if (REG_P (operands[2]) && REG_P (operands[1])
1367       && true_regnum (operands[0]) != true_regnum (operands[1])
1368       && true_regnum (operands[0]) != true_regnum (operands[2]))
1369     return \"xor %1,%2,%0\";
1370   if (REG_P (operands[2]) && REG_P (operands[0])
1371       && true_regnum (operands[2]) == true_regnum (operands[0]))
1372     return \"xor %1,%0\";
1373   return \"xor %2,%0\";
1375   [(set_attr "cc" "set_znv")])
1377 (define_insn ""
1378   [(set (match_operand:SI 0 "register_operand" "=dx")
1379         (xor:SI (match_operand:SI 1 "register_operand" "%0")
1380                 (match_operand:SI 2 "nonmemory_operand" "dxi")))]
1381   ""
1382   "xor %2,%0"
1383   [(set_attr "cc" "set_znv")])
1385 ;; ----------------------------------------------------------------------
1386 ;; NOT INSTRUCTIONS
1387 ;; ----------------------------------------------------------------------
1389 (define_expand "one_cmplsi2"
1390   [(set (match_operand:SI 0 "register_operand" "")
1391         (not:SI (match_operand:SI 1 "register_operand" "")))]
1392   ""
1393   "")
1395 (define_insn ""
1396   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1397         (not:SI (match_operand:SI 1 "register_operand" "0,0")))]
1398   "TARGET_AM33"
1399   "not %0"
1400   [(set_attr "cc" "set_znv")])
1402 (define_insn ""
1403   [(set (match_operand:SI 0 "register_operand" "=dx")
1404         (not:SI (match_operand:SI 1 "register_operand" "0")))]
1405   ""
1406   "not %0"
1407   [(set_attr "cc" "set_znv")])
1409 ;; -----------------------------------------------------------------
1410 ;; BIT FIELDS
1411 ;; -----------------------------------------------------------------
1414 ;; These set/clear memory in byte sized chunks.
1416 ;; They are no smaller/faster than loading the value into a register
1417 ;; and storing the register, but they don't need a scratch register
1418 ;; which may allow for better code generation.
1419 (define_insn ""
1420   [(set (match_operand:QI 0 "nonimmediate_operand" "=R,d") (const_int 0))]
1421   ""
1422   "@
1423   bclr 255,%A0
1424   clr %0"
1425   [(set_attr "cc" "clobber")])
1427 (define_insn ""
1428   [(set (match_operand:QI 0 "nonimmediate_operand" "=R,d") (const_int -1))]
1429   ""
1430   "@
1431   bset 255,%A0
1432   mov -1,%0"
1433   [(set_attr "cc" "clobber,none_0hit")])
1435 (define_insn ""
1436   [(set (match_operand:QI 0 "nonimmediate_operand" "+R,d")
1437         (subreg:QI
1438           (and:SI (subreg:SI (match_dup 0) 0)
1439                   (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
1440   ""
1441   "@
1442   bclr %N1,%A0
1443   and %1,%0"
1444   [(set_attr "cc" "clobber,set_znv")])
1446 (define_insn ""
1447   [(set (match_operand:QI 0 "memory_operand" "=R,T")
1448         (and:QI
1449          (match_dup 0)
1450          (not:QI (match_operand:QI 1 "nonmemory_operand" "i,d"))))]
1451   ""
1452   "@
1453   bclr %U1,%A0
1454   bclr %1,%0"
1455   [(set_attr "cc" "clobber,clobber")])
1457 (define_insn ""
1458   [(set (match_operand:QI 0 "nonimmediate_operand" "+R,d")
1459         (subreg:QI
1460           (ior:SI (subreg:SI (match_dup 0) 0)
1461                   (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
1462   ""
1463   "@
1464   bset %U1,%A0
1465   or %1,%0"
1466   [(set_attr "cc" "clobber,set_znv")])
1468 (define_expand "iorqi3"
1469   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1470         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
1471                 (match_operand:QI 2 "nonmemory_operand" "")))]
1472   ""
1473   "")
1475 (define_insn ""
1476   [(set (match_operand:QI 0 "nonimmediate_operand" "=R,T,r")
1477         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
1478                 ;; This constraint should really be nonmemory_operand,
1479                 ;; but making it general_operand, along with the
1480                 ;; condition that not both input operands are MEMs, it
1481                 ;; here helps combine do a better job.
1482                 (match_operand:QI 2 "general_operand" "i,d,ir")))]
1483   "TARGET_AM33 &&
1484    (GET_CODE (operands[2]) != MEM || GET_CODE (operands[1]) != MEM)"
1485   "@
1486   bset %U2,%A0
1487   bset %2,%0
1488   or %2,%0"
1489   [(set_attr "cc" "clobber,clobber,set_znv")])
1491 (define_insn ""
1492   [(set (match_operand:QI 0 "nonimmediate_operand" "=R,T,d")
1493         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
1494                 ;; This constraint should really be nonmemory_operand,
1495                 ;; but making it general_operand, along with the
1496                 ;; condition that not both input operands are MEMs, it
1497                 ;; here helps combine do a better job.
1498                 (match_operand:QI 2 "general_operand" "i,d,id")))]
1499   "GET_CODE (operands[2]) != MEM || GET_CODE (operands[1]) != MEM"
1500   "@
1501   bset %U2,%A0
1502   bset %2,%0
1503   or %2,%0"
1504   [(set_attr "cc" "clobber,clobber,set_znv")])
1506 (define_insn ""
1507   [(set (cc0)
1508      (zero_extract:SI (match_operand:SI 0 "register_operand" "dx")
1509                       (match_operand 1 "const_int_operand" "")
1510                       (match_operand 2 "const_int_operand" "")))]
1511   ""
1512   "*
1514   int len = INTVAL (operands[1]);
1515   int bit = INTVAL (operands[2]);
1516   int mask = 0;
1517   rtx xoperands[2];
1519   while (len > 0)
1520     {
1521       mask |= (1 << bit);
1522       bit++;
1523       len--;
1524     }
1526   xoperands[0] = operands[0];
1527   xoperands[1] = GEN_INT (trunc_int_for_mode (mask, SImode));
1528   output_asm_insn (\"btst %1,%0\", xoperands);
1529   return \"\";
1531   [(set_attr "cc" "clobber")])
1533 (define_insn ""
1534   [(set (cc0)
1535      (zero_extract:SI (match_operand:QI 0 "general_operand" "R,dx")
1536                       (match_operand 1 "const_int_operand" "")
1537                       (match_operand 2 "const_int_operand" "")))]
1538   "mask_ok_for_mem_btst (INTVAL (operands[1]), INTVAL (operands[2]))"
1539   "*
1541   int len = INTVAL (operands[1]);
1542   int bit = INTVAL (operands[2]);
1543   int mask = 0;
1544   rtx xoperands[2];
1546   while (len > 0)
1547     {
1548       mask |= (1 << bit);
1549       bit++;
1550       len--;
1551     }
1553   /* If the source operand is not a reg (i.e. it is memory), then extract the
1554      bits from mask that we actually want to test.  Note that the mask will
1555      never cross a byte boundary.  */
1556   if (!REG_P (operands[0]))
1557     {
1558       if (mask & 0xff)
1559         mask = mask & 0xff;
1560       else if (mask & 0xff00)
1561         mask = (mask >> 8) & 0xff;
1562       else if (mask & 0xff0000)
1563         mask = (mask >> 16) & 0xff;
1564       else if (mask & 0xff000000)
1565         mask = (mask >> 24) & 0xff;
1566     }
1568   xoperands[0] = operands[0];
1569   xoperands[1] = GEN_INT (trunc_int_for_mode (mask, SImode));
1570   if (GET_CODE (operands[0]) == REG)
1571     output_asm_insn (\"btst %1,%0\", xoperands);
1572   else
1573     output_asm_insn (\"btst %U1,%A0\", xoperands);
1574   return \"\";
1576   [(set_attr "cc" "clobber")])
1578 (define_insn ""
1579   [(set (cc0) (and:SI (match_operand:SI 0 "register_operand" "dx")
1580                       (match_operand:SI 1 "const_int_operand" "")))]
1581   ""
1582   "btst %1,%0"
1583   [(set_attr "cc" "clobber")])
1585 (define_insn ""
1586   [(set (cc0)
1587      (and:SI
1588        (subreg:SI (match_operand:QI 0 "general_operand" "R,dx") 0)
1589        (match_operand:SI 1 "const_8bit_operand" "")))]
1590   ""
1591   "@
1592   btst %U1,%A0
1593   btst %1,%0"
1594   [(set_attr "cc" "clobber")])
1597 ;; ----------------------------------------------------------------------
1598 ;; JUMP INSTRUCTIONS
1599 ;; ----------------------------------------------------------------------
1601 ;; Conditional jump instructions
1603 (define_expand "ble"
1604   [(set (pc)
1605         (if_then_else (le (cc0)
1606                           (const_int 0))
1607                       (label_ref (match_operand 0 "" ""))
1608                       (pc)))]
1609   ""
1610   "")
1612 (define_expand "bleu"
1613   [(set (pc)
1614         (if_then_else (leu (cc0)
1615                            (const_int 0))
1616                       (label_ref (match_operand 0 "" ""))
1617                       (pc)))]
1618   ""
1619   "")
1621 (define_expand "bge"
1622   [(set (pc)
1623         (if_then_else (ge (cc0)
1624                           (const_int 0))
1625                       (label_ref (match_operand 0 "" ""))
1626                       (pc)))]
1627   ""
1628   "")
1630 (define_expand "bgeu"
1631   [(set (pc)
1632         (if_then_else (geu (cc0)
1633                            (const_int 0))
1634                       (label_ref (match_operand 0 "" ""))
1635                       (pc)))]
1636   ""
1637   "")
1639 (define_expand "blt"
1640   [(set (pc)
1641         (if_then_else (lt (cc0)
1642                           (const_int 0))
1643                       (label_ref (match_operand 0 "" ""))
1644                       (pc)))]
1645   ""
1646   "")
1648 (define_expand "bltu"
1649   [(set (pc)
1650         (if_then_else (ltu (cc0)
1651                            (const_int 0))
1652                       (label_ref (match_operand 0 "" ""))
1653                       (pc)))]
1654   ""
1655   "")
1657 (define_expand "bgt"
1658   [(set (pc)
1659         (if_then_else (gt (cc0)
1660                           (const_int 0))
1661                       (label_ref (match_operand 0 "" ""))
1662                       (pc)))]
1663   ""
1664   "")
1666 (define_expand "bgtu"
1667   [(set (pc)
1668         (if_then_else (gtu (cc0)
1669                            (const_int 0))
1670                       (label_ref (match_operand 0 "" ""))
1671                       (pc)))]
1672   ""
1673   "")
1675 (define_expand "beq"
1676   [(set (pc)
1677         (if_then_else (eq (cc0)
1678                           (const_int 0))
1679                       (label_ref (match_operand 0 "" ""))
1680                       (pc)))]
1681   ""
1682   "")
1684 (define_expand "bne"
1685   [(set (pc)
1686         (if_then_else (ne (cc0)
1687                           (const_int 0))
1688                       (label_ref (match_operand 0 "" ""))
1689                       (pc)))]
1690   ""
1691   "")
1693 (define_insn ""
1694   [(set (pc)
1695         (if_then_else (match_operator 1 "comparison_operator"
1696                                       [(cc0) (const_int 0)])
1697                       (label_ref (match_operand 0 "" ""))
1698                       (pc)))]
1699   ""
1700   "*
1702   if (cc_status.mdep.fpCC)
1703     return \"fb%b1 %0\";
1704   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1705       && (GET_CODE (operands[1]) == GT
1706           || GET_CODE (operands[1]) == GE
1707           || GET_CODE (operands[1]) == LE
1708           || GET_CODE (operands[1]) == LT))
1709     return 0;
1710   return \"b%b1 %0\";
1712  [(set_attr "cc" "none")])
1714 (define_insn ""
1715   [(set (pc)
1716         (if_then_else (match_operator 1 "comparison_operator"
1717                                       [(cc0) (const_int 0)])
1718                       (pc)
1719                       (label_ref (match_operand 0 "" ""))))]
1720   ""
1721   "*
1723   if (cc_status.mdep.fpCC)
1724     return \"fb%B1 %0\";
1725   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1726       && (GET_CODE (operands[1]) == GT
1727           || GET_CODE (operands[1]) == GE
1728           || GET_CODE (operands[1]) == LE
1729           || GET_CODE (operands[1]) == LT))
1730     return 0;
1731   return \"b%B1 %0\";
1733  [(set_attr "cc" "none")])
1735 ;; Unconditional and other jump instructions.
1737 (define_insn "jump"
1738   [(set (pc)
1739         (label_ref (match_operand 0 "" "")))]
1740   ""
1741   "jmp %l0"
1742  [(set_attr "cc" "none")])
1744 (define_insn "indirect_jump"
1745   [(set (pc) (match_operand:SI 0 "register_operand" "a"))]
1746   ""
1747   "jmp (%0)"
1748   [(set_attr "cc" "none")])
1750 (define_expand "builtin_setjmp_receiver"
1751   [(match_operand 0 "" "")]
1752   "flag_pic"
1753   "
1755   if (flag_pic)
1756     emit_insn (gen_GOTaddr2picreg ());
1758   DONE;
1761 (define_expand "casesi"
1762   [(match_operand:SI 0 "register_operand" "")
1763    (match_operand:SI 1 "immediate_operand" "")
1764    (match_operand:SI 2 "immediate_operand" "")
1765    (match_operand 3 "" "") (match_operand 4 "" "")]
1766   ""
1767   "
1769   rtx table = gen_reg_rtx (SImode);
1770   rtx index = gen_reg_rtx (SImode);
1771   rtx addr = gen_reg_rtx (Pmode);
1773   emit_move_insn (table, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
1774   emit_move_insn (index, plus_constant (operands[0], - INTVAL (operands[1])));
1775   emit_insn (gen_cmpsi (index, operands[2]));
1776   emit_jump_insn (gen_bgtu (operands[4]));
1777   emit_move_insn (index, gen_rtx_ASHIFT (SImode, index, const2_rtx));
1778   emit_move_insn (addr, gen_rtx_MEM (SImode,
1779                                      gen_rtx_PLUS (SImode, table, index)));
1780   if (flag_pic)
1781     emit_move_insn (addr, gen_rtx_PLUS (SImode, addr, table));
1783   emit_jump_insn (gen_tablejump (addr, operands[3]));
1784   DONE;
1787 (define_insn "tablejump"
1788   [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1789    (use (label_ref (match_operand 1 "" "")))]
1790   ""
1791   "jmp (%0)"
1792   [(set_attr "cc" "none")])
1794 ;; Call subroutine with no return value.
1796 (define_expand "call"
1797   [(call (match_operand:QI 0 "general_operand" "")
1798          (match_operand:SI 1 "general_operand" ""))]
1799   ""
1800   "
1802   if (flag_pic && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
1803     {
1804       if (MN10300_GLOBAL_P (XEXP (operands[0], 0)))
1805         {
1806           /* The PLT code won't run on AM30, but then, there's no
1807              shared library support for AM30 either, so we just assume
1808              the linker is going to adjust all @PLT relocs to the
1809              actual symbols.  */
1810           emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
1811           XEXP (operands[0], 0) = gen_sym2PLT (XEXP (operands[0], 0));
1812         }
1813       else
1814         XEXP (operands[0], 0) = gen_sym2PIC (XEXP (operands[0], 0));
1815     }
1816   if (! call_address_operand (XEXP (operands[0], 0), VOIDmode))
1817     XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
1818   emit_call_insn (gen_call_internal (XEXP (operands[0], 0), operands[1]));
1819   DONE;
1822 ;; NB: Mode on match_operand 0 deliberately omitted in
1823 ;;     order to be able to match UNSPECs in PIC mode.
1824 (define_insn "call_internal"
1825   [(call (mem:QI (match_operand 0 "call_address_operand" "aS"))
1826          (match_operand:SI 1 "general_operand" "g"))]
1827   ""
1828   "*
1830   if (REG_P (operands[0]))
1831     return \"calls %C0\";
1832   else
1833     return \"call %C0,[],0\";
1835   [(set_attr "cc" "clobber")])
1837 ;; Call subroutine, returning value in operand 0
1838 ;; (which must be a hard register).
1840 (define_expand "call_value"
1841   [(set (match_operand 0 "" "")
1842         (call (match_operand:QI 1 "general_operand" "")
1843               (match_operand:SI 2 "general_operand" "")))]
1844   ""
1845   "
1847   if (flag_pic && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
1848     {
1849       if (MN10300_GLOBAL_P (XEXP (operands[1], 0)))
1850         {
1851           /* The PLT code won't run on AM30, but then, there's no
1852              shared library support for AM30 either, so we just assume
1853              the linker is going to adjust all @PLT relocs to the
1854              actual symbols.  */
1855           emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
1856           XEXP (operands[1], 0) = gen_sym2PLT (XEXP (operands[1], 0));
1857         }
1858       else
1859         XEXP (operands[1], 0) = gen_sym2PIC (XEXP (operands[1], 0));
1860     }
1861   if (! call_address_operand (XEXP (operands[1], 0), VOIDmode))
1862     XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
1863   emit_call_insn (gen_call_value_internal (operands[0],
1864                                            XEXP (operands[1], 0),
1865                                            operands[2]));
1866   DONE;
1869 ;; NB: Mode on match_operands 0 and 1 deliberately omitted
1870 ;;     in order to be able to match UNSPECs in PIC mode.
1871 (define_insn "call_value_internal"
1872   [(set (match_operand               0 "register_operand" "=dax")
1873         (call (mem:QI (match_operand 1 "call_address_operand" "aS"))
1874               (match_operand:SI      2 "general_operand" "g")))]
1875   ""
1876   "*
1878   if (REG_P (operands[1]))
1879     return \"calls %C1\";
1880   else
1881     return \"call %C1,[],0\";
1883   [(set_attr "cc" "clobber")])
1885 (define_expand "untyped_call"
1886   [(parallel [(call (match_operand 0 "" "")
1887                     (const_int 0))
1888               (match_operand 1 "" "")
1889               (match_operand 2 "" "")])]
1890   ""
1891   "
1893   int i;
1895   emit_call_insn (gen_call (operands[0], const0_rtx));
1897   for (i = 0; i < XVECLEN (operands[2], 0); i++)
1898     {
1899       rtx set = XVECEXP (operands[2], 0, i);
1900       emit_move_insn (SET_DEST (set), SET_SRC (set));
1901     }
1902   DONE;
1905 (define_insn "nop"
1906   [(const_int 0)]
1907   ""
1908   "nop"
1909   [(set_attr "cc" "none")])
1911 ;; ----------------------------------------------------------------------
1912 ;; EXTEND INSTRUCTIONS
1913 ;; ----------------------------------------------------------------------
1915 (define_expand "zero_extendqisi2"
1916   [(set (match_operand:SI 0 "general_operand" "")
1917         (zero_extend:SI
1918          (match_operand:QI 1 "general_operand" "")))]
1919   ""
1920   "")
1922 (define_insn ""
1923   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx,!dax,!dax,!dax")
1924         (zero_extend:SI
1925          (match_operand:QI 1 "general_operand" "0,dax,m,0,dax,m")))]
1926   "TARGET_AM33"
1927   "@
1928   extbu %0
1929   mov %1,%0\;extbu %0
1930   movbu %1,%0
1931   extbu %0
1932   mov %1,%0\;extbu %0
1933   movbu %1,%0"
1934   [(set_attr "cc" "none_0hit")])
1936 (define_insn ""
1937   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx")
1938         (zero_extend:SI
1939          (match_operand:QI 1 "general_operand" "0,d,m")))]
1940   ""
1941   "@
1942   extbu %0
1943   mov %1,%0\;extbu %0
1944   movbu %1,%0"
1945   [(set_attr "cc" "none_0hit")])
1947 (define_expand "zero_extendhisi2"
1948   [(set (match_operand:SI 0 "general_operand" "")
1949         (zero_extend:SI
1950          (match_operand:HI 1 "general_operand" "")))]
1951   ""
1952   "")
1954 (define_insn ""
1955   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx,!dax,!dax,!dax")
1956         (zero_extend:SI
1957          (match_operand:HI 1 "general_operand" "0,dax,m,0,dax,m")))]
1958   "TARGET_AM33"
1959   "@
1960   exthu %0
1961   mov %1,%0\;exthu %0
1962   movhu %1,%0
1963   exthu %0
1964   mov %1,%0\;exthu %0
1965   movhu %1,%0"
1966   [(set_attr "cc" "none_0hit")])
1968 (define_insn ""
1969   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx")
1970         (zero_extend:SI
1971          (match_operand:HI 1 "general_operand" "0,dx,m")))]
1972   ""
1973   "@
1974   exthu %0
1975   mov %1,%0\;exthu %0
1976   movhu %1,%0"
1977   [(set_attr "cc" "none_0hit")])
1979 ;;- sign extension instructions
1981 (define_expand "extendqisi2"
1982   [(set (match_operand:SI 0 "general_operand" "")
1983         (sign_extend:SI
1984          (match_operand:QI 1 "general_operand" "")))]
1985   ""
1986   "")
1988 (define_insn ""
1989   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,!dax,!dax")
1990         (sign_extend:SI
1991          (match_operand:QI 1 "general_operand" "0,dx,0,dax")))]
1992   "TARGET_AM33"
1993   "@
1994   extb %0
1995   mov %1,%0\;extb %0
1996   extb %0
1997   mov %1,%0\;extb %0"
1998   [(set_attr "cc" "none_0hit")])
2000 (define_insn ""
2001   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx")
2002         (sign_extend:SI
2003          (match_operand:QI 1 "general_operand" "0,dx")))]
2004   ""
2005   "@
2006   extb %0
2007   mov %1,%0\;extb %0"
2008   [(set_attr "cc" "none_0hit")])
2010 (define_expand "extendhisi2"
2011   [(set (match_operand:SI 0 "general_operand" "")
2012         (sign_extend:SI
2013          (match_operand:HI 1 "general_operand" "")))]
2014   ""
2015   "")
2017 (define_insn ""
2018   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,!dax,!dax")
2019         (sign_extend:SI
2020          (match_operand:HI 1 "general_operand" "0,dax,0,dax")))]
2021   "TARGET_AM33"
2022   "@
2023   exth %0
2024   mov %1,%0\;exth %0
2025   exth %0
2026   mov %1,%0\;exth %0"
2027   [(set_attr "cc" "none_0hit")])
2029 (define_insn ""
2030   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx")
2031         (sign_extend:SI
2032          (match_operand:HI 1 "general_operand" "0,dx")))]
2033   ""
2034   "@
2035   exth %0
2036   mov %1,%0\;exth %0"
2037   [(set_attr "cc" "none_0hit")])
2039 ;; ----------------------------------------------------------------------
2040 ;; SHIFTS
2041 ;; ----------------------------------------------------------------------
2043 (define_expand "ashlsi3"
2044   [(set (match_operand:SI 0 "register_operand" "")
2045         (ashift:SI
2046          (match_operand:SI 1 "register_operand" "")
2047          (match_operand:QI 2 "nonmemory_operand" "")))]
2048   ""
2049   "")
2051 (define_insn ""
2052   [(set (match_operand:SI 0 "register_operand" "=dax,dx,!dax")
2053         (ashift:SI
2054          (match_operand:SI 1 "register_operand" "0,0,dax")
2055          (match_operand:QI 2 "nonmemory_operand" "J,dxi,dax")))]
2056   "TARGET_AM33"
2057   "*
2059   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 1)
2060     return \"add %0,%0\";
2062   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 2)
2063     return \"asl2 %0\";
2065   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 3
2066       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS)
2067     return \"asl2 %0\;add %0,%0\";
2069   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 4
2070       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS)
2071     return \"asl2 %0\;asl2 %0\";
2073   if (true_regnum (operands[1]) == true_regnum (operands[0]))
2074     return \"asl %S2,%0\";
2076   if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
2077       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
2078       && true_regnum (operands[0]) != true_regnum (operands[2]))
2079     return \"mov %1,%0\;asl %S2,%0\";
2080   return \"asl %2,%1,%0\";
2082   [(set_attr "cc" "set_zn")])
2084 (define_insn ""
2085   [(set (match_operand:SI 0 "register_operand" "=dax,dx,dx,dx,dx")
2086         (ashift:SI
2087          (match_operand:SI 1 "register_operand" "0,0,0,0,0")
2088          (match_operand:QI 2 "nonmemory_operand" "J,K,M,L,dxi")))]
2089   ""
2090   "@
2091   add %0,%0
2092   asl2 %0
2093   asl2 %0\;add %0,%0
2094   asl2 %0\;asl2 %0
2095   asl %S2,%0"
2096   [(set_attr "cc" "set_zn")])
2098 (define_expand "lshrsi3"
2099   [(set (match_operand:SI 0 "register_operand" "")
2100         (lshiftrt:SI
2101          (match_operand:SI 1 "register_operand" "")
2102          (match_operand:QI 2 "nonmemory_operand" "")))]
2103   ""
2104   "")
2106 (define_insn ""
2107   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
2108         (lshiftrt:SI
2109          (match_operand:SI 1 "register_operand" "0,dax")
2110          (match_operand:QI 2 "nonmemory_operand" "dxi,dax")))]
2111   "TARGET_AM33"
2112   "*
2114   if (true_regnum (operands[1]) == true_regnum (operands[0]))
2115     return \"lsr %S2,%0\";
2117   if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
2118       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
2119       && true_regnum (operands[0]) != true_regnum (operands[2]))
2120     return \"mov %1,%0\;lsr %S2,%0\";
2121   return \"lsr %2,%1,%0\";
2123   [(set_attr "cc" "set_zn")])
2125 (define_insn ""
2126   [(set (match_operand:SI 0 "register_operand" "=dx")
2127         (lshiftrt:SI
2128          (match_operand:SI 1 "register_operand" "0")
2129          (match_operand:QI 2 "nonmemory_operand" "dxi")))]
2130   ""
2131   "lsr %S2,%0"
2132   [(set_attr "cc" "set_zn")])
2134 (define_expand "ashrsi3"
2135   [(set (match_operand:SI 0 "register_operand" "")
2136         (ashiftrt:SI
2137          (match_operand:SI 1 "register_operand" "")
2138          (match_operand:QI 2 "nonmemory_operand" "")))]
2139   ""
2140   "")
2142 (define_insn ""
2143   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
2144         (ashiftrt:SI
2145          (match_operand:SI 1 "register_operand" "0,dax")
2146          (match_operand:QI 2 "nonmemory_operand" "dxi,dax")))]
2147   "TARGET_AM33"
2148   "*
2150   if (true_regnum (operands[1]) == true_regnum (operands[0]))
2151     return \"asr %S2,%0\";
2153   if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
2154       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
2155       && true_regnum (operands[0]) != true_regnum (operands[2]))
2156     return \"mov %1,%0\;asr %S2,%0\";
2157   return \"asr %2,%1,%0\";
2159   [(set_attr "cc" "set_zn")])
2161 (define_insn ""
2162   [(set (match_operand:SI 0 "register_operand" "=dx")
2163         (ashiftrt:SI
2164          (match_operand:SI 1 "register_operand" "0")
2165          (match_operand:QI 2 "nonmemory_operand" "dxi")))]
2166   ""
2167   "asr %S2,%0"
2168   [(set_attr "cc" "set_zn")])
2170 ;; ----------------------------------------------------------------------
2171 ;; FP INSTRUCTIONS
2172 ;; ----------------------------------------------------------------------
2174 ;; The mn103 series does not have floating point instructions, but since
2175 ;; FP values are held in integer regs, we can clear the high bit easily
2176 ;; which gives us an efficient inline floating point absolute value.
2178 ;; Similarly for negation of a FP value.
2181 (define_expand "absdf2"
2182   [(set (match_operand:DF 0 "register_operand" "")
2183         (abs:DF (match_operand:DF 1 "register_operand" "")))]
2184   ""
2185   "
2187   rtx target, result, insns;
2189   start_sequence ();
2190   target = operand_subword (operands[0], 1, 1, DFmode);
2191   result = expand_binop (SImode, and_optab,
2192                          operand_subword_force (operands[1], 1, DFmode),
2193                          GEN_INT (0x7fffffff), target, 0, OPTAB_WIDEN);
2195   gcc_assert (result);
2197   if (result != target)
2198     emit_move_insn (result, target);
2200   emit_move_insn (operand_subword (operands[0], 0, 1, DFmode),
2201                   operand_subword_force (operands[1], 0, DFmode));
2203   insns = get_insns ();
2204   end_sequence ();
2206   emit_insn (insns);
2207   DONE;
2210 (define_expand "abssf2"
2211   [(set (match_operand:SF 0 "register_operand" "")
2212         (abs:SF (match_operand:SF 1 "register_operand" "")))]
2213   ""
2214   "
2216   rtx result;
2217   rtx target;
2219   if (TARGET_AM33_2)
2220     {
2221       emit_insn (gen_abssf2_am33_2 (operands[0], operands[1]));
2222       DONE;
2223     }
2225   target = operand_subword_force (operands[0], 0, SFmode);
2226   result = expand_binop (SImode, and_optab,
2227                          operand_subword_force (operands[1], 0, SFmode),
2228                          GEN_INT (0x7fffffff), target, 0, OPTAB_WIDEN);
2229   gcc_assert (result);
2231   if (result != target)
2232     emit_move_insn (result, target);
2234   /* Make a place for REG_EQUAL.  */
2235   emit_move_insn (operands[0], operands[0]);
2236   DONE;
2240 (define_insn "abssf2_am33_2"
2241   [(set (match_operand:SF 0 "register_operand" "=f,f")
2242         (abs:SF (match_operand:SF 1 "register_operand" "0,?f")))]
2243   "TARGET_AM33_2"
2244   "@
2245    fabs %0
2246    fabs %1, %0"
2247   [(set_attr "cc" "none_0hit")])
2249 (define_expand "negdf2"
2250   [(set (match_operand:DF 0 "register_operand" "")
2251         (neg:DF (match_operand:DF 1 "register_operand" "")))]
2252   ""
2253   "
2255   rtx target, result, insns;
2257   start_sequence ();
2258   target = operand_subword (operands[0], 1, 1, DFmode);
2259   result = expand_binop (SImode, xor_optab,
2260                          operand_subword_force (operands[1], 1, DFmode),
2261                          GEN_INT (trunc_int_for_mode (0x80000000, SImode)),
2262                          target, 0, OPTAB_WIDEN);
2264   gcc_assert (result);
2266   if (result != target)
2267     emit_move_insn (result, target);
2269   emit_move_insn (operand_subword (operands[0], 0, 1, DFmode),
2270                   operand_subword_force (operands[1], 0, DFmode));
2272   insns = get_insns ();
2273   end_sequence ();
2275   emit_insn (insns);
2276   DONE;
2279 (define_expand "negsf2"
2280   [(set (match_operand:SF 0 "register_operand" "")
2281         (neg:SF (match_operand:SF 1 "register_operand" "")))]
2282   ""
2283   "
2285   rtx result;
2286   rtx target;
2288   if (TARGET_AM33_2)
2289     {
2290       emit_insn (gen_negsf2_am33_2 (operands[0], operands[1]));
2291       DONE;
2292     }
2294   target = operand_subword_force (operands[0], 0, SFmode);
2295   result = expand_binop (SImode, xor_optab,
2296                          operand_subword_force (operands[1], 0, SFmode),
2297                          GEN_INT (trunc_int_for_mode (0x80000000, SImode)),
2298                          target, 0, OPTAB_WIDEN);
2299   gcc_assert (result);
2301   if (result != target)
2302     emit_move_insn (result, target);
2304   /* Make a place for REG_EQUAL.  */
2305   emit_move_insn (operands[0], operands[0]);
2306   DONE;
2309 (define_insn "negsf2_am33_2"
2310   [(set (match_operand:SF 0 "register_operand" "=f,f")
2311         (neg:SF (match_operand:SF 1 "register_operand" "0,?f")))]
2312   "TARGET_AM33_2"
2313   "@
2314    fneg %0
2315    fneg %1, %0"
2316   [(set_attr "cc" "none_0hit")])
2318 (define_expand "sqrtsf2"
2319   [(set (match_operand:SF 0 "register_operand" "")
2320         (sqrt:SF (match_operand:SF 1 "register_operand" "")))]
2321   "TARGET_AM33_2 && flag_unsafe_math_optimizations"
2322   "
2324   rtx scratch = gen_reg_rtx (SFmode);
2325   emit_insn (gen_rsqrtsf2 (scratch, operands[1], CONST1_RTX (SFmode)));
2326   emit_insn (gen_divsf3 (operands[0], force_reg (SFmode, CONST1_RTX (SFmode)),
2327                          scratch));
2328   DONE;
2331 (define_insn "rsqrtsf2"
2332   [(set (match_operand:SF 0 "register_operand" "=f,f")
2333         (div:SF (match_operand:SF 2 "const_1f_operand" "F,F")
2334                 (sqrt:SF (match_operand:SF 1 "register_operand" "0,?f"))))]
2335   "TARGET_AM33_2"
2336   "@
2337    frsqrt %0
2338    frsqrt %1, %0"
2339   [(set_attr "cc" "none_0hit")])
2341 (define_insn "addsf3"
2342   [(set (match_operand:SF 0 "register_operand" "=f,f")
2343         (plus:SF (match_operand:SF 1 "register_operand" "%0,f")
2344                  (match_operand:SF 2 "general_operand" "f,?fF")))]
2345   "TARGET_AM33_2"
2346   "@
2347    fadd %2, %0
2348    fadd %2, %1, %0"
2349   [(set_attr "cc" "none_0hit")])
2351 (define_insn "subsf3"
2352   [(set (match_operand:SF 0 "register_operand" "=f,f")
2353         (minus:SF (match_operand:SF 1 "register_operand" "0,f")
2354                   (match_operand:SF 2 "general_operand" "f,?fF")))]
2355   "TARGET_AM33_2"
2356   "@
2357    fsub %2, %0
2358    fsub %2, %1, %0"
2359   [(set_attr "cc" "none_0hit")])
2361 (define_insn "mulsf3"
2362   [(set (match_operand:SF 0 "register_operand" "=f,f")
2363         (mult:SF (match_operand:SF 1 "register_operand" "%0,f")
2364                  (match_operand:SF 2 "general_operand" "f,?fF")))]
2365   "TARGET_AM33_2"
2366   "@
2367    fmul %2, %0
2368    fmul %2, %1, %0"
2369   [(set_attr "cc" "none_0hit")])
2371 (define_insn "divsf3"
2372   [(set (match_operand:SF 0 "register_operand" "=f,f")
2373         (div:SF (match_operand:SF 1 "register_operand" "0,f")
2374                 (match_operand:SF 2 "general_operand" "f,?fF")))]
2375   "TARGET_AM33_2"
2376   "@
2377    fdiv %2, %0
2378    fdiv %2, %1, %0"
2379   [(set_attr "cc" "none_0hit")])
2381 (define_insn "fmaddsf4"
2382   [(set (match_operand:SF 0 "register_operand" "=A")
2383         (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
2384                           (match_operand:SF 2 "register_operand" "f"))
2385                  (match_operand:SF 3 "register_operand" "f")))]
2386   "TARGET_AM33_2"
2387   "fmadd %1, %2, %3, %0"
2388   [(set_attr "cc" "none_0hit")])
2390 (define_insn "fmsubsf4"
2391   [(set (match_operand:SF 0 "register_operand" "=A")
2392         (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
2393                            (match_operand:SF 2 "register_operand" "f"))
2394                   (match_operand:SF 3 "register_operand" "f")))]
2395   "TARGET_AM33_2"
2396   "fmsub %1, %2, %3, %0"
2397   [(set_attr "cc" "none_0hit")])
2399 (define_insn "fnmaddsf4"
2400   [(set (match_operand:SF 0 "register_operand" "=A")
2401         (minus:SF (match_operand:SF 3 "register_operand" "f")
2402                   (mult:SF (match_operand:SF 1 "register_operand" "%f")
2403                            (match_operand:SF 2 "register_operand" "f"))))]
2404   "TARGET_AM33_2"
2405   "fnmadd %1, %2, %3, %0"
2406   [(set_attr "cc" "none_0hit")])
2408 (define_insn "fnmsubsf4"
2409   [(set (match_operand:SF 0 "register_operand" "=A")
2410         (minus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
2411                                    (match_operand:SF 2 "register_operand" "f")))
2412                   (match_operand:SF 3 "register_operand" "f")))]
2413   "TARGET_AM33_2"
2414   "fnmsub %1, %2, %3, %0"
2415   [(set_attr "cc" "none_0hit")])
2418 ;; ----------------------------------------------------------------------
2419 ;; PROLOGUE/EPILOGUE
2420 ;; ----------------------------------------------------------------------
2421 (define_expand "prologue"
2422   [(const_int 0)]
2423   ""
2424   "expand_prologue (); DONE;")
2426 (define_expand "epilogue"
2427   [(return)]
2428   ""
2429   "
2431   expand_epilogue ();
2432   DONE;
2435 (define_insn "return_internal"
2436   [(const_int 2)
2437    (return)]
2438   ""
2439   "rets"
2440   [(set_attr "cc" "clobber")])
2442 ;; This insn restores the callee saved registers and does a return, it
2443 ;; can also deallocate stack space.
2444 (define_insn "return_internal_regs"
2445   [(const_int 0)
2446    (match_operand:SI 0  "const_int_operand" "i")
2447    (return)]
2448   ""
2449   "*
2451   fputs (\"\\tret \", asm_out_file);
2452   mn10300_print_reg_list (asm_out_file, mn10300_get_live_callee_saved_regs ());
2453   fprintf (asm_out_file, \",%d\\n\", (int) INTVAL (operands[0]));
2454   return \"\";
2456   [(set_attr "cc" "clobber")])
2458 ;; This instruction matches one generated by mn10300_gen_multiple_store()
2459 (define_insn "store_movm"
2460   [(match_parallel 0 "store_multiple_operation"
2461     [(set (reg:SI 9) (plus:SI (reg:SI 9) (match_operand 1 "" "")))])]
2462   ""
2463   "*
2465   fputs (\"\\tmovm \", asm_out_file);
2466   mn10300_print_reg_list (asm_out_file,
2467                           store_multiple_operation (operands[0], VOIDmode));
2468   fprintf (asm_out_file, \",(sp)\\n\");
2469   return \"\";
2471   [(set_attr "cc" "clobber")])
2473 (define_insn "return"
2474   [(return)]
2475   "can_use_return_insn ()"
2476   "*
2478   rtx next = next_active_insn (insn);
2480   if (next
2481       && GET_CODE (next) == JUMP_INSN
2482       && GET_CODE (PATTERN (next)) == RETURN)
2483     return \"\";
2484   else
2485     return \"rets\";
2487   [(set_attr "cc" "clobber")])
2489 ;; Try to combine consecutive updates of the stack pointer (or any
2490 ;; other register for that matter).
2491 (define_peephole
2492   [(set (match_operand:SI 0 "register_operand" "=dxay")
2493         (plus:SI (match_dup 0)
2494                  (match_operand 1 "const_int_operand" "")))
2495    (set (match_dup 0)
2496         (plus:SI (match_dup 0)
2497                  (match_operand 2 "const_int_operand" "")))]
2498   ""
2499   "*
2501   operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]));
2502   return \"add %1,%0\";
2504   [(set_attr "cc" "clobber")])
2507 ;; We had patterns to check eq/ne, but the they don't work because
2508 ;; 0x80000000 + 0x80000000 = 0x0 with a carry out.
2510 ;; The Z flag and C flag would be set, and we have no way to
2511 ;; check for the Z flag set and C flag clear.
2513 ;; This will work on the mn10200 because we can check the ZX flag
2514 ;; if the comparison is in HImode.
2515 (define_peephole
2516   [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2517    (set (pc) (if_then_else (ge (cc0) (const_int 0))
2518                            (match_operand 1 "" "")
2519                            (pc)))]
2520   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2521   "add %0,%0\;bcc %1"
2522   [(set_attr "cc" "clobber")])
2524 (define_peephole
2525   [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2526    (set (pc) (if_then_else (lt (cc0) (const_int 0))
2527                            (match_operand 1 "" "")
2528                            (pc)))]
2529   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2530   "add %0,%0\;bcs %1"
2531   [(set_attr "cc" "clobber")])
2533 (define_peephole
2534   [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2535    (set (pc) (if_then_else (ge (cc0) (const_int 0))
2536                            (pc)
2537                            (match_operand 1 "" "")))]
2538   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2539   "add %0,%0\;bcs %1"
2540   [(set_attr "cc" "clobber")])
2542 (define_peephole
2543   [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2544    (set (pc) (if_then_else (lt (cc0) (const_int 0))
2545                            (pc)
2546                            (match_operand 1 "" "")))]
2547   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2548   "add %0,%0\;bcc %1"
2549   [(set_attr "cc" "clobber")])
2551 (define_expand "int_label"
2552   [(unspec [(match_operand:SI 0 "" "")] UNSPEC_INT_LABEL)]
2553   "" "")
2555 (define_expand "GOTaddr2picreg"
2556   [(match_dup 0)]
2557   "" "
2559   /* It would be nice to be able to have int_label keep track of the
2560      counter and all, but if we add C code to it, we'll get an insn
2561      back, and we just want the pattern.  */
2562   operands[0] = gen_int_label (GEN_INT (mn10300_unspec_int_label_counter++));
2563   if (TARGET_AM33)
2564     emit_insn (gen_am33_loadPC (operands[0]));
2565   else
2566     emit_insn (gen_mn10300_loadPC (operands[0]));
2567   emit_insn (gen_add_GOT_to_pic_reg (copy_rtx (operands[0])));
2568   DONE;
2572 (define_insn "am33_loadPC"
2573   [(parallel
2574     [(set (reg:SI PIC_REG) (pc))
2575      (use (match_operand 0 "" ""))])]
2576   "TARGET_AM33"
2577   "%0:\;mov pc,a2")
2580 (define_insn_and_split "mn10300_loadPC"
2581   [(parallel
2582     [(set (reg:SI PIC_REG) (pc))
2583      (use (match_operand 0 "" ""))])]
2584   ""
2585   "#"
2586   "reload_completed"
2587   [(match_operand 0 "" "")]
2588   "
2590   rtx sp_reg = gen_rtx_REG (SImode, SP_REG);
2591   int need_stack_space = (get_frame_size () == 0
2592                           && crtl->outgoing_args_size == 0);
2594   if (need_stack_space)
2595     emit_move_insn (sp_reg, plus_constant (sp_reg, -4));
2597   emit_insn (gen_call_next_insn (operands[0]));
2599   if (need_stack_space)
2600     emit_insn (gen_pop_pic_reg ());
2601   else
2602     emit_move_insn (pic_offset_table_rtx, gen_rtx_MEM (SImode, sp_reg));
2604   DONE;
2607 (define_insn "call_next_insn"
2608   [(parallel
2609     [(set (mem:SI (reg:SI SP_REG)) (pc))
2610      (use (match_operand 0 "" ""))])]
2611   "reload_completed"
2612   "calls %0\;%0:")
2614 (define_expand "add_GOT_to_pic_reg"
2615   [(set (reg:SI PIC_REG)
2616         (plus:SI
2617          (reg:SI PIC_REG)
2618          (const
2619           (unspec [(minus:SI
2620                     (match_dup 1)
2621                     (const (minus:SI
2622                             (const (match_operand:SI 0 "" ""))
2623                             (pc))))
2624                   ] UNSPEC_PIC))))]
2625   ""
2626   "
2628   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
2631 (define_expand "symGOT2reg"
2632   [(match_operand:SI 0 "" "")
2633    (match_operand:SI 1 "" "")]
2634   ""
2635   "
2637   rtx insn = emit_insn (gen_symGOT2reg_i (operands[0], operands[1]));
2639   MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
2641   set_unique_reg_note (insn, REG_EQUAL, operands[1]);
2643   DONE;
2646 (define_expand "symGOT2reg_i"
2647   [(set (match_operand:SI 0 "" "")
2648         (mem:SI (plus:SI (reg:SI PIC_REG)
2649                          (const (unspec [(match_operand:SI 1 "" "")]
2650                                         UNSPEC_GOT)))))]
2651   ""
2652   "")
2654 (define_expand "symGOTOFF2reg"
2655   [(match_operand:SI 0 "" "") (match_operand:SI 1 "" "")]
2656   ""
2657   "
2659   rtx insn = emit_insn (gen_symGOTOFF2reg_i (operands[0], operands[1]));
2661   set_unique_reg_note (insn, REG_EQUAL, operands[1]);
2663   DONE;
2666 (define_expand "symGOTOFF2reg_i"
2667   [(set (match_operand:SI 0 "" "")
2668         (const (unspec [(match_operand:SI 1 "" "")] UNSPEC_GOTOFF)))
2669   (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI PIC_REG)))]
2670   ""
2671   "")
2673 (define_expand "sym2PIC"
2674   [(unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC)]
2675   "" "")
2677 (define_expand "sym2PLT"
2678   [(unspec [(match_operand:SI 0 "" "")] UNSPEC_PLT)]
2679   "" "")