OSDN Git Service

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