Merge from trunk @ 138209
[official-gcc.git] / gcc / config / mn10300 / mn10300.md
blob8fbbdc87df5a06b0155cbdd2a05d662a1c07461f
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*a,d,m")
119         (match_operand:QI 1 "general_operand" "0,I,i,i,da,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     case 3:
132     case 4:
133       if (GET_CODE (operands[1]) == CONST_DOUBLE)
134         {
135           rtx xoperands[2];
136           xoperands[0] = operands[0];
137           xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
138           output_asm_insn (\"mov %1,%0\", xoperands);
139           return \"\";
140         }
142       return \"mov %1,%0\";
143     case 5:
144     case 6:
145       return \"movbu %1,%0\";
146     default:
147       gcc_unreachable ();
148     }
150   [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
152 ;; movhi
154 (define_expand "movhi"
155   [(set (match_operand:HI 0 "general_operand" "")
156         (match_operand:HI 1 "general_operand" ""))]
157   ""
158   "
160   /* One of the ops has to be in a register */
161   if (!register_operand (operand1, HImode)
162       && !register_operand (operand0, HImode))
163     operands[1] = copy_to_mode_reg (HImode, operand1);
166 (define_insn ""
167   [(set (match_operand:HI 0 "nonimmediate_operand" "=d*x*a*f,d*x,d*x*a,d*x*a,m,*f,d*x*a")
168         (match_operand:HI 1 "general_operand" "0,I,d*x*ai,m,d*x*a,d*x*a*f,*f"))]
169   "TARGET_AM33
170    && (register_operand (operands[0], HImode)
171        || register_operand (operands[1], HImode))"
172   "*
174   switch (which_alternative)
175     {
176     case 0:
177       return \"nop\";
178     case 1:
179       return \"clr %0\";
180     case 2:
181       if (GET_CODE (operands[1]) == CONST_DOUBLE)
182         {
183           rtx xoperands[2];
184           xoperands[0] = operands[0];
185           xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
186           output_asm_insn (\"mov %1,%0\", xoperands);
187           return \"\";
188         }
190       if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
191           && GET_CODE (operands[1]) == CONST_INT)
192         {
193           HOST_WIDE_INT val = INTVAL (operands[1]);
195           if (((val & 0x80) && ! (val & 0xffffff00))
196               || ((val & 0x800000) && ! (val & 0xff000000)))
197             return \"movu %1,%0\";
198         }
199       return \"mov %1,%0\";
200     case 3:
201     case 4:
202       return \"movhu %1,%0\";
203     case 5:
204     case 6:
205       return \"fmov %1,%0\";
206     default:
207       gcc_unreachable ();
208     }
210   [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
212 (define_insn ""
213   [(set (match_operand:HI 0 "nonimmediate_operand" "=d*a,d,d,!*a,d*a,d,m")
214         (match_operand:HI 1 "general_operand" "0,I,i,i,da,m,d"))]
215   "register_operand (operands[0], HImode)
216    || register_operand (operands[1], HImode)"
217   "*
219   switch (which_alternative)
220     {
221     case 0:
222       return \"nop\";
223     case 1:
224       return \"clr %0\";
225     case 2:
226     case 3:
227     case 4:
228       if (GET_CODE (operands[1]) == CONST_DOUBLE)
229         {
230           rtx xoperands[2];
231           xoperands[0] = operands[0];
232           xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
233           output_asm_insn (\"mov %1,%0\", xoperands);
234           return \"\";
235         }
236       return \"mov %1,%0\";
237     case 5:
238     case 6:
239       return \"movhu %1,%0\";
240     default:
241       gcc_unreachable ();
242     }
244   [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
246 ;; movsi and helpers
248 ;; We use this to handle addition of two values when one operand is the
249 ;; stack pointer and the other is a memory reference of some kind.  Reload
250 ;; does not handle them correctly without this expander.
251 (define_expand "reload_insi"
252   [(set (match_operand:SI 0 "register_operand" "=a")
253         (match_operand:SI 1 "impossible_plus_operand" ""))
254    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
255   ""
256   "
258   if (XEXP (operands[1], 0) == stack_pointer_rtx)
259     {
260       if (GET_CODE (XEXP (operands[1], 1)) == SUBREG
261           && (GET_MODE_SIZE (GET_MODE (XEXP (operands[1], 1)))
262               > GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (operands[1], 1))))))
263         emit_move_insn (operands[2],
264                         gen_rtx_ZERO_EXTEND
265                         (GET_MODE (XEXP (operands[1], 1)),
266                          SUBREG_REG (XEXP (operands[1], 1))));
267       else
268         emit_move_insn (operands[2], XEXP (operands[1], 1));
269       emit_move_insn (operands[0], XEXP (operands[1], 0));
270     }
271   else
272     {
273       if (GET_CODE (XEXP (operands[1], 0)) == SUBREG
274           && (GET_MODE_SIZE (GET_MODE (XEXP (operands[1], 0)))
275               > GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (operands[1], 0))))))
276         emit_move_insn (operands[2],
277                         gen_rtx_ZERO_EXTEND
278                         (GET_MODE (XEXP (operands[1], 0)),
279                          SUBREG_REG (XEXP (operands[1], 0))));
280       else
281         emit_move_insn (operands[2], XEXP (operands[1], 0));
282       emit_move_insn (operands[0], XEXP (operands[1], 1));
283     }
284   emit_insn (gen_addsi3 (operands[0], operands[0], operands[2]));
285   DONE;
288 (define_insn "pop_pic_reg"
289   [(set (reg:SI PIC_REG)
290         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
291   "reload_completed"
292   "movm (sp),[a2]")
294 (define_expand "movsi"
295   [(set (match_operand:SI 0 "general_operand" "")
296         (match_operand:SI 1 "general_operand" ""))]
297   ""
298   "
300   /* One of the ops has to be in a register */
301   if (!register_operand (operand1, SImode)
302       && !register_operand (operand0, SImode))
303     operands[1] = copy_to_mode_reg (SImode, operand1);
304   if (flag_pic)
305     {
306       rtx temp;
307       if (SYMBOLIC_CONST_P (operands[1]))
308         {
309           if (GET_CODE (operands[0]) == MEM)
310             operands[1] = force_reg (Pmode, operands[1]);
311           else
312             {
313               temp = (!can_create_pseudo_p ()
314                       ? operands[0]
315                       : gen_reg_rtx (Pmode));
316               operands[1] = legitimize_pic_address (operands[1], temp);
317             }
318         }
319       else if (GET_CODE (operands[1]) == CONST
320                && GET_CODE (XEXP (operands[1], 0)) == PLUS
321                && SYMBOLIC_CONST_P (XEXP (XEXP (operands[1], 0), 0)))
322         {
323           temp = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
324           temp = legitimize_pic_address (XEXP (XEXP (operands[1], 0), 0),
325                                          temp);
326           operands[1] = expand_binop (SImode, add_optab, temp,
327                                       XEXP (XEXP (operands[1], 0), 1),
328                                       (!can_create_pseudo_p ()
329                                        ? temp
330                                        : gen_reg_rtx (Pmode)),
331                                       0, OPTAB_LIB_WIDEN);
332         }
333     }
336 (define_insn ""
337   [(set (match_operand:SI 0 "nonimmediate_operand"
338                                 "=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax,axR,!*y,*f,*f,dxaQ")
339         (match_operand:SI 1 "general_operand"
340                                 "0,0,I,I,dx,ax,dx,ax,dixm,aixm,dixm,aixm,!*y,axR,0,dxaQi*f,*f"))]
341   "register_operand (operands[0], SImode)
342    || register_operand (operands[1], SImode)"
343   "*
345   switch (which_alternative)
346     {
347     case 0:
348     case 1:
349       return \"nop\";
350     case 2:
351       return \"clr %0\";
352     case 3:
353     case 4:
354     case 5:
355     case 6:
356     case 7:
357     case 8:
358     case 9:
359     case 10:
360     case 11:
361     case 12:
362     case 13:
363       if (GET_CODE (operands[1]) == CONST_DOUBLE)
364         {
365           rtx xoperands[2];
366           xoperands[0] = operands[0];
367           xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
368           output_asm_insn (\"mov %1,%0\", xoperands);
369           return \"\";
370         }
372       if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
373           && GET_CODE (operands[1]) == CONST_INT)
374         {
375           HOST_WIDE_INT val = INTVAL (operands[1]);
377           if (((val & 0x80) && ! (val & 0xffffff00))
378               || ((val & 0x800000) && ! (val & 0xff000000)))
379             return \"movu %1,%0\";
380         }
381       return \"mov %1,%0\";
382     case 14:
383       return \"nop\";
384     case 15:
385     case 16:
386       return \"fmov %1,%0\";
387     default:
388       gcc_unreachable ();
389     }
391   [(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")])
393 (define_expand "movsf"
394   [(set (match_operand:SF 0 "general_operand" "")
395         (match_operand:SF 1 "general_operand" ""))]
396   ""
397   "
399   /* One of the ops has to be in a register */
400   if (!register_operand (operand1, SFmode)
401       && !register_operand (operand0, SFmode))
402     operands[1] = copy_to_mode_reg (SFmode, operand1);
405 (define_insn ""
406   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,dx,ax,dx,a,f,dxaQ,daxm,dax")
407         (match_operand:SF 1 "general_operand" "0,0,0,G,G,fdxaQF,f,dax,daxFm"))]
408   "register_operand (operands[0], SFmode)
409    || register_operand (operands[1], SFmode)"
410   "*
412   switch (which_alternative)
413     {
414     case 0:
415     case 1:
416     case 2:
417       return \"nop\";
418     case 3:
419       return \"clr %0\";
420     /* case 4: below */
421     case 5:
422     case 6:
423       return \"fmov %1, %0\";
424     case 4:
425     case 7:
426     case 8:
427       if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
428           && GET_CODE (operands[1]) == CONST_INT)
429         {
430           HOST_WIDE_INT val = INTVAL (operands[1]);
432           if (((val & 0x80) && ! (val & 0xffffff00))
433               || ((val & 0x800000) && ! (val & 0xff000000)))
434             return \"movu %1,%0\";
435         }
436       return \"mov %1,%0\";
437     default:
438       gcc_unreachable ();
439     }
441   [(set_attr "cc" "none,none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
443 (define_expand "movdi"
444   [(set (match_operand:DI 0 "general_operand" "")
445         (match_operand:DI 1 "general_operand" ""))]
446   ""
447   "
449   /* One of the ops has to be in a register */
450   if (!register_operand (operand1, DImode)
451       && !register_operand (operand0, DImode))
452     operands[1] = copy_to_mode_reg (DImode, operand1);
455 (define_insn ""
456   [(set (match_operand:DI 0 "nonimmediate_operand"
457                                 "=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax,*f,*f,*f,dxa,*f,Q")
458         (match_operand:DI 1 "general_operand"
459                                 "0,0,I,I,dx,ax,dx,ax,dxim,axim,dxim,axim,0,*f,dxai,*f,Q,*f"))]
460   "register_operand (operands[0], DImode)
461    || register_operand (operands[1], DImode)"
462   "*
464   long val[2];
465   REAL_VALUE_TYPE rv;
467   switch (which_alternative)
468     {
469       case 0:
470       case 1:
471         return \"nop\";
473       case 2:
474         return \"clr %L0\;clr %H0\";
476       case 3:
477         if (rtx_equal_p (operands[0], operands[1]))
478           return \"sub %L1,%L0\;mov %L0,%H0\";
479         else
480           return \"mov %1,%L0\;mov %L0,%H0\";
481       case 4:
482       case 5:
483       case 6:
484       case 7:
485       case 8:
486       case 9:
487       case 10:
488       case 11:
489         if (GET_CODE (operands[1]) == CONST_INT)
490           {
491             rtx low, high;
492             split_double (operands[1], &low, &high);
493             val[0] = INTVAL (low);
494             val[1] = INTVAL (high);
495           }
496         if (GET_CODE (operands[1]) == CONST_DOUBLE)
497           {
498             if (GET_MODE (operands[1]) == DFmode)
499               {
500                 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
501                 REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
502               }
503             else if (GET_MODE (operands[1]) == VOIDmode
504                      || GET_MODE (operands[1]) == DImode)
505               {
506                 val[0] = CONST_DOUBLE_LOW (operands[1]);
507                 val[1] = CONST_DOUBLE_HIGH (operands[1]);
508               }
509           }
511         if (GET_CODE (operands[1]) == MEM
512             && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
513           {
514             rtx temp = operands[0];
516             while (GET_CODE (temp) == SUBREG)
517               temp = SUBREG_REG (temp);
519             gcc_assert (GET_CODE (temp) == REG);
521             if (reg_overlap_mentioned_p (gen_rtx_REG (SImode, REGNO (temp)),
522                                          XEXP (operands[1], 0)))
523               return \"mov %H1,%H0\;mov %L1,%L0\";
524             else
525               return \"mov %L1,%L0\;mov %H1,%H0\";
527           }
528         else if (GET_CODE (operands[1]) == MEM
529                  && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
530                  && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
531           {
532             rtx xoperands[2];
534             xoperands[0] = operands[0];
535             xoperands[1] = XEXP (operands[1], 0);
537             output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\",
538                              xoperands);
539             return \"\";
540           }
541         else
542           {
543             if ((GET_CODE (operands[1]) == CONST_INT
544                  || GET_CODE (operands[1]) == CONST_DOUBLE)
545                 && val[0] == 0)
546               {
547                 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
548                   output_asm_insn (\"clr %L0\", operands);
549                 else
550                   output_asm_insn (\"mov %L1,%L0\", operands);
551               }
552             else if ((GET_CODE (operands[1]) == CONST_INT
553                       || GET_CODE (operands[1]) == CONST_DOUBLE)
554                      && (REGNO_REG_CLASS (true_regnum (operands[0]))
555                          == EXTENDED_REGS)
556                      && (((val[0] & 0x80) && ! (val[0] & 0xffffff00))
557                          || ((val[0] & 0x800000) && ! (val[0] & 0xff000000))))
558               output_asm_insn (\"movu %L1,%L0\", operands);
559             else
560               output_asm_insn (\"mov %L1,%L0\", operands);
562             if ((GET_CODE (operands[1]) == CONST_INT
563                  || GET_CODE (operands[1]) == CONST_DOUBLE)
564                 && val[1] == 0)
565               {
566                 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
567                   output_asm_insn (\"clr %H0\", operands);
568                 else
569                   output_asm_insn (\"mov %H1,%H0\", operands);
570               }
571             else if ((GET_CODE (operands[1]) == CONST_INT
572                       || GET_CODE (operands[1]) == CONST_DOUBLE)
573                      && val[0] == val[1])
574               output_asm_insn (\"mov %L0,%H0\", operands);
575             else if ((GET_CODE (operands[1]) == CONST_INT
576                       || GET_CODE (operands[1]) == CONST_DOUBLE)
577                      && (REGNO_REG_CLASS (true_regnum (operands[0]))
578                          == EXTENDED_REGS)
579                      && (((val[1] & 0x80) && ! (val[1] & 0xffffff00))
580                          || ((val[1] & 0x800000) && ! (val[1] & 0xff000000))))
581               output_asm_insn (\"movu %H1,%H0\", operands);
582             else
583               output_asm_insn (\"mov %H1,%H0\", operands);
584             return \"\";
585           }
586       case 12:
587         return \"nop\";
588       case 13:
589       case 14:
590       case 15:
591         return \"fmov %L1, %L0\;fmov %H1, %H0\";
592       case 16:
593         if (GET_CODE (operands[1]) == MEM
594             && GET_CODE (XEXP (operands[1], 0)) == CONST_INT
595             && (INTVAL (XEXP (operands[1], 0)) & 7) == 0)
596           return \"fmov %D1, %D0\";
597         else
598           return \"fmov %L1, %L0\;fmov %H1, %H0\";
599       case 17:
600         if (GET_CODE (operands[0]) == MEM
601             && GET_CODE (XEXP (operands[0], 0)) == CONST_INT
602             && (INTVAL (XEXP (operands[0], 0)) & 7) == 0)
603           return \"fmov %D1, %D0\";
604         else
605           return \"fmov %L1, %L0\;fmov %H1, %H0\";
606     default:
607       gcc_unreachable ();
608     }
610   [(set (attr "cc")
611         (cond
612          [
613          (ior (lt (symbol_ref "which_alternative") (const_int 2))
614               (eq (symbol_ref "which_alternative") (const_int 12))
615               ) (const_string "none")
616          (eq (symbol_ref "which_alternative") (const_int 2)
617              ) (const_string "clobber")
618          (eq (symbol_ref "which_alternative") (const_int 3)
619              ) (if_then_else
620                 (ne (symbol_ref "rtx_equal_p (operands[0], operands[1])")
621                     (const_int 0)) (const_string "clobber")
622                     (const_string "none_0hit"))
623          (ior (eq (symbol_ref "which_alternative") (const_int 8))
624               (eq (symbol_ref "which_alternative") (const_int 9))
625               ) (if_then_else
626                  (ne (symbol_ref "mn10300_wide_const_load_uses_clr
627                                   (operands)")
628                      (const_int 0)) (const_string "clobber")
629                      (const_string "none_0hit"))
630          ] (const_string "none_0hit")))])
632 (define_expand "movdf"
633   [(set (match_operand:DF 0 "general_operand" "")
634         (match_operand:DF 1 "general_operand" ""))]
635   ""
636   "
638   /* One of the ops has to be in a register */
639   if (!register_operand (operand1, DFmode)
640       && !register_operand (operand0, DFmode))
641     operands[1] = copy_to_mode_reg (DFmode, operand1);
644 (define_insn ""
645   [(set (match_operand:DF 0 "nonimmediate_operand"
646                                 "=f,dx,ax,dx,f,f,dxa,f,Q,a,dxm,dxm,axm,axm,dx,dx,ax,ax")
647         (match_operand:DF 1 "general_operand"
648                                 "0,0,0,G,f,dxaF,f,Q,f,G,dx,ax,dx,ax,dxFm,axFm,dxFm,axFm"))]
649   "register_operand (operands[0], DFmode)
650    || register_operand (operands[1], DFmode)"
651   "*
653   long val[2];
654   REAL_VALUE_TYPE rv;
656   switch (which_alternative)
657     {
658       case 0:
659       case 1:
660       case 2:
661         return \"nop\";
663       case 3:
664         return \"clr %L0\;clr %H0\";
666       case 4:
667       case 5:
668       case 6:
669         return \"fmov %L1, %L0\;fmov %H1, %H0\";
671       case 7:
672         if (GET_CODE (operands[1]) == MEM
673             && GET_CODE (XEXP (operands[1], 0)) == CONST_INT
674             && (INTVAL (XEXP (operands[1], 0)) & 7) == 0)
675           return \"fmov %D1, %D0\";
676         else
677           return \"fmov %L1, %L0\;fmov %H1, %H0\";
679       case 8:
680         if (GET_CODE (operands[0]) == MEM
681             && GET_CODE (XEXP (operands[0], 0)) == CONST_INT
682             && (INTVAL (XEXP (operands[0], 0)) & 7) == 0)
683           return \"fmov %D1, %D0\";
684         else
685           return \"fmov %L1, %L0\;fmov %H1, %H0\";
687       case 9:
688          if (rtx_equal_p (operands[0], operands[1]))
689            return \"sub %L1,%L0\;mov %L0,%H0\";
690          else
691            return \"mov %1,%L0\;mov %L0,%H0\";
692       case 10:
693       case 11:
694       case 12:
695       case 13:
696       case 14:
697       case 15:
698       case 16:
699       case 17:
700         if (GET_CODE (operands[1]) == CONST_INT)
701           {
702             rtx low, high;
703             split_double (operands[1], &low, &high);
704             val[0] = INTVAL (low);
705             val[1] = INTVAL (high);
706           }
707         if (GET_CODE (operands[1]) == CONST_DOUBLE)
708           {
709             if (GET_MODE (operands[1]) == DFmode)
710               {
711                 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
712                 REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
713               }
714             else if (GET_MODE (operands[1]) == VOIDmode
715                      || GET_MODE (operands[1]) == DImode)
716               {
717                 val[0] = CONST_DOUBLE_LOW (operands[1]);
718                 val[1] = CONST_DOUBLE_HIGH (operands[1]);
719               }
720           }
722         if (GET_CODE (operands[1]) == MEM
723             && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
724           {
725             rtx temp = operands[0];
727             while (GET_CODE (temp) == SUBREG)
728               temp = SUBREG_REG (temp);
730             gcc_assert (GET_CODE (temp) == REG);
732             if (reg_overlap_mentioned_p (gen_rtx_REG (SImode, REGNO (temp)),
733                                          XEXP (operands[1], 0)))
734               return \"mov %H1,%H0\;mov %L1,%L0\";
735             else
736               return \"mov %L1,%L0\;mov %H1,%H0\";
738           }
739         else if (GET_CODE (operands[1]) == MEM
740                  && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
741                  && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
742           {
743             rtx xoperands[2];
745             xoperands[0] = operands[0];
746             xoperands[1] = XEXP (operands[1], 0);
748             output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\",
749                              xoperands);
750             return \"\";
751           }
752         else
753           {
754             if ((GET_CODE (operands[1]) == CONST_INT
755                  || GET_CODE (operands[1]) == CONST_DOUBLE)
756                 && val[0] == 0)
757               {
758                 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
759                   output_asm_insn (\"clr %L0\", operands);
760                 else
761                   output_asm_insn (\"mov %L1,%L0\", operands);
762               }
763             else if ((GET_CODE (operands[1]) == CONST_INT
764                       || GET_CODE (operands[1]) == CONST_DOUBLE)
765                      && (REGNO_REG_CLASS (true_regnum (operands[0]))
766                          == EXTENDED_REGS)
767                      && (((val[0] & 0x80) && ! (val[0] & 0xffffff00))
768                          || ((val[0] & 0x800000) && ! (val[0] & 0xff000000))))
769               output_asm_insn (\"movu %L1,%L0\", operands);
770             else
771               output_asm_insn (\"mov %L1,%L0\", operands);
773             if ((GET_CODE (operands[1]) == CONST_INT
774                  || GET_CODE (operands[1]) == CONST_DOUBLE)
775                 && val[1] == 0)
776               {
777                 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
778                   output_asm_insn (\"clr %H0\", operands);
779                 else
780                   output_asm_insn (\"mov %H1,%H0\", operands);
781               }
782             else if ((GET_CODE (operands[1]) == CONST_INT
783                       || GET_CODE (operands[1]) == CONST_DOUBLE)
784                      && val[0] == val[1])
785               output_asm_insn (\"mov %L0,%H0\", operands);
786             else if ((GET_CODE (operands[1]) == CONST_INT
787                       || GET_CODE (operands[1]) == CONST_DOUBLE)
788                      && (REGNO_REG_CLASS (true_regnum (operands[0]))
789                          == EXTENDED_REGS)
790                      && (((val[1] & 0x80) && ! (val[1] & 0xffffff00))
791                          || ((val[1] & 0x800000) && ! (val[1] & 0xff000000))))
792               output_asm_insn (\"movu %H1,%H0\", operands);
793             else
794               output_asm_insn (\"mov %H1,%H0\", operands);
795             return \"\";
796           }
797     default:
798       gcc_unreachable ();
799     }
801   [(set (attr "cc")
802         (cond
803          [
804          (lt (symbol_ref "which_alternative") (const_int 3)
805              ) (const_string "none")
806          (eq (symbol_ref "which_alternative") (const_int 3)
807              ) (const_string "clobber")
808          (eq (symbol_ref "which_alternative") (const_int 9)
809              ) (if_then_else
810                 (ne (symbol_ref "rtx_equal_p (operands[0], operands[1])")
811                     (const_int 0)) (const_string "clobber")
812                     (const_string "none_0hit"))
813          (ior (eq (symbol_ref "which_alternative") (const_int 14))
814               (eq (symbol_ref "which_alternative") (const_int 15))
815               ) (if_then_else
816                  (ne (symbol_ref "mn10300_wide_const_load_uses_clr
817                                   (operands)")
818                      (const_int 0)) (const_string "clobber")
819                      (const_string "none_0hit"))
820          ] (const_string "none_0hit")))])
824 ;; ----------------------------------------------------------------------
825 ;; TEST INSTRUCTIONS
826 ;; ----------------------------------------------------------------------
828 ;; Go ahead and define tstsi so we can eliminate redundant tst insns
829 ;; when we start trying to optimize this port.
830 (define_insn "tstsi"
831   [(set (cc0) (match_operand:SI 0 "register_operand" "dax"))]
832   ""
833   "* return output_tst (operands[0], insn);"
834   [(set_attr "cc" "set_znv")])
836 (define_insn ""
837   [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "dx,!a")))]
838   "TARGET_AM33"
839   "* return output_tst (operands[0], insn);"
840   [(set_attr "cc" "set_znv")])
842 (define_insn ""
843   [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "dx")))]
844   ""
845   "* return output_tst (operands[0], insn);"
846   [(set_attr "cc" "set_znv")])
848 (define_insn ""
849   [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "dx,!a")))]
850   "TARGET_AM33"
851   "* return output_tst (operands[0], insn);"
852   [(set_attr "cc" "set_znv")])
854 (define_insn ""
855   [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "dx")))]
856   ""
857   "* return output_tst (operands[0], insn);"
858   [(set_attr "cc" "set_znv")])
860 ;; Ordinarily, the cmp instruction will set the Z bit of cc0 to 1 if
861 ;; its operands hold equal values, but the operands of a cmp
862 ;; instruction must be distinct registers.  In the case where we'd
863 ;; like to compare a register to itself, we can achieve this effect
864 ;; with a btst 0,d0 instead.  (This will not alter the contents of d0
865 ;; but will have the proper effect on cc0.  Using d0 is arbitrary; any
866 ;; data register would work.)
868 ;; Even though the first alternative would be preferable if it can
869 ;; possibly match, reload must not be given the opportunity to attempt
870 ;; to use it.  It assumes that such matches can only occur when one of
871 ;; the operands is used for input and the other for output.  Since
872 ;; this is not the case, it abort()s.  Indeed, such a reload cannot be
873 ;; possibly satisfied, so just mark the alternative with a `!', so
874 ;; that it is not considered by reload.
876 (define_insn "cmpsi"
877   [(set (cc0)
878         (compare (match_operand:SI 0 "register_operand" "!*d*a*x,dax")
879                  (match_operand:SI 1 "nonmemory_operand" "*0,daxi")))]
880   ""
881   "@
882   btst 0,d0
883   cmp %1,%0"
884   [(set_attr "cc" "compare,compare")])
886 (define_insn "cmpsf"
887   [(set (cc0)
888         (compare (match_operand:SF 0 "register_operand" "f,f")
889                  (match_operand:SF 1 "nonmemory_operand" "f,F")))]
890   "TARGET_AM33_2"
891   "fcmp %1,%0"
892   [(set_attr "cc" "compare,compare")])
894 ;; ----------------------------------------------------------------------
895 ;; ADD INSTRUCTIONS
896 ;; ----------------------------------------------------------------------
898 (define_expand "addsi3"
899   [(set (match_operand:SI 0 "register_operand" "")
900         (plus:SI (match_operand:SI 1 "register_operand" "")
901                  (match_operand:SI 2 "nonmemory_operand" "")))]
902   ""
903   "")
905 (define_insn ""
906   [(set (match_operand:SI 0 "register_operand" "=dx,a,x,a,dax,!*y,!dax")
907         (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,dax")
908                  (match_operand:SI 2 "nonmemory_operand" "J,J,L,L,daxi,i,dax")))]
909   "TARGET_AM33"
910   "*
912   switch (which_alternative)
913     {
914     case 0:
915     case 1:
916       return \"inc %0\";
917     case 2:
918     case 3:
919       return \"inc4 %0\";
920     case 4:
921     case 5:
922       return \"add %2,%0\";
923     case 6:
924       {
925         enum reg_class src1_class, src2_class, dst_class;
927         src1_class = REGNO_REG_CLASS (true_regnum (operands[1]));
928         src2_class = REGNO_REG_CLASS (true_regnum (operands[2]));
929         dst_class = REGNO_REG_CLASS (true_regnum (operands[0]));
931         /* I'm not sure if this can happen or not.  Might as well be prepared
932           and generate the best possible code if it does happen.  */
933         if (true_regnum (operands[0]) == true_regnum (operands[1]))
934           return \"add %2,%0\";
935         if (true_regnum (operands[0]) == true_regnum (operands[2]))
936           return \"add %1,%0\";
938         /* Catch cases where no extended register was used.  These should be
939            handled just like the mn10300.  */
940         if (src1_class != EXTENDED_REGS
941             && src2_class != EXTENDED_REGS
942             && dst_class != EXTENDED_REGS)
943           {
944             /* We have to copy one of the sources into the destination, then
945                add the other source to the destination.
947                Carefully select which source to copy to the destination; a naive
948                implementation will waste a byte when the source classes are
949                different and the destination is an address register.  Selecting
950                the lowest cost register copy will optimize this sequence.  */
951             if (REGNO_REG_CLASS (true_regnum (operands[1]))
952                 == REGNO_REG_CLASS (true_regnum (operands[0])))
953               return \"mov %1,%0\;add %2,%0\";
954             return \"mov %2,%0\;add %1,%0\";
955           }
957         /* At least one register is an extended register.  */
959         /* The three operand add instruction on the am33 is a win iff the
960            output register is an extended register, or if both source
961            registers are extended registers.  */
962         if (dst_class == EXTENDED_REGS
963             || src1_class == src2_class)
964           return \"add %2,%1,%0\";
966       /* It is better to copy one of the sources to the destination, then
967          perform a 2 address add.  The destination in this case must be
968          an address or data register and one of the sources must be an
969          extended register and the remaining source must not be an extended
970          register.
972          The best code for this case is to copy the extended reg to the
973          destination, then emit a two address add.  */
974       if (src1_class == EXTENDED_REGS)
975         return \"mov %1,%0\;add %2,%0\";
976       return \"mov %2,%0\;add %1,%0\";
977       }
978     default:
979       gcc_unreachable ();
980     }
982   [(set_attr "cc" "set_zn,none_0hit,set_zn,none_0hit,set_zn,none_0hit,set_zn")])
984 (define_insn ""
985   [(set (match_operand:SI 0 "register_operand" "=dx,a,a,dax,!*y,!dax")
986         (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,dax")
987                  (match_operand:SI 2 "nonmemory_operand" "J,J,L,daxi,i,dax")))]
988   ""
989   "*
991   switch (which_alternative)
992     {
993     case 0:
994     case 1:
995       return \"inc %0\";
996     case 2:
997       return \"inc4 %0\";
998     case 3:
999     case 4:
1000       return \"add %2,%0\";
1001     case 5:
1002       /* I'm not sure if this can happen or not.  Might as well be prepared
1003          and generate the best possible code if it does happen.  */
1004       if (true_regnum (operands[0]) == true_regnum (operands[1]))
1005         return \"add %2,%0\";
1006       if (true_regnum (operands[0]) == true_regnum (operands[2]))
1007         return \"add %1,%0\";
1009       /* We have to copy one of the sources into the destination, then add
1010          the other source to the destination.
1012          Carefully select which source to copy to the destination; a naive
1013          implementation will waste a byte when the source classes are different
1014          and the destination is an address register.  Selecting the lowest
1015          cost register copy will optimize this sequence.  */
1016       if (REGNO_REG_CLASS (true_regnum (operands[1]))
1017           == REGNO_REG_CLASS (true_regnum (operands[0])))
1018         return \"mov %1,%0\;add %2,%0\";
1019       return \"mov %2,%0\;add %1,%0\";
1020     default:
1021       gcc_unreachable ();
1022     }
1024   [(set_attr "cc" "set_zn,none_0hit,none_0hit,set_zn,none_0hit,set_zn")])
1026 ;; ----------------------------------------------------------------------
1027 ;; SUBTRACT INSTRUCTIONS
1028 ;; ----------------------------------------------------------------------
1030 (define_expand "subsi3"
1031   [(set (match_operand:SI 0 "register_operand" "")
1032         (minus:SI (match_operand:SI 1 "register_operand" "")
1033                   (match_operand:SI 2 "nonmemory_operand" "")))]
1034   ""
1035   "")
1037 (define_insn ""
1038   [(set (match_operand:SI 0 "register_operand" "=dax,!dax")
1039         (minus:SI (match_operand:SI 1 "register_operand" "0,dax")
1040                   (match_operand:SI 2 "nonmemory_operand" "daxi,dax")))]
1041   "TARGET_AM33"
1042   "*
1044   if (true_regnum (operands[0]) == true_regnum (operands[1]))
1045     return \"sub %2,%0\";
1046   else
1047     {
1048       enum reg_class src1_class, src2_class, dst_class;
1050       src1_class = REGNO_REG_CLASS (true_regnum (operands[1]));
1051       src2_class = REGNO_REG_CLASS (true_regnum (operands[2]));
1052       dst_class = REGNO_REG_CLASS (true_regnum (operands[0]));
1054       /* If no extended registers are used, then the best way to handle
1055          this is to copy the first source operand into the destination
1056          and emit a two address subtraction.  */
1057       if (src1_class != EXTENDED_REGS
1058           && src2_class != EXTENDED_REGS
1059           && dst_class != EXTENDED_REGS
1060           && true_regnum (operands[0]) != true_regnum (operands[2]))
1061         return \"mov %1,%0\;sub %2,%0\";
1062       return \"sub %2,%1,%0\";
1063     }
1065   [(set_attr "cc" "set_zn")])
1067 (define_insn ""
1068   [(set (match_operand:SI 0 "register_operand" "=dax")
1069         (minus:SI (match_operand:SI 1 "register_operand" "0")
1070                   (match_operand:SI 2 "nonmemory_operand" "daxi")))]
1071   ""
1072   "sub %2,%0"
1073   [(set_attr "cc" "set_zn")])
1075 (define_expand "negsi2"
1076   [(set (match_operand:SI 0 "register_operand" "")
1077         (neg:SI (match_operand:SI 1 "register_operand" "")))]
1078   ""
1079   "
1081   rtx target = gen_reg_rtx (SImode);
1083   emit_move_insn (target, const0_rtx);
1084   emit_insn (gen_subsi3 (target, target, operands[1]));
1085   emit_move_insn (operands[0], target);
1086   DONE;
1089 ;; ----------------------------------------------------------------------
1090 ;; MULTIPLY INSTRUCTIONS
1091 ;; ----------------------------------------------------------------------
1093 (define_insn "mulsidi3"
1094   [(set (match_operand:DI 0 "register_operand" "=dax")
1095         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "dax"))
1096                  (sign_extend:DI (match_operand:SI 2 "register_operand" "dax"))))]
1097   "TARGET_AM33"
1098   "mul %1,%2,%H0,%L0"
1099   [(set_attr "cc" "set_zn")])
1101 (define_insn "umulsidi3"
1102   [(set (match_operand:DI 0 "register_operand" "=dax")
1103         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "dax"))
1104                  (zero_extend:DI (match_operand:SI 2 "register_operand" "dax"))))]
1105   "TARGET_AM33"
1106   "mulu %1,%2,%H0,%L0"
1107   [(set_attr "cc" "set_zn")])
1109 (define_expand "mulsi3"
1110   [(set (match_operand:SI 0 "register_operand" "")
1111         (mult:SI (match_operand:SI 1 "register_operand" "")
1112                  (match_operand:SI 2 "register_operand" "")))]
1113   ""
1114   "")
1116 (define_insn ""
1117   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1118         (mult:SI (match_operand:SI 1 "register_operand" "%0,0")
1119                  (match_operand:SI 2 "nonmemory_operand" "dx,daxi")))]
1120   "TARGET_AM33"
1121   "*
1123   if (TARGET_MULT_BUG)
1124     return \"nop\;nop\;mul %2,%0\";
1125   else
1126     return \"mul %2,%0\";
1128   [(set_attr "cc" "set_zn")])
1130 (define_insn ""
1131   [(set (match_operand:SI 0 "register_operand" "=dx")
1132         (mult:SI (match_operand:SI 1 "register_operand" "%0")
1133                  (match_operand:SI 2 "register_operand" "dx")))]
1134   ""
1135   "*
1137   if (TARGET_MULT_BUG)
1138     return \"nop\;nop\;mul %2,%0\";
1139   else
1140     return \"mul %2,%0\";
1142   [(set_attr "cc" "set_zn")])
1144 (define_insn "udivmodsi4"
1145   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx")
1146         (udiv:SI (match_operand:SI 1 "general_operand" "0")
1147                  (match_operand:SI 2 "general_operand" "dx")))
1148    (set (match_operand:SI 3 "nonimmediate_operand" "=&d")
1149         (umod:SI (match_dup 1) (match_dup 2)))]
1150   ""
1151   "*
1153   output_asm_insn (\"sub %3,%3\;mov %3,mdr\", operands);
1155   if (find_reg_note (insn, REG_UNUSED, operands[3]))
1156     return \"divu %2,%0\";
1157   else
1158     return \"divu %2,%0\;mov mdr,%3\";
1160   [(set_attr "cc" "set_zn")])
1162 (define_insn "divmodsi4"
1163   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx")
1164         (div:SI (match_operand:SI 1 "general_operand" "0")
1165                  (match_operand:SI 2 "general_operand" "dx")))
1166    (set (match_operand:SI 3 "nonimmediate_operand" "=d")
1167         (mod:SI (match_dup 1) (match_dup 2)))]
1168   ""
1169   "*
1171   if (find_reg_note (insn, REG_UNUSED, operands[3]))
1172     return \"ext %0\;div %2,%0\";
1173   else
1174     return \"ext %0\;div %2,%0\;mov mdr,%3\";
1176   [(set_attr "cc" "set_zn")])
1179 ;; ----------------------------------------------------------------------
1180 ;; AND INSTRUCTIONS
1181 ;; ----------------------------------------------------------------------
1183 (define_expand "andsi3"
1184   [(set (match_operand:SI 0 "register_operand" "")
1185         (and:SI (match_operand:SI 1 "register_operand" "")
1186                 (match_operand:SI 2 "nonmemory_operand" "")))]
1187   ""
1188   "")
1190 (define_insn ""
1191   [(set (match_operand:SI 0 "register_operand" "=dx,dx,!dax")
1192         (and:SI (match_operand:SI 1 "register_operand" "%0,0,dax")
1193                 (match_operand:SI 2 "nonmemory_operand" "N,dxi,dax")))]
1194   "TARGET_AM33"
1195   "*
1197   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff)
1198     return \"extbu %0\";
1199   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xffff)
1200     return \"exthu %0\";
1201   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x7fffffff)
1202     return \"add %0,%0\;lsr 1,%0\";
1203   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x3fffffff)
1204     return \"asl2 %0\;lsr 2,%0\";
1205   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x1fffffff)
1206     return \"add %0,%0\;asl2 %0\;lsr 3,%0\";
1207   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x0fffffff)
1208     return \"asl2 %0\;asl2 %0\;lsr 4,%0\";
1209   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffe)
1210     return \"lsr 1,%0\;add %0,%0\";
1211   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffc)
1212     return \"lsr 2,%0\;asl2 %0\";
1213   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff8)
1214     return \"lsr 3,%0\;add %0,%0\;asl2 %0\";
1215   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff0)
1216     return \"lsr 4,%0\;asl2 %0\;asl2 %0\";
1217   if (REG_P (operands[2]) && REG_P (operands[1])
1218       && true_regnum (operands[0]) != true_regnum (operands[1])
1219       && true_regnum (operands[0]) != true_regnum (operands[2])
1220       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1221       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1222       && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
1223     return \"mov %1,%0\;and %2,%0\";
1224   if (REG_P (operands[2]) && REG_P (operands[1])
1225       && true_regnum (operands[0]) != true_regnum (operands[1])
1226       && true_regnum (operands[0]) != true_regnum (operands[2]))
1227     return \"and %1,%2,%0\";
1228   if (REG_P (operands[2]) && REG_P (operands[0])
1229       && true_regnum (operands[2]) == true_regnum (operands[0]))
1230     return \"and %1,%0\";
1231   return \"and %2,%0\";
1233   [(set (attr "cc")
1234         (cond
1235          [
1236          (eq (symbol_ref "which_alternative") (const_int 0)
1237              ) (const_string "none_0hit")
1238          (ne (symbol_ref "GET_CODE (operands[2]) == CONST_INT
1239                           && (INTVAL (operands[2]) == 0x7fffffff
1240                               || INTVAL (operands[2]) == 0x3fffffff
1241                               || INTVAL (operands[2]) == 0x1fffffff
1242                               || INTVAL (operands[2]) == 0x0fffffff
1243                               || INTVAL (operands[2]) == 0xfffffffe
1244                               || INTVAL (operands[2]) == 0xfffffffc
1245                               || INTVAL (operands[2]) == 0xfffffff8
1246                               || INTVAL (operands[2]) == 0xfffffff0)")
1247              (const_int 0)) (const_string "set_zn")
1248           ] (const_string "set_znv")))])
1250 (define_insn ""
1251   [(set (match_operand:SI 0 "register_operand" "=dx,dx")
1252         (and:SI (match_operand:SI 1 "register_operand" "%0,0")
1253                 (match_operand:SI 2 "nonmemory_operand" "N,dxi")))]
1254   ""
1255   "*
1257   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff)
1258     return \"extbu %0\";
1259   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xffff)
1260     return \"exthu %0\";
1261   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x7fffffff)
1262     return \"add %0,%0\;lsr 1,%0\";
1263   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x3fffffff)
1264     return \"asl2 %0\;lsr 2,%0\";
1265   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x1fffffff)
1266     return \"add %0,%0\;asl2 %0\;lsr 3,%0\";
1267   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x0fffffff)
1268     return \"asl2 %0\;asl2 %0\;lsr 4,%0\";
1269   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffe)
1270     return \"lsr 1,%0\;add %0,%0\";
1271   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffc)
1272     return \"lsr 2,%0\;asl2 %0\";
1273   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff8)
1274     return \"lsr 3,%0\;add %0,%0\;asl2 %0\";
1275   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff0)
1276     return \"lsr 4,%0\;asl2 %0\;asl2 %0\";
1277   return \"and %2,%0\";
1279   [(set (attr "cc")
1280         (cond
1281          [
1282          (eq (symbol_ref "which_alternative") (const_int 0)
1283              ) (const_string "none_0hit")
1284          ;; Shifts don't set the V flag, but bitwise operations clear
1285          ;; it (which correctly reflects the absence of overflow in a
1286          ;; compare-with-zero that might follow).  As for the
1287          ;; 0xfffffffe case, the add may overflow, so we can't use the
1288          ;; V flag.
1289          (ne (symbol_ref "GET_CODE (operands[2]) == CONST_INT
1290                           && (INTVAL (operands[2]) == 0x7fffffff
1291                               || INTVAL (operands[2]) == 0x3fffffff
1292                               || INTVAL (operands[2]) == 0x1fffffff
1293                               || INTVAL (operands[2]) == 0x0fffffff
1294                               || INTVAL (operands[2]) == 0xfffffffe
1295                               || INTVAL (operands[2]) == 0xfffffffc
1296                               || INTVAL (operands[2]) == 0xfffffff8
1297                               || INTVAL (operands[2]) == 0xfffffff0)")
1298              (const_int 0)) (const_string "set_zn")
1299           ] (const_string "set_znv")))])
1301 ;; ----------------------------------------------------------------------
1302 ;; OR INSTRUCTIONS
1303 ;; ----------------------------------------------------------------------
1305 (define_expand "iorsi3"
1306   [(set (match_operand:SI 0 "register_operand" "")
1307         (ior:SI (match_operand:SI 1 "register_operand" "")
1308                 (match_operand:SI 2 "nonmemory_operand" "")))]
1309   ""
1310   "")
1312 (define_insn ""
1313   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1314         (ior:SI (match_operand:SI 1 "register_operand" "%0,dax")
1315                 (match_operand:SI 2 "nonmemory_operand" "dxi,dax")))]
1316   "TARGET_AM33"
1317   "*
1319   if (REG_P (operands[2]) && REG_P (operands[1])
1320       && true_regnum (operands[0]) != true_regnum (operands[1])
1321       && true_regnum (operands[0]) != true_regnum (operands[2])
1322       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1323       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1324       && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
1325     return \"mov %1,%0\;or %2,%0\";
1326   if (REG_P (operands[2]) && REG_P (operands[1])
1327       && true_regnum (operands[0]) != true_regnum (operands[1])
1328       && true_regnum (operands[0]) != true_regnum (operands[2]))
1329     return \"or %1,%2,%0\";
1330   if (REG_P (operands[2]) && REG_P (operands[0])
1331       && true_regnum (operands[2]) == true_regnum (operands[0]))
1332     return \"or %1,%0\";
1333   return \"or %2,%0\";
1335   [(set_attr "cc" "set_znv")])
1337 (define_insn ""
1338   [(set (match_operand:SI 0 "register_operand" "=dx")
1339         (ior:SI (match_operand:SI 1 "register_operand" "%0")
1340                 (match_operand:SI 2 "nonmemory_operand" "dxi")))]
1341   ""
1342   "or %2,%0"
1343   [(set_attr "cc" "set_znv")])
1345 ;; ----------------------------------------------------------------------
1346 ;; XOR INSTRUCTIONS
1347 ;; ----------------------------------------------------------------------
1349 (define_expand "xorsi3"
1350   [(set (match_operand:SI 0 "register_operand" "")
1351         (xor:SI (match_operand:SI 1 "register_operand" "")
1352                 (match_operand:SI 2 "nonmemory_operand" "")))]
1353   ""
1354   "")
1356 (define_insn ""
1357   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1358         (xor:SI (match_operand:SI 1 "register_operand" "%0,dax")
1359                 (match_operand:SI 2 "nonmemory_operand" "dxi,dax")))]
1360   "TARGET_AM33"
1361   "*
1363   if (REG_P (operands[2]) && REG_P (operands[1])
1364       && true_regnum (operands[0]) != true_regnum (operands[1])
1365       && true_regnum (operands[0]) != true_regnum (operands[2])
1366       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1367       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1368       && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
1369     return \"mov %1,%0\;xor %2,%0\";
1370   if (REG_P (operands[2]) && REG_P (operands[1])
1371       && true_regnum (operands[0]) != true_regnum (operands[1])
1372       && true_regnum (operands[0]) != true_regnum (operands[2]))
1373     return \"xor %1,%2,%0\";
1374   if (REG_P (operands[2]) && REG_P (operands[0])
1375       && true_regnum (operands[2]) == true_regnum (operands[0]))
1376     return \"xor %1,%0\";
1377   return \"xor %2,%0\";
1379   [(set_attr "cc" "set_znv")])
1381 (define_insn ""
1382   [(set (match_operand:SI 0 "register_operand" "=dx")
1383         (xor:SI (match_operand:SI 1 "register_operand" "%0")
1384                 (match_operand:SI 2 "nonmemory_operand" "dxi")))]
1385   ""
1386   "xor %2,%0"
1387   [(set_attr "cc" "set_znv")])
1389 ;; ----------------------------------------------------------------------
1390 ;; NOT INSTRUCTIONS
1391 ;; ----------------------------------------------------------------------
1393 (define_expand "one_cmplsi2"
1394   [(set (match_operand:SI 0 "register_operand" "")
1395         (not:SI (match_operand:SI 1 "register_operand" "")))]
1396   ""
1397   "")
1399 (define_insn ""
1400   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1401         (not:SI (match_operand:SI 1 "register_operand" "0,0")))]
1402   "TARGET_AM33"
1403   "not %0"
1404   [(set_attr "cc" "set_znv")])
1406 (define_insn ""
1407   [(set (match_operand:SI 0 "register_operand" "=dx")
1408         (not:SI (match_operand:SI 1 "register_operand" "0")))]
1409   ""
1410   "not %0"
1411   [(set_attr "cc" "set_znv")])
1413 ;; -----------------------------------------------------------------
1414 ;; BIT FIELDS
1415 ;; -----------------------------------------------------------------
1418 ;; These set/clear memory in byte sized chunks.
1420 ;; They are no smaller/faster than loading the value into a register
1421 ;; and storing the register, but they don't need a scratch register
1422 ;; which may allow for better code generation.
1423 (define_insn ""
1424   [(set (match_operand:QI 0 "nonimmediate_operand" "=R,d") (const_int 0))]
1425   ""
1426   "@
1427   bclr 255,%A0
1428   clr %0"
1429   [(set_attr "cc" "clobber")])
1431 (define_insn ""
1432   [(set (match_operand:QI 0 "nonimmediate_operand" "=R,d") (const_int -1))]
1433   ""
1434   "@
1435   bset 255,%A0
1436   mov -1,%0"
1437   [(set_attr "cc" "clobber,none_0hit")])
1439 (define_insn ""
1440   [(set (match_operand:QI 0 "nonimmediate_operand" "+R,d")
1441         (subreg:QI
1442           (and:SI (subreg:SI (match_dup 0) 0)
1443                   (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
1444   ""
1445   "@
1446   bclr %N1,%A0
1447   and %1,%0"
1448   [(set_attr "cc" "clobber,set_znv")])
1450 (define_insn ""
1451   [(set (match_operand:QI 0 "memory_operand" "=R,T")
1452         (and:QI
1453          (match_dup 0)
1454          (not:QI (match_operand:QI 1 "nonmemory_operand" "i,d"))))]
1455   ""
1456   "@
1457   bclr %U1,%A0
1458   bclr %1,%0"
1459   [(set_attr "cc" "clobber,clobber")])
1461 (define_insn ""
1462   [(set (match_operand:QI 0 "nonimmediate_operand" "+R,d")
1463         (subreg:QI
1464           (ior:SI (subreg:SI (match_dup 0) 0)
1465                   (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
1466   ""
1467   "@
1468   bset %U1,%A0
1469   or %1,%0"
1470   [(set_attr "cc" "clobber,set_znv")])
1472 (define_expand "iorqi3"
1473   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1474         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
1475                 (match_operand:QI 2 "nonmemory_operand" "")))]
1476   ""
1477   "")
1479 (define_insn ""
1480   [(set (match_operand:QI 0 "nonimmediate_operand" "=R,T,r")
1481         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
1482                 ;; This constraint should really be nonmemory_operand,
1483                 ;; but making it general_operand, along with the
1484                 ;; condition that not both input operands are MEMs, it
1485                 ;; here helps combine do a better job.
1486                 (match_operand:QI 2 "general_operand" "i,d,ir")))]
1487   "TARGET_AM33 &&
1488    (GET_CODE (operands[2]) != MEM || GET_CODE (operands[1]) != MEM)"
1489   "@
1490   bset %U2,%A0
1491   bset %2,%0
1492   or %2,%0"
1493   [(set_attr "cc" "clobber,clobber,set_znv")])
1495 (define_insn ""
1496   [(set (match_operand:QI 0 "nonimmediate_operand" "=R,T,d")
1497         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
1498                 ;; This constraint should really be nonmemory_operand,
1499                 ;; but making it general_operand, along with the
1500                 ;; condition that not both input operands are MEMs, it
1501                 ;; here helps combine do a better job.
1502                 (match_operand:QI 2 "general_operand" "i,d,id")))]
1503   "GET_CODE (operands[2]) != MEM || GET_CODE (operands[1]) != MEM"
1504   "@
1505   bset %U2,%A0
1506   bset %2,%0
1507   or %2,%0"
1508   [(set_attr "cc" "clobber,clobber,set_znv")])
1510 (define_insn ""
1511   [(set (cc0)
1512      (zero_extract:SI (match_operand:SI 0 "register_operand" "dx")
1513                       (match_operand 1 "const_int_operand" "")
1514                       (match_operand 2 "const_int_operand" "")))]
1515   ""
1516   "*
1518   int len = INTVAL (operands[1]);
1519   int bit = INTVAL (operands[2]);
1520   int mask = 0;
1521   rtx xoperands[2];
1523   while (len > 0)
1524     {
1525       mask |= (1 << bit);
1526       bit++;
1527       len--;
1528     }
1530   xoperands[0] = operands[0];
1531   xoperands[1] = GEN_INT (trunc_int_for_mode (mask, SImode));
1532   output_asm_insn (\"btst %1,%0\", xoperands);
1533   return \"\";
1535   [(set_attr "cc" "clobber")])
1537 (define_insn ""
1538   [(set (cc0)
1539      (zero_extract:SI (match_operand:QI 0 "general_operand" "R,dx")
1540                       (match_operand 1 "const_int_operand" "")
1541                       (match_operand 2 "const_int_operand" "")))]
1542   "mask_ok_for_mem_btst (INTVAL (operands[1]), INTVAL (operands[2]))"
1543   "*
1545   int len = INTVAL (operands[1]);
1546   int bit = INTVAL (operands[2]);
1547   int mask = 0;
1548   rtx xoperands[2];
1550   while (len > 0)
1551     {
1552       mask |= (1 << bit);
1553       bit++;
1554       len--;
1555     }
1557   /* If the source operand is not a reg (i.e. it is memory), then extract the
1558      bits from mask that we actually want to test.  Note that the mask will
1559      never cross a byte boundary.  */
1560   if (!REG_P (operands[0]))
1561     {
1562       if (mask & 0xff)
1563         mask = mask & 0xff;
1564       else if (mask & 0xff00)
1565         mask = (mask >> 8) & 0xff;
1566       else if (mask & 0xff0000)
1567         mask = (mask >> 16) & 0xff;
1568       else if (mask & 0xff000000)
1569         mask = (mask >> 24) & 0xff;
1570     }
1572   xoperands[0] = operands[0];
1573   xoperands[1] = GEN_INT (trunc_int_for_mode (mask, SImode));
1574   if (GET_CODE (operands[0]) == REG)
1575     output_asm_insn (\"btst %1,%0\", xoperands);
1576   else
1577     output_asm_insn (\"btst %U1,%A0\", xoperands);
1578   return \"\";
1580   [(set_attr "cc" "clobber")])
1582 (define_insn ""
1583   [(set (cc0) (and:SI (match_operand:SI 0 "register_operand" "dx")
1584                       (match_operand:SI 1 "const_int_operand" "")))]
1585   ""
1586   "btst %1,%0"
1587   [(set_attr "cc" "clobber")])
1589 (define_insn ""
1590   [(set (cc0)
1591      (and:SI
1592        (subreg:SI (match_operand:QI 0 "general_operand" "R,dx") 0)
1593        (match_operand:SI 1 "const_8bit_operand" "")))]
1594   ""
1595   "@
1596   btst %U1,%A0
1597   btst %1,%0"
1598   [(set_attr "cc" "clobber")])
1601 ;; ----------------------------------------------------------------------
1602 ;; JUMP INSTRUCTIONS
1603 ;; ----------------------------------------------------------------------
1605 ;; Conditional jump instructions
1607 (define_expand "ble"
1608   [(set (pc)
1609         (if_then_else (le (cc0)
1610                           (const_int 0))
1611                       (label_ref (match_operand 0 "" ""))
1612                       (pc)))]
1613   ""
1614   "")
1616 (define_expand "bleu"
1617   [(set (pc)
1618         (if_then_else (leu (cc0)
1619                            (const_int 0))
1620                       (label_ref (match_operand 0 "" ""))
1621                       (pc)))]
1622   ""
1623   "")
1625 (define_expand "bge"
1626   [(set (pc)
1627         (if_then_else (ge (cc0)
1628                           (const_int 0))
1629                       (label_ref (match_operand 0 "" ""))
1630                       (pc)))]
1631   ""
1632   "")
1634 (define_expand "bgeu"
1635   [(set (pc)
1636         (if_then_else (geu (cc0)
1637                            (const_int 0))
1638                       (label_ref (match_operand 0 "" ""))
1639                       (pc)))]
1640   ""
1641   "")
1643 (define_expand "blt"
1644   [(set (pc)
1645         (if_then_else (lt (cc0)
1646                           (const_int 0))
1647                       (label_ref (match_operand 0 "" ""))
1648                       (pc)))]
1649   ""
1650   "")
1652 (define_expand "bltu"
1653   [(set (pc)
1654         (if_then_else (ltu (cc0)
1655                            (const_int 0))
1656                       (label_ref (match_operand 0 "" ""))
1657                       (pc)))]
1658   ""
1659   "")
1661 (define_expand "bgt"
1662   [(set (pc)
1663         (if_then_else (gt (cc0)
1664                           (const_int 0))
1665                       (label_ref (match_operand 0 "" ""))
1666                       (pc)))]
1667   ""
1668   "")
1670 (define_expand "bgtu"
1671   [(set (pc)
1672         (if_then_else (gtu (cc0)
1673                            (const_int 0))
1674                       (label_ref (match_operand 0 "" ""))
1675                       (pc)))]
1676   ""
1677   "")
1679 (define_expand "beq"
1680   [(set (pc)
1681         (if_then_else (eq (cc0)
1682                           (const_int 0))
1683                       (label_ref (match_operand 0 "" ""))
1684                       (pc)))]
1685   ""
1686   "")
1688 (define_expand "bne"
1689   [(set (pc)
1690         (if_then_else (ne (cc0)
1691                           (const_int 0))
1692                       (label_ref (match_operand 0 "" ""))
1693                       (pc)))]
1694   ""
1695   "")
1697 (define_insn ""
1698   [(set (pc)
1699         (if_then_else (match_operator 1 "comparison_operator"
1700                                       [(cc0) (const_int 0)])
1701                       (label_ref (match_operand 0 "" ""))
1702                       (pc)))]
1703   ""
1704   "*
1706   if (cc_status.mdep.fpCC)
1707     return \"fb%b1 %0\";
1708   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1709       && (GET_CODE (operands[1]) == GT
1710           || GET_CODE (operands[1]) == GE
1711           || GET_CODE (operands[1]) == LE
1712           || GET_CODE (operands[1]) == LT))
1713     return 0;
1714   return \"b%b1 %0\";
1716  [(set_attr "cc" "none")])
1718 (define_insn ""
1719   [(set (pc)
1720         (if_then_else (match_operator 1 "comparison_operator"
1721                                       [(cc0) (const_int 0)])
1722                       (pc)
1723                       (label_ref (match_operand 0 "" ""))))]
1724   ""
1725   "*
1727   if (cc_status.mdep.fpCC)
1728     return \"fb%B1 %0\";
1729   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1730       && (GET_CODE (operands[1]) == GT
1731           || GET_CODE (operands[1]) == GE
1732           || GET_CODE (operands[1]) == LE
1733           || GET_CODE (operands[1]) == LT))
1734     return 0;
1735   return \"b%B1 %0\";
1737  [(set_attr "cc" "none")])
1739 ;; Unconditional and other jump instructions.
1741 (define_insn "jump"
1742   [(set (pc)
1743         (label_ref (match_operand 0 "" "")))]
1744   ""
1745   "jmp %l0"
1746  [(set_attr "cc" "none")])
1748 (define_insn "indirect_jump"
1749   [(set (pc) (match_operand:SI 0 "register_operand" "a"))]
1750   ""
1751   "jmp (%0)"
1752   [(set_attr "cc" "none")])
1754 (define_expand "builtin_setjmp_receiver"
1755   [(match_operand 0 "" "")]
1756   "flag_pic"
1757   "
1759   if (flag_pic)
1760     emit_insn (gen_GOTaddr2picreg ());
1762   DONE;
1765 (define_expand "casesi"
1766   [(match_operand:SI 0 "register_operand" "")
1767    (match_operand:SI 1 "immediate_operand" "")
1768    (match_operand:SI 2 "immediate_operand" "")
1769    (match_operand 3 "" "") (match_operand 4 "" "")]
1770   ""
1771   "
1773   rtx table = gen_reg_rtx (SImode);
1774   rtx index = gen_reg_rtx (SImode);
1775   rtx addr = gen_reg_rtx (Pmode);
1777   emit_move_insn (table, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
1778   emit_move_insn (index, plus_constant (operands[0], - INTVAL (operands[1])));
1779   emit_insn (gen_cmpsi (index, operands[2]));
1780   emit_jump_insn (gen_bgtu (operands[4]));
1781   emit_move_insn (index, gen_rtx_ASHIFT (SImode, index, const2_rtx));
1782   emit_move_insn (addr, gen_rtx_MEM (SImode,
1783                                      gen_rtx_PLUS (SImode, table, index)));
1784   if (flag_pic)
1785     emit_move_insn (addr, gen_rtx_PLUS (SImode, addr, table));
1787   emit_jump_insn (gen_tablejump (addr, operands[3]));
1788   DONE;
1791 (define_insn "tablejump"
1792   [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1793    (use (label_ref (match_operand 1 "" "")))]
1794   ""
1795   "jmp (%0)"
1796   [(set_attr "cc" "none")])
1798 ;; Call subroutine with no return value.
1800 (define_expand "call"
1801   [(call (match_operand:QI 0 "general_operand" "")
1802          (match_operand:SI 1 "general_operand" ""))]
1803   ""
1804   "
1806   if (flag_pic && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
1807     {
1808       if (MN10300_GLOBAL_P (XEXP (operands[0], 0)))
1809         {
1810           /* The PLT code won't run on AM30, but then, there's no
1811              shared library support for AM30 either, so we just assume
1812              the linker is going to adjust all @PLT relocs to the
1813              actual symbols.  */
1814           emit_use (pic_offset_table_rtx);
1815           XEXP (operands[0], 0) = gen_sym2PLT (XEXP (operands[0], 0));
1816         }
1817       else
1818         XEXP (operands[0], 0) = gen_sym2PIC (XEXP (operands[0], 0));
1819     }
1820   if (! call_address_operand (XEXP (operands[0], 0), VOIDmode))
1821     XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
1822   emit_call_insn (gen_call_internal (XEXP (operands[0], 0), operands[1]));
1823   DONE;
1826 ;; NB: Mode on match_operand 0 deliberately omitted in
1827 ;;     order to be able to match UNSPECs in PIC mode.
1828 (define_insn "call_internal"
1829   [(call (mem:QI (match_operand 0 "call_address_operand" "aS"))
1830          (match_operand:SI 1 "general_operand" "g"))]
1831   ""
1832   "*
1834   if (REG_P (operands[0]))
1835     return \"calls %C0\";
1836   else
1837     return \"call %C0,[],0\";
1839   [(set_attr "cc" "clobber")])
1841 ;; Call subroutine, returning value in operand 0
1842 ;; (which must be a hard register).
1844 (define_expand "call_value"
1845   [(set (match_operand 0 "" "")
1846         (call (match_operand:QI 1 "general_operand" "")
1847               (match_operand:SI 2 "general_operand" "")))]
1848   ""
1849   "
1851   if (flag_pic && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
1852     {
1853       if (MN10300_GLOBAL_P (XEXP (operands[1], 0)))
1854         {
1855           /* The PLT code won't run on AM30, but then, there's no
1856              shared library support for AM30 either, so we just assume
1857              the linker is going to adjust all @PLT relocs to the
1858              actual symbols.  */
1859           emit_use (pic_offset_table_rtx);
1860           XEXP (operands[1], 0) = gen_sym2PLT (XEXP (operands[1], 0));
1861         }
1862       else
1863         XEXP (operands[1], 0) = gen_sym2PIC (XEXP (operands[1], 0));
1864     }
1865   if (! call_address_operand (XEXP (operands[1], 0), VOIDmode))
1866     XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
1867   emit_call_insn (gen_call_value_internal (operands[0],
1868                                            XEXP (operands[1], 0),
1869                                            operands[2]));
1870   DONE;
1873 ;; NB: Mode on match_operands 0 and 1 deliberately omitted
1874 ;;     in order to be able to match UNSPECs in PIC mode.
1875 (define_insn "call_value_internal"
1876   [(set (match_operand               0 "register_operand" "=dax")
1877         (call (mem:QI (match_operand 1 "call_address_operand" "aS"))
1878               (match_operand:SI      2 "general_operand" "g")))]
1879   ""
1880   "*
1882   if (REG_P (operands[1]))
1883     return \"calls %C1\";
1884   else
1885     return \"call %C1,[],0\";
1887   [(set_attr "cc" "clobber")])
1889 (define_expand "untyped_call"
1890   [(parallel [(call (match_operand 0 "" "")
1891                     (const_int 0))
1892               (match_operand 1 "" "")
1893               (match_operand 2 "" "")])]
1894   ""
1895   "
1897   int i;
1899   emit_call_insn (gen_call (operands[0], const0_rtx));
1901   for (i = 0; i < XVECLEN (operands[2], 0); i++)
1902     {
1903       rtx set = XVECEXP (operands[2], 0, i);
1904       emit_move_insn (SET_DEST (set), SET_SRC (set));
1905     }
1906   DONE;
1909 (define_insn "nop"
1910   [(const_int 0)]
1911   ""
1912   "nop"
1913   [(set_attr "cc" "none")])
1915 ;; ----------------------------------------------------------------------
1916 ;; EXTEND INSTRUCTIONS
1917 ;; ----------------------------------------------------------------------
1919 (define_expand "zero_extendqisi2"
1920   [(set (match_operand:SI 0 "general_operand" "")
1921         (zero_extend:SI
1922          (match_operand:QI 1 "general_operand" "")))]
1923   ""
1924   "")
1926 (define_insn ""
1927   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx,!dax,!dax,!dax")
1928         (zero_extend:SI
1929          (match_operand:QI 1 "general_operand" "0,dax,m,0,dax,m")))]
1930   "TARGET_AM33"
1931   "@
1932   extbu %0
1933   mov %1,%0\;extbu %0
1934   movbu %1,%0
1935   extbu %0
1936   mov %1,%0\;extbu %0
1937   movbu %1,%0"
1938   [(set_attr "cc" "none_0hit")])
1940 (define_insn ""
1941   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx")
1942         (zero_extend:SI
1943          (match_operand:QI 1 "general_operand" "0,d,m")))]
1944   ""
1945   "@
1946   extbu %0
1947   mov %1,%0\;extbu %0
1948   movbu %1,%0"
1949   [(set_attr "cc" "none_0hit")])
1951 (define_expand "zero_extendhisi2"
1952   [(set (match_operand:SI 0 "general_operand" "")
1953         (zero_extend:SI
1954          (match_operand:HI 1 "general_operand" "")))]
1955   ""
1956   "")
1958 (define_insn ""
1959   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx,!dax,!dax,!dax")
1960         (zero_extend:SI
1961          (match_operand:HI 1 "general_operand" "0,dax,m,0,dax,m")))]
1962   "TARGET_AM33"
1963   "@
1964   exthu %0
1965   mov %1,%0\;exthu %0
1966   movhu %1,%0
1967   exthu %0
1968   mov %1,%0\;exthu %0
1969   movhu %1,%0"
1970   [(set_attr "cc" "none_0hit")])
1972 (define_insn ""
1973   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx")
1974         (zero_extend:SI
1975          (match_operand:HI 1 "general_operand" "0,dx,m")))]
1976   ""
1977   "@
1978   exthu %0
1979   mov %1,%0\;exthu %0
1980   movhu %1,%0"
1981   [(set_attr "cc" "none_0hit")])
1983 ;;- sign extension instructions
1985 (define_expand "extendqisi2"
1986   [(set (match_operand:SI 0 "general_operand" "")
1987         (sign_extend:SI
1988          (match_operand:QI 1 "general_operand" "")))]
1989   ""
1990   "")
1992 (define_insn ""
1993   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,!dax,!dax")
1994         (sign_extend:SI
1995          (match_operand:QI 1 "general_operand" "0,dx,0,dax")))]
1996   "TARGET_AM33"
1997   "@
1998   extb %0
1999   mov %1,%0\;extb %0
2000   extb %0
2001   mov %1,%0\;extb %0"
2002   [(set_attr "cc" "none_0hit")])
2004 (define_insn ""
2005   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx")
2006         (sign_extend:SI
2007          (match_operand:QI 1 "general_operand" "0,dx")))]
2008   ""
2009   "@
2010   extb %0
2011   mov %1,%0\;extb %0"
2012   [(set_attr "cc" "none_0hit")])
2014 (define_expand "extendhisi2"
2015   [(set (match_operand:SI 0 "general_operand" "")
2016         (sign_extend:SI
2017          (match_operand:HI 1 "general_operand" "")))]
2018   ""
2019   "")
2021 (define_insn ""
2022   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,!dax,!dax")
2023         (sign_extend:SI
2024          (match_operand:HI 1 "general_operand" "0,dax,0,dax")))]
2025   "TARGET_AM33"
2026   "@
2027   exth %0
2028   mov %1,%0\;exth %0
2029   exth %0
2030   mov %1,%0\;exth %0"
2031   [(set_attr "cc" "none_0hit")])
2033 (define_insn ""
2034   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx")
2035         (sign_extend:SI
2036          (match_operand:HI 1 "general_operand" "0,dx")))]
2037   ""
2038   "@
2039   exth %0
2040   mov %1,%0\;exth %0"
2041   [(set_attr "cc" "none_0hit")])
2043 ;; ----------------------------------------------------------------------
2044 ;; SHIFTS
2045 ;; ----------------------------------------------------------------------
2047 (define_expand "ashlsi3"
2048   [(set (match_operand:SI 0 "register_operand" "")
2049         (ashift:SI
2050          (match_operand:SI 1 "register_operand" "")
2051          (match_operand:QI 2 "nonmemory_operand" "")))]
2052   ""
2053   "")
2055 (define_insn ""
2056   [(set (match_operand:SI 0 "register_operand" "=dax,dx,!dax")
2057         (ashift:SI
2058          (match_operand:SI 1 "register_operand" "0,0,dax")
2059          (match_operand:QI 2 "nonmemory_operand" "J,dxi,dax")))]
2060   "TARGET_AM33"
2061   "*
2063   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 1)
2064     return \"add %0,%0\";
2066   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 2)
2067     return \"asl2 %0\";
2069   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 3
2070       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS)
2071     return \"asl2 %0\;add %0,%0\";
2073   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 4
2074       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS)
2075     return \"asl2 %0\;asl2 %0\";
2077   if (true_regnum (operands[1]) == true_regnum (operands[0]))
2078     return \"asl %S2,%0\";
2080   if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
2081       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
2082       && true_regnum (operands[0]) != true_regnum (operands[2]))
2083     return \"mov %1,%0\;asl %S2,%0\";
2084   return \"asl %2,%1,%0\";
2086   [(set_attr "cc" "set_zn")])
2088 (define_insn ""
2089   [(set (match_operand:SI 0 "register_operand" "=dax,dx,dx,dx,dx")
2090         (ashift:SI
2091          (match_operand:SI 1 "register_operand" "0,0,0,0,0")
2092          (match_operand:QI 2 "nonmemory_operand" "J,K,M,L,dxi")))]
2093   ""
2094   "@
2095   add %0,%0
2096   asl2 %0
2097   asl2 %0\;add %0,%0
2098   asl2 %0\;asl2 %0
2099   asl %S2,%0"
2100   [(set_attr "cc" "set_zn")])
2102 (define_expand "lshrsi3"
2103   [(set (match_operand:SI 0 "register_operand" "")
2104         (lshiftrt:SI
2105          (match_operand:SI 1 "register_operand" "")
2106          (match_operand:QI 2 "nonmemory_operand" "")))]
2107   ""
2108   "")
2110 (define_insn ""
2111   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
2112         (lshiftrt:SI
2113          (match_operand:SI 1 "register_operand" "0,dax")
2114          (match_operand:QI 2 "nonmemory_operand" "dxi,dax")))]
2115   "TARGET_AM33"
2116   "*
2118   if (true_regnum (operands[1]) == true_regnum (operands[0]))
2119     return \"lsr %S2,%0\";
2121   if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
2122       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
2123       && true_regnum (operands[0]) != true_regnum (operands[2]))
2124     return \"mov %1,%0\;lsr %S2,%0\";
2125   return \"lsr %2,%1,%0\";
2127   [(set_attr "cc" "set_zn")])
2129 (define_insn ""
2130   [(set (match_operand:SI 0 "register_operand" "=dx")
2131         (lshiftrt:SI
2132          (match_operand:SI 1 "register_operand" "0")
2133          (match_operand:QI 2 "nonmemory_operand" "dxi")))]
2134   ""
2135   "lsr %S2,%0"
2136   [(set_attr "cc" "set_zn")])
2138 (define_expand "ashrsi3"
2139   [(set (match_operand:SI 0 "register_operand" "")
2140         (ashiftrt:SI
2141          (match_operand:SI 1 "register_operand" "")
2142          (match_operand:QI 2 "nonmemory_operand" "")))]
2143   ""
2144   "")
2146 (define_insn ""
2147   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
2148         (ashiftrt:SI
2149          (match_operand:SI 1 "register_operand" "0,dax")
2150          (match_operand:QI 2 "nonmemory_operand" "dxi,dax")))]
2151   "TARGET_AM33"
2152   "*
2154   if (true_regnum (operands[1]) == true_regnum (operands[0]))
2155     return \"asr %S2,%0\";
2157   if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
2158       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
2159       && true_regnum (operands[0]) != true_regnum (operands[2]))
2160     return \"mov %1,%0\;asr %S2,%0\";
2161   return \"asr %2,%1,%0\";
2163   [(set_attr "cc" "set_zn")])
2165 (define_insn ""
2166   [(set (match_operand:SI 0 "register_operand" "=dx")
2167         (ashiftrt:SI
2168          (match_operand:SI 1 "register_operand" "0")
2169          (match_operand:QI 2 "nonmemory_operand" "dxi")))]
2170   ""
2171   "asr %S2,%0"
2172   [(set_attr "cc" "set_zn")])
2174 ;; ----------------------------------------------------------------------
2175 ;; FP INSTRUCTIONS
2176 ;; ----------------------------------------------------------------------
2178 ;; The mn103 series does not have floating point instructions, but since
2179 ;; FP values are held in integer regs, we can clear the high bit easily
2180 ;; which gives us an efficient inline floating point absolute value.
2182 ;; Similarly for negation of a FP value.
2185 (define_expand "absdf2"
2186   [(set (match_operand:DF 0 "register_operand" "")
2187         (abs:DF (match_operand:DF 1 "register_operand" "")))]
2188   ""
2189   "
2191   rtx target, result, insns;
2193   start_sequence ();
2194   target = operand_subword (operands[0], 1, 1, DFmode);
2195   result = expand_binop (SImode, and_optab,
2196                          operand_subword_force (operands[1], 1, DFmode),
2197                          GEN_INT (0x7fffffff), target, 0, OPTAB_WIDEN);
2199   gcc_assert (result);
2201   if (result != target)
2202     emit_move_insn (result, target);
2204   emit_move_insn (operand_subword (operands[0], 0, 1, DFmode),
2205                   operand_subword_force (operands[1], 0, DFmode));
2207   insns = get_insns ();
2208   end_sequence ();
2210   emit_insn (insns);
2211   DONE;
2214 (define_expand "abssf2"
2215   [(set (match_operand:SF 0 "register_operand" "")
2216         (abs:SF (match_operand:SF 1 "register_operand" "")))]
2217   ""
2218   "
2220   rtx result;
2221   rtx target;
2223   if (TARGET_AM33_2)
2224     {
2225       emit_insn (gen_abssf2_am33_2 (operands[0], operands[1]));
2226       DONE;
2227     }
2229   target = operand_subword_force (operands[0], 0, SFmode);
2230   result = expand_binop (SImode, and_optab,
2231                          operand_subword_force (operands[1], 0, SFmode),
2232                          GEN_INT (0x7fffffff), target, 0, OPTAB_WIDEN);
2233   gcc_assert (result);
2235   if (result != target)
2236     emit_move_insn (result, target);
2238   /* Make a place for REG_EQUAL.  */
2239   emit_move_insn (operands[0], operands[0]);
2240   DONE;
2244 (define_insn "abssf2_am33_2"
2245   [(set (match_operand:SF 0 "register_operand" "=f,f")
2246         (abs:SF (match_operand:SF 1 "register_operand" "0,?f")))]
2247   "TARGET_AM33_2"
2248   "@
2249    fabs %0
2250    fabs %1, %0"
2251   [(set_attr "cc" "none_0hit")])
2253 (define_expand "negdf2"
2254   [(set (match_operand:DF 0 "register_operand" "")
2255         (neg:DF (match_operand:DF 1 "register_operand" "")))]
2256   ""
2257   "
2259   rtx target, result, insns;
2261   start_sequence ();
2262   target = operand_subword (operands[0], 1, 1, DFmode);
2263   result = expand_binop (SImode, xor_optab,
2264                          operand_subword_force (operands[1], 1, DFmode),
2265                          GEN_INT (trunc_int_for_mode (0x80000000, SImode)),
2266                          target, 0, OPTAB_WIDEN);
2268   gcc_assert (result);
2270   if (result != target)
2271     emit_move_insn (result, target);
2273   emit_move_insn (operand_subword (operands[0], 0, 1, DFmode),
2274                   operand_subword_force (operands[1], 0, DFmode));
2276   insns = get_insns ();
2277   end_sequence ();
2279   emit_insn (insns);
2280   DONE;
2283 (define_expand "negsf2"
2284   [(set (match_operand:SF 0 "register_operand" "")
2285         (neg:SF (match_operand:SF 1 "register_operand" "")))]
2286   ""
2287   "
2289   rtx result;
2290   rtx target;
2292   if (TARGET_AM33_2)
2293     {
2294       emit_insn (gen_negsf2_am33_2 (operands[0], operands[1]));
2295       DONE;
2296     }
2298   target = operand_subword_force (operands[0], 0, SFmode);
2299   result = expand_binop (SImode, xor_optab,
2300                          operand_subword_force (operands[1], 0, SFmode),
2301                          GEN_INT (trunc_int_for_mode (0x80000000, SImode)),
2302                          target, 0, OPTAB_WIDEN);
2303   gcc_assert (result);
2305   if (result != target)
2306     emit_move_insn (result, target);
2308   /* Make a place for REG_EQUAL.  */
2309   emit_move_insn (operands[0], operands[0]);
2310   DONE;
2313 (define_insn "negsf2_am33_2"
2314   [(set (match_operand:SF 0 "register_operand" "=f,f")
2315         (neg:SF (match_operand:SF 1 "register_operand" "0,?f")))]
2316   "TARGET_AM33_2"
2317   "@
2318    fneg %0
2319    fneg %1, %0"
2320   [(set_attr "cc" "none_0hit")])
2322 (define_expand "sqrtsf2"
2323   [(set (match_operand:SF 0 "register_operand" "")
2324         (sqrt:SF (match_operand:SF 1 "register_operand" "")))]
2325   "TARGET_AM33_2 && flag_unsafe_math_optimizations"
2326   "
2328   rtx scratch = gen_reg_rtx (SFmode);
2329   emit_insn (gen_rsqrtsf2 (scratch, operands[1], CONST1_RTX (SFmode)));
2330   emit_insn (gen_divsf3 (operands[0], force_reg (SFmode, CONST1_RTX (SFmode)),
2331                          scratch));
2332   DONE;
2335 (define_insn "rsqrtsf2"
2336   [(set (match_operand:SF 0 "register_operand" "=f,f")
2337         (div:SF (match_operand:SF 2 "const_1f_operand" "F,F")
2338                 (sqrt:SF (match_operand:SF 1 "register_operand" "0,?f"))))]
2339   "TARGET_AM33_2"
2340   "@
2341    frsqrt %0
2342    frsqrt %1, %0"
2343   [(set_attr "cc" "none_0hit")])
2345 (define_insn "addsf3"
2346   [(set (match_operand:SF 0 "register_operand" "=f,f")
2347         (plus:SF (match_operand:SF 1 "register_operand" "%0,f")
2348                  (match_operand:SF 2 "general_operand" "f,?fF")))]
2349   "TARGET_AM33_2"
2350   "@
2351    fadd %2, %0
2352    fadd %2, %1, %0"
2353   [(set_attr "cc" "none_0hit")])
2355 (define_insn "subsf3"
2356   [(set (match_operand:SF 0 "register_operand" "=f,f")
2357         (minus:SF (match_operand:SF 1 "register_operand" "0,f")
2358                   (match_operand:SF 2 "general_operand" "f,?fF")))]
2359   "TARGET_AM33_2"
2360   "@
2361    fsub %2, %0
2362    fsub %2, %1, %0"
2363   [(set_attr "cc" "none_0hit")])
2365 (define_insn "mulsf3"
2366   [(set (match_operand:SF 0 "register_operand" "=f,f")
2367         (mult:SF (match_operand:SF 1 "register_operand" "%0,f")
2368                  (match_operand:SF 2 "general_operand" "f,?fF")))]
2369   "TARGET_AM33_2"
2370   "@
2371    fmul %2, %0
2372    fmul %2, %1, %0"
2373   [(set_attr "cc" "none_0hit")])
2375 (define_insn "divsf3"
2376   [(set (match_operand:SF 0 "register_operand" "=f,f")
2377         (div:SF (match_operand:SF 1 "register_operand" "0,f")
2378                 (match_operand:SF 2 "general_operand" "f,?fF")))]
2379   "TARGET_AM33_2"
2380   "@
2381    fdiv %2, %0
2382    fdiv %2, %1, %0"
2383   [(set_attr "cc" "none_0hit")])
2385 (define_insn "fmaddsf4"
2386   [(set (match_operand:SF 0 "register_operand" "=A")
2387         (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
2388                           (match_operand:SF 2 "register_operand" "f"))
2389                  (match_operand:SF 3 "register_operand" "f")))]
2390   "TARGET_AM33_2"
2391   "fmadd %1, %2, %3, %0"
2392   [(set_attr "cc" "none_0hit")])
2394 (define_insn "fmsubsf4"
2395   [(set (match_operand:SF 0 "register_operand" "=A")
2396         (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
2397                            (match_operand:SF 2 "register_operand" "f"))
2398                   (match_operand:SF 3 "register_operand" "f")))]
2399   "TARGET_AM33_2"
2400   "fmsub %1, %2, %3, %0"
2401   [(set_attr "cc" "none_0hit")])
2403 (define_insn "fnmaddsf4"
2404   [(set (match_operand:SF 0 "register_operand" "=A")
2405         (minus:SF (match_operand:SF 3 "register_operand" "f")
2406                   (mult:SF (match_operand:SF 1 "register_operand" "%f")
2407                            (match_operand:SF 2 "register_operand" "f"))))]
2408   "TARGET_AM33_2"
2409   "fnmadd %1, %2, %3, %0"
2410   [(set_attr "cc" "none_0hit")])
2412 (define_insn "fnmsubsf4"
2413   [(set (match_operand:SF 0 "register_operand" "=A")
2414         (minus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
2415                                    (match_operand:SF 2 "register_operand" "f")))
2416                   (match_operand:SF 3 "register_operand" "f")))]
2417   "TARGET_AM33_2"
2418   "fnmsub %1, %2, %3, %0"
2419   [(set_attr "cc" "none_0hit")])
2422 ;; ----------------------------------------------------------------------
2423 ;; PROLOGUE/EPILOGUE
2424 ;; ----------------------------------------------------------------------
2425 (define_expand "prologue"
2426   [(const_int 0)]
2427   ""
2428   "expand_prologue (); DONE;")
2430 (define_expand "epilogue"
2431   [(return)]
2432   ""
2433   "
2435   expand_epilogue ();
2436   DONE;
2439 (define_insn "return_internal"
2440   [(const_int 2)
2441    (return)]
2442   ""
2443   "rets"
2444   [(set_attr "cc" "clobber")])
2446 ;; This insn restores the callee saved registers and does a return, it
2447 ;; can also deallocate stack space.
2448 (define_insn "return_internal_regs"
2449   [(const_int 0)
2450    (match_operand:SI 0  "const_int_operand" "i")
2451    (return)]
2452   ""
2453   "*
2455   fputs (\"\\tret \", asm_out_file);
2456   mn10300_print_reg_list (asm_out_file, mn10300_get_live_callee_saved_regs ());
2457   fprintf (asm_out_file, \",%d\\n\", (int) INTVAL (operands[0]));
2458   return \"\";
2460   [(set_attr "cc" "clobber")])
2462 ;; This instruction matches one generated by mn10300_gen_multiple_store()
2463 (define_insn "store_movm"
2464   [(match_parallel 0 "store_multiple_operation"
2465     [(set (reg:SI 9) (plus:SI (reg:SI 9) (match_operand 1 "" "")))])]
2466   ""
2467   "*
2469   fputs (\"\\tmovm \", asm_out_file);
2470   mn10300_print_reg_list (asm_out_file,
2471                           store_multiple_operation (operands[0], VOIDmode));
2472   fprintf (asm_out_file, \",(sp)\\n\");
2473   return \"\";
2475   [(set_attr "cc" "clobber")])
2477 (define_insn "return"
2478   [(return)]
2479   "can_use_return_insn ()"
2480   "*
2482   rtx next = next_active_insn (insn);
2484   if (next
2485       && GET_CODE (next) == JUMP_INSN
2486       && GET_CODE (PATTERN (next)) == RETURN)
2487     return \"\";
2488   else
2489     return \"rets\";
2491   [(set_attr "cc" "clobber")])
2493 ;; Try to combine consecutive updates of the stack pointer (or any
2494 ;; other register for that matter).
2495 (define_peephole
2496   [(set (match_operand:SI 0 "register_operand" "=dxay")
2497         (plus:SI (match_dup 0)
2498                  (match_operand 1 "const_int_operand" "")))
2499    (set (match_dup 0)
2500         (plus:SI (match_dup 0)
2501                  (match_operand 2 "const_int_operand" "")))]
2502   ""
2503   "*
2505   operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]));
2506   return \"add %1,%0\";
2508   [(set_attr "cc" "clobber")])
2511 ;; We had patterns to check eq/ne, but the they don't work because
2512 ;; 0x80000000 + 0x80000000 = 0x0 with a carry out.
2514 ;; The Z flag and C flag would be set, and we have no way to
2515 ;; check for the Z flag set and C flag clear.
2517 ;; This will work on the mn10200 because we can check the ZX flag
2518 ;; if the comparison is in HImode.
2519 (define_peephole
2520   [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2521    (set (pc) (if_then_else (ge (cc0) (const_int 0))
2522                            (match_operand 1 "" "")
2523                            (pc)))]
2524   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2525   "add %0,%0\;bcc %1"
2526   [(set_attr "cc" "clobber")])
2528 (define_peephole
2529   [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2530    (set (pc) (if_then_else (lt (cc0) (const_int 0))
2531                            (match_operand 1 "" "")
2532                            (pc)))]
2533   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2534   "add %0,%0\;bcs %1"
2535   [(set_attr "cc" "clobber")])
2537 (define_peephole
2538   [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2539    (set (pc) (if_then_else (ge (cc0) (const_int 0))
2540                            (pc)
2541                            (match_operand 1 "" "")))]
2542   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2543   "add %0,%0\;bcs %1"
2544   [(set_attr "cc" "clobber")])
2546 (define_peephole
2547   [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2548    (set (pc) (if_then_else (lt (cc0) (const_int 0))
2549                            (pc)
2550                            (match_operand 1 "" "")))]
2551   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2552   "add %0,%0\;bcc %1"
2553   [(set_attr "cc" "clobber")])
2555 (define_expand "int_label"
2556   [(unspec [(match_operand:SI 0 "" "")] UNSPEC_INT_LABEL)]
2557   "" "")
2559 (define_expand "GOTaddr2picreg"
2560   [(match_dup 0)]
2561   "" "
2563   /* It would be nice to be able to have int_label keep track of the
2564      counter and all, but if we add C code to it, we'll get an insn
2565      back, and we just want the pattern.  */
2566   operands[0] = gen_int_label (GEN_INT (mn10300_unspec_int_label_counter++));
2567   if (TARGET_AM33)
2568     emit_insn (gen_am33_loadPC (operands[0]));
2569   else
2570     emit_insn (gen_mn10300_loadPC (operands[0]));
2571   emit_insn (gen_add_GOT_to_pic_reg (copy_rtx (operands[0])));
2572   DONE;
2576 (define_insn "am33_loadPC"
2577   [(parallel
2578     [(set (reg:SI PIC_REG) (pc))
2579      (use (match_operand 0 "" ""))])]
2580   "TARGET_AM33"
2581   "%0:\;mov pc,a2")
2584 (define_insn_and_split "mn10300_loadPC"
2585   [(parallel
2586     [(set (reg:SI PIC_REG) (pc))
2587      (use (match_operand 0 "" ""))])]
2588   ""
2589   "#"
2590   "reload_completed"
2591   [(match_operand 0 "" "")]
2592   "
2594   rtx sp_reg = gen_rtx_REG (SImode, SP_REG);
2595   int need_stack_space = (get_frame_size () == 0
2596                           && crtl->outgoing_args_size == 0);
2598   if (need_stack_space)
2599     emit_move_insn (sp_reg, plus_constant (sp_reg, -4));
2601   emit_insn (gen_call_next_insn (operands[0]));
2603   if (need_stack_space)
2604     emit_insn (gen_pop_pic_reg ());
2605   else
2606     emit_move_insn (pic_offset_table_rtx, gen_rtx_MEM (SImode, sp_reg));
2608   DONE;
2611 (define_insn "call_next_insn"
2612   [(parallel
2613     [(set (mem:SI (reg:SI SP_REG)) (pc))
2614      (use (match_operand 0 "" ""))])]
2615   "reload_completed"
2616   "calls %0\;%0:")
2618 (define_expand "add_GOT_to_pic_reg"
2619   [(set (reg:SI PIC_REG)
2620         (plus:SI
2621          (reg:SI PIC_REG)
2622          (const
2623           (unspec [(minus:SI
2624                     (match_dup 1)
2625                     (const (minus:SI
2626                             (const (match_operand:SI 0 "" ""))
2627                             (pc))))
2628                   ] UNSPEC_PIC))))]
2629   ""
2630   "
2632   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
2635 (define_expand "symGOT2reg"
2636   [(match_operand:SI 0 "" "")
2637    (match_operand:SI 1 "" "")]
2638   ""
2639   "
2641   rtx insn = emit_insn (gen_symGOT2reg_i (operands[0], operands[1]));
2643   MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
2645   set_unique_reg_note (insn, REG_EQUAL, operands[1]);
2647   DONE;
2650 (define_expand "symGOT2reg_i"
2651   [(set (match_operand:SI 0 "" "")
2652         (mem:SI (plus:SI (reg:SI PIC_REG)
2653                          (const (unspec [(match_operand:SI 1 "" "")]
2654                                         UNSPEC_GOT)))))]
2655   ""
2656   "")
2658 (define_expand "symGOTOFF2reg"
2659   [(match_operand:SI 0 "" "") (match_operand:SI 1 "" "")]
2660   ""
2661   "
2663   rtx insn = emit_insn (gen_symGOTOFF2reg_i (operands[0], operands[1]));
2665   set_unique_reg_note (insn, REG_EQUAL, operands[1]);
2667   DONE;
2670 (define_expand "symGOTOFF2reg_i"
2671   [(set (match_operand:SI 0 "" "")
2672         (const (unspec [(match_operand:SI 1 "" "")] UNSPEC_GOTOFF)))
2673   (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI PIC_REG)))]
2674   ""
2675   "")
2677 (define_expand "sym2PIC"
2678   [(unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC)]
2679   "" "")
2681 (define_expand "sym2PLT"
2682   [(unspec [(match_operand:SI 0 "" "")] UNSPEC_PLT)]
2683   "" "")