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