OSDN Git Service

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