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