OSDN Git Service

* config/mn10300/mn10300.md: (call_internal): Remove mode on
[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 ;; NB: Mode on match_operand 0 deliberately omitted in
1823 ;;     order to be able to match UNSPECs in PIC mode.
1824 (define_insn "call_internal"
1825   [(call (mem:QI (match_operand 0 "call_address_operand" "aS"))
1826          (match_operand:SI 1 "general_operand" "g"))]
1827   ""
1828   "*
1829 {
1830   if (REG_P (operands[0]))
1831     return \"calls %C0\";
1832   else
1833     return \"call %C0,[],0\";
1834 }"
1835   [(set_attr "cc" "clobber")])
1836
1837 ;; Call subroutine, returning value in operand 0
1838 ;; (which must be a hard register).
1839
1840 (define_expand "call_value"
1841   [(set (match_operand 0 "" "")
1842         (call (match_operand:QI 1 "general_operand" "")
1843               (match_operand:SI 2 "general_operand" "")))]
1844   ""
1845   "
1846 {
1847   if (flag_pic && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
1848     {
1849       if (MN10300_GLOBAL_P (XEXP (operands[1], 0)))
1850         {
1851           /* The PLT code won't run on AM30, but then, there's no
1852              shared library support for AM30 either, so we just assume
1853              the linker is going to adjust all @PLT relocs to the
1854              actual symbols.  */
1855           emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
1856           XEXP (operands[1], 0) = gen_sym2PLT (XEXP (operands[1], 0));
1857         }
1858       else
1859         XEXP (operands[1], 0) = gen_sym2PIC (XEXP (operands[1], 0));
1860     }
1861   if (! call_address_operand (XEXP (operands[1], 0), VOIDmode))
1862     XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
1863   emit_call_insn (gen_call_value_internal (operands[0],
1864                                            XEXP (operands[1], 0),
1865                                            operands[2]));
1866   DONE;
1867 }")
1868
1869 ;; NB: Mode on match_operands 0 and 1 deliberately omitted
1870 ;;     in order to be able to match UNSPECs in PIC mode.
1871 (define_insn "call_value_internal"
1872   [(set (match_operand               0 "register_operand" "=dax")
1873         (call (mem:QI (match_operand 1 "call_address_operand" "aS"))
1874               (match_operand:SI      2 "general_operand" "g")))]
1875   ""
1876   "*
1877 {
1878   if (REG_P (operands[1]))
1879     return \"calls %C1\";
1880   else
1881     return \"call %C1,[],0\";
1882 }"
1883   [(set_attr "cc" "clobber")])
1884
1885 (define_expand "untyped_call"
1886   [(parallel [(call (match_operand 0 "" "")
1887                     (const_int 0))
1888               (match_operand 1 "" "")
1889               (match_operand 2 "" "")])]
1890   ""
1891   "
1892 {
1893   int i;
1894
1895   emit_call_insn (gen_call (operands[0], const0_rtx));
1896
1897   for (i = 0; i < XVECLEN (operands[2], 0); i++)
1898     {
1899       rtx set = XVECEXP (operands[2], 0, i);
1900       emit_move_insn (SET_DEST (set), SET_SRC (set));
1901     }
1902   DONE;
1903 }")
1904
1905 (define_insn "nop"
1906   [(const_int 0)]
1907   ""
1908   "nop"
1909   [(set_attr "cc" "none")])
1910 \f
1911 ;; ----------------------------------------------------------------------
1912 ;; EXTEND INSTRUCTIONS
1913 ;; ----------------------------------------------------------------------
1914
1915 (define_expand "zero_extendqisi2"
1916   [(set (match_operand:SI 0 "general_operand" "")
1917         (zero_extend:SI
1918          (match_operand:QI 1 "general_operand" "")))]
1919   ""
1920   "")
1921
1922 (define_insn ""
1923   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx,!dax,!dax,!dax")
1924         (zero_extend:SI
1925          (match_operand:QI 1 "general_operand" "0,dax,m,0,dax,m")))]
1926   "TARGET_AM33"
1927   "@
1928   extbu %0
1929   mov %1,%0\;extbu %0
1930   movbu %1,%0
1931   extbu %0
1932   mov %1,%0\;extbu %0
1933   movbu %1,%0"
1934   [(set_attr "cc" "none_0hit")])
1935
1936 (define_insn ""
1937   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx")
1938         (zero_extend:SI
1939          (match_operand:QI 1 "general_operand" "0,d,m")))]
1940   ""
1941   "@
1942   extbu %0
1943   mov %1,%0\;extbu %0
1944   movbu %1,%0"
1945   [(set_attr "cc" "none_0hit")])
1946
1947 (define_expand "zero_extendhisi2"
1948   [(set (match_operand:SI 0 "general_operand" "")
1949         (zero_extend:SI
1950          (match_operand:HI 1 "general_operand" "")))]
1951   ""
1952   "")
1953
1954 (define_insn ""
1955   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx,!dax,!dax,!dax")
1956         (zero_extend:SI
1957          (match_operand:HI 1 "general_operand" "0,dax,m,0,dax,m")))]
1958   "TARGET_AM33"
1959   "@
1960   exthu %0
1961   mov %1,%0\;exthu %0
1962   movhu %1,%0
1963   exthu %0
1964   mov %1,%0\;exthu %0
1965   movhu %1,%0"
1966   [(set_attr "cc" "none_0hit")])
1967
1968 (define_insn ""
1969   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx")
1970         (zero_extend:SI
1971          (match_operand:HI 1 "general_operand" "0,dx,m")))]
1972   ""
1973   "@
1974   exthu %0
1975   mov %1,%0\;exthu %0
1976   movhu %1,%0"
1977   [(set_attr "cc" "none_0hit")])
1978
1979 ;;- sign extension instructions
1980
1981 (define_expand "extendqisi2"
1982   [(set (match_operand:SI 0 "general_operand" "")
1983         (sign_extend:SI
1984          (match_operand:QI 1 "general_operand" "")))]
1985   ""
1986   "")
1987
1988 (define_insn ""
1989   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,!dax,!dax")
1990         (sign_extend:SI
1991          (match_operand:QI 1 "general_operand" "0,dx,0,dax")))]
1992   "TARGET_AM33"
1993   "@
1994   extb %0
1995   mov %1,%0\;extb %0
1996   extb %0
1997   mov %1,%0\;extb %0"
1998   [(set_attr "cc" "none_0hit")])
1999
2000 (define_insn ""
2001   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx")
2002         (sign_extend:SI
2003          (match_operand:QI 1 "general_operand" "0,dx")))]
2004   ""
2005   "@
2006   extb %0
2007   mov %1,%0\;extb %0"
2008   [(set_attr "cc" "none_0hit")])
2009
2010 (define_expand "extendhisi2"
2011   [(set (match_operand:SI 0 "general_operand" "")
2012         (sign_extend:SI
2013          (match_operand:HI 1 "general_operand" "")))]
2014   ""
2015   "")
2016
2017 (define_insn ""
2018   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,!dax,!dax")
2019         (sign_extend:SI
2020          (match_operand:HI 1 "general_operand" "0,dax,0,dax")))]
2021   "TARGET_AM33"
2022   "@
2023   exth %0
2024   mov %1,%0\;exth %0
2025   exth %0
2026   mov %1,%0\;exth %0"
2027   [(set_attr "cc" "none_0hit")])
2028
2029 (define_insn ""
2030   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx")
2031         (sign_extend:SI
2032          (match_operand:HI 1 "general_operand" "0,dx")))]
2033   ""
2034   "@
2035   exth %0
2036   mov %1,%0\;exth %0"
2037   [(set_attr "cc" "none_0hit")])
2038 \f
2039 ;; ----------------------------------------------------------------------
2040 ;; SHIFTS
2041 ;; ----------------------------------------------------------------------
2042
2043 (define_expand "ashlsi3"
2044   [(set (match_operand:SI 0 "register_operand" "")
2045         (ashift:SI
2046          (match_operand:SI 1 "register_operand" "")
2047          (match_operand:QI 2 "nonmemory_operand" "")))]
2048   ""
2049   "")
2050
2051 (define_insn ""
2052   [(set (match_operand:SI 0 "register_operand" "=dax,dx,!dax")
2053         (ashift:SI
2054          (match_operand:SI 1 "register_operand" "0,0,dax")
2055          (match_operand:QI 2 "nonmemory_operand" "J,dxi,dax")))]
2056   "TARGET_AM33"
2057   "*
2058 {
2059   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 1)
2060     return \"add %0,%0\";
2061
2062   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 2)
2063     return \"asl2 %0\";
2064
2065   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 3
2066       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS)
2067     return \"asl2 %0\;add %0,%0\";
2068
2069   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 4
2070       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS)
2071     return \"asl2 %0\;asl2 %0\";
2072
2073   if (true_regnum (operands[1]) == true_regnum (operands[0]))
2074     return \"asl %S2,%0\";
2075
2076   if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
2077       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
2078       && true_regnum (operands[0]) != true_regnum (operands[2]))
2079     return \"mov %1,%0\;asl %S2,%0\";
2080   return \"asl %2,%1,%0\";
2081 }"
2082   [(set_attr "cc" "set_zn")])
2083
2084 (define_insn ""
2085   [(set (match_operand:SI 0 "register_operand" "=dax,dx,dx,dx,dx")
2086         (ashift:SI
2087          (match_operand:SI 1 "register_operand" "0,0,0,0,0")
2088          (match_operand:QI 2 "nonmemory_operand" "J,K,M,L,dxi")))]
2089   ""
2090   "@
2091   add %0,%0
2092   asl2 %0
2093   asl2 %0\;add %0,%0
2094   asl2 %0\;asl2 %0
2095   asl %S2,%0"
2096   [(set_attr "cc" "set_zn")])
2097
2098 (define_expand "lshrsi3"
2099   [(set (match_operand:SI 0 "register_operand" "")
2100         (lshiftrt:SI
2101          (match_operand:SI 1 "register_operand" "")
2102          (match_operand:QI 2 "nonmemory_operand" "")))]
2103   ""
2104   "")
2105
2106 (define_insn ""
2107   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
2108         (lshiftrt:SI
2109          (match_operand:SI 1 "register_operand" "0,dax")
2110          (match_operand:QI 2 "nonmemory_operand" "dxi,dax")))]
2111   "TARGET_AM33"
2112   "*
2113 {
2114   if (true_regnum (operands[1]) == true_regnum (operands[0]))
2115     return \"lsr %S2,%0\";
2116
2117   if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
2118       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
2119       && true_regnum (operands[0]) != true_regnum (operands[2]))
2120     return \"mov %1,%0\;lsr %S2,%0\";
2121   return \"lsr %2,%1,%0\";
2122 }"
2123   [(set_attr "cc" "set_zn")])
2124
2125 (define_insn ""
2126   [(set (match_operand:SI 0 "register_operand" "=dx")
2127         (lshiftrt:SI
2128          (match_operand:SI 1 "register_operand" "0")
2129          (match_operand:QI 2 "nonmemory_operand" "dxi")))]
2130   ""
2131   "lsr %S2,%0"
2132   [(set_attr "cc" "set_zn")])
2133
2134 (define_expand "ashrsi3"
2135   [(set (match_operand:SI 0 "register_operand" "")
2136         (ashiftrt:SI
2137          (match_operand:SI 1 "register_operand" "")
2138          (match_operand:QI 2 "nonmemory_operand" "")))]
2139   ""
2140   "")
2141
2142 (define_insn ""
2143   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
2144         (ashiftrt:SI
2145          (match_operand:SI 1 "register_operand" "0,dax")
2146          (match_operand:QI 2 "nonmemory_operand" "dxi,dax")))]
2147   "TARGET_AM33"
2148   "*
2149 {
2150   if (true_regnum (operands[1]) == true_regnum (operands[0]))
2151     return \"asr %S2,%0\";
2152
2153   if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
2154       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
2155       && true_regnum (operands[0]) != true_regnum (operands[2]))
2156     return \"mov %1,%0\;asr %S2,%0\";
2157   return \"asr %2,%1,%0\";
2158 }"
2159   [(set_attr "cc" "set_zn")])
2160
2161 (define_insn ""
2162   [(set (match_operand:SI 0 "register_operand" "=dx")
2163         (ashiftrt:SI
2164          (match_operand:SI 1 "register_operand" "0")
2165          (match_operand:QI 2 "nonmemory_operand" "dxi")))]
2166   ""
2167   "asr %S2,%0"
2168   [(set_attr "cc" "set_zn")])
2169
2170 ;; ----------------------------------------------------------------------
2171 ;; FP INSTRUCTIONS
2172 ;; ----------------------------------------------------------------------
2173 ;;
2174 ;; The mn103 series does not have floating point instructions, but since
2175 ;; FP values are held in integer regs, we can clear the high bit easily
2176 ;; which gives us an efficient inline floating point absolute value.
2177 ;;
2178 ;; Similarly for negation of a FP value.
2179 ;;
2180
2181 (define_expand "absdf2"
2182   [(set (match_operand:DF 0 "register_operand" "")
2183         (abs:DF (match_operand:DF 1 "register_operand" "")))]
2184   ""
2185   "
2186 {
2187   rtx target, result, insns;
2188
2189   start_sequence ();
2190   target = operand_subword (operands[0], 1, 1, DFmode);
2191   result = expand_binop (SImode, and_optab,
2192                          operand_subword_force (operands[1], 1, DFmode),
2193                          GEN_INT (0x7fffffff), target, 0, OPTAB_WIDEN);
2194
2195   gcc_assert (result);
2196
2197   if (result != target)
2198     emit_move_insn (result, target);
2199
2200   emit_move_insn (operand_subword (operands[0], 0, 1, DFmode),
2201                   operand_subword_force (operands[1], 0, DFmode));
2202
2203   insns = get_insns ();
2204   end_sequence ();
2205
2206   emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
2207   DONE;
2208 }")
2209
2210 (define_expand "abssf2"
2211   [(set (match_operand:SF 0 "register_operand" "")
2212         (abs:SF (match_operand:SF 1 "register_operand" "")))]
2213   ""
2214   "
2215 {
2216   rtx result;
2217   rtx target;
2218
2219   if (TARGET_AM33_2)
2220     {
2221       emit_insn (gen_abssf2_am33_2 (operands[0], operands[1]));
2222       DONE;
2223     }
2224
2225   target = operand_subword_force (operands[0], 0, SFmode);
2226   result = expand_binop (SImode, and_optab,
2227                          operand_subword_force (operands[1], 0, SFmode),
2228                          GEN_INT (0x7fffffff), target, 0, OPTAB_WIDEN);
2229   gcc_assert (result);
2230
2231   if (result != target)
2232     emit_move_insn (result, target);
2233
2234   /* Make a place for REG_EQUAL.  */
2235   emit_move_insn (operands[0], operands[0]);
2236   DONE;
2237 }")
2238
2239
2240 (define_insn "abssf2_am33_2"
2241   [(set (match_operand:SF 0 "register_operand" "=f,f")
2242         (abs:SF (match_operand:SF 1 "register_operand" "0,?f")))]
2243   "TARGET_AM33_2"
2244   "@
2245    fabs %0
2246    fabs %1, %0"
2247   [(set_attr "cc" "none_0hit")])
2248
2249 (define_expand "negdf2"
2250   [(set (match_operand:DF 0 "register_operand" "")
2251         (neg:DF (match_operand:DF 1 "register_operand" "")))]
2252   ""
2253   "
2254 {
2255   rtx target, result, insns;
2256
2257   start_sequence ();
2258   target = operand_subword (operands[0], 1, 1, DFmode);
2259   result = expand_binop (SImode, xor_optab,
2260                          operand_subword_force (operands[1], 1, DFmode),
2261                          GEN_INT (trunc_int_for_mode (0x80000000, SImode)),
2262                          target, 0, OPTAB_WIDEN);
2263
2264   gcc_assert (result);
2265
2266   if (result != target)
2267     emit_move_insn (result, target);
2268
2269   emit_move_insn (operand_subword (operands[0], 0, 1, DFmode),
2270                   operand_subword_force (operands[1], 0, DFmode));
2271
2272   insns = get_insns ();
2273   end_sequence ();
2274
2275   emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
2276   DONE;
2277 }")
2278
2279 (define_expand "negsf2"
2280   [(set (match_operand:SF 0 "register_operand" "")
2281         (neg:SF (match_operand:SF 1 "register_operand" "")))]
2282   ""
2283   "
2284 {
2285   rtx result;
2286   rtx target;
2287
2288   if (TARGET_AM33_2)
2289     {
2290       emit_insn (gen_negsf2_am33_2 (operands[0], operands[1]));
2291       DONE;
2292     }
2293
2294   target = operand_subword_force (operands[0], 0, SFmode);
2295   result = expand_binop (SImode, xor_optab,
2296                          operand_subword_force (operands[1], 0, SFmode),
2297                          GEN_INT (trunc_int_for_mode (0x80000000, SImode)),
2298                          target, 0, OPTAB_WIDEN);
2299   gcc_assert (result);
2300
2301   if (result != target)
2302     emit_move_insn (result, target);
2303
2304   /* Make a place for REG_EQUAL.  */
2305   emit_move_insn (operands[0], operands[0]);
2306   DONE;
2307 }")
2308
2309 (define_insn "negsf2_am33_2"
2310   [(set (match_operand:SF 0 "register_operand" "=f,f")
2311         (neg:SF (match_operand:SF 1 "register_operand" "0,?f")))]
2312   "TARGET_AM33_2"
2313   "@
2314    fneg %0
2315    fneg %1, %0"
2316   [(set_attr "cc" "none_0hit")])
2317
2318 (define_expand "sqrtsf2"
2319   [(set (match_operand:SF 0 "register_operand" "")
2320         (sqrt:SF (match_operand:SF 1 "register_operand" "")))]
2321   "TARGET_AM33_2 && flag_unsafe_math_optimizations"
2322   "
2323 {
2324   rtx scratch = gen_reg_rtx (SFmode);
2325   emit_insn (gen_rsqrtsf2 (scratch, operands[1], CONST1_RTX (SFmode)));
2326   emit_insn (gen_divsf3 (operands[0], force_reg (SFmode, CONST1_RTX (SFmode)),
2327                          scratch));
2328   DONE;
2329 }")
2330
2331 (define_insn "rsqrtsf2"
2332   [(set (match_operand:SF 0 "register_operand" "=f,f")
2333         (div:SF (match_operand:SF 2 "const_1f_operand" "F,F")
2334                 (sqrt:SF (match_operand:SF 1 "register_operand" "0,?f"))))]
2335   "TARGET_AM33_2"
2336   "@
2337    frsqrt %0
2338    frsqrt %1, %0"
2339   [(set_attr "cc" "none_0hit")])
2340
2341 (define_insn "addsf3"
2342   [(set (match_operand:SF 0 "register_operand" "=f,f")
2343         (plus:SF (match_operand:SF 1 "register_operand" "%0,f")
2344                  (match_operand:SF 2 "general_operand" "f,?fF")))]
2345   "TARGET_AM33_2"
2346   "@
2347    fadd %2, %0
2348    fadd %2, %1, %0"
2349   [(set_attr "cc" "none_0hit")])
2350
2351 (define_insn "subsf3"
2352   [(set (match_operand:SF 0 "register_operand" "=f,f")
2353         (minus:SF (match_operand:SF 1 "register_operand" "0,f")
2354                   (match_operand:SF 2 "general_operand" "f,?fF")))]
2355   "TARGET_AM33_2"
2356   "@
2357    fsub %2, %0
2358    fsub %2, %1, %0"
2359   [(set_attr "cc" "none_0hit")])
2360
2361 (define_insn "mulsf3"
2362   [(set (match_operand:SF 0 "register_operand" "=f,f")
2363         (mult:SF (match_operand:SF 1 "register_operand" "%0,f")
2364                  (match_operand:SF 2 "general_operand" "f,?fF")))]
2365   "TARGET_AM33_2"
2366   "@
2367    fmul %2, %0
2368    fmul %2, %1, %0"
2369   [(set_attr "cc" "none_0hit")])
2370
2371 (define_insn "divsf3"
2372   [(set (match_operand:SF 0 "register_operand" "=f,f")
2373         (div:SF (match_operand:SF 1 "register_operand" "0,f")
2374                 (match_operand:SF 2 "general_operand" "f,?fF")))]
2375   "TARGET_AM33_2"
2376   "@
2377    fdiv %2, %0
2378    fdiv %2, %1, %0"
2379   [(set_attr "cc" "none_0hit")])
2380
2381 (define_insn "fmaddsf4"
2382   [(set (match_operand:SF 0 "register_operand" "=A")
2383         (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
2384                           (match_operand:SF 2 "register_operand" "f"))
2385                  (match_operand:SF 3 "register_operand" "f")))]
2386   "TARGET_AM33_2"
2387   "fmadd %1, %2, %3, %0"
2388   [(set_attr "cc" "none_0hit")])
2389
2390 (define_insn "fmsubsf4"
2391   [(set (match_operand:SF 0 "register_operand" "=A")
2392         (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
2393                            (match_operand:SF 2 "register_operand" "f"))
2394                   (match_operand:SF 3 "register_operand" "f")))]
2395   "TARGET_AM33_2"
2396   "fmsub %1, %2, %3, %0"
2397   [(set_attr "cc" "none_0hit")])
2398
2399 (define_insn "fnmaddsf4"
2400   [(set (match_operand:SF 0 "register_operand" "=A")
2401         (minus:SF (match_operand:SF 3 "register_operand" "f")
2402                   (mult:SF (match_operand:SF 1 "register_operand" "%f")
2403                            (match_operand:SF 2 "register_operand" "f"))))]
2404   "TARGET_AM33_2"
2405   "fnmadd %1, %2, %3, %0"
2406   [(set_attr "cc" "none_0hit")])
2407
2408 (define_insn "fnmsubsf4"
2409   [(set (match_operand:SF 0 "register_operand" "=A")
2410         (minus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
2411                                    (match_operand:SF 2 "register_operand" "f")))
2412                   (match_operand:SF 3 "register_operand" "f")))]
2413   "TARGET_AM33_2"
2414   "fnmsub %1, %2, %3, %0"
2415   [(set_attr "cc" "none_0hit")])
2416
2417
2418 ;; ----------------------------------------------------------------------
2419 ;; PROLOGUE/EPILOGUE
2420 ;; ----------------------------------------------------------------------
2421 (define_expand "prologue"
2422   [(const_int 0)]
2423   ""
2424   "expand_prologue (); DONE;")
2425
2426 (define_expand "epilogue"
2427   [(return)]
2428   ""
2429   "
2430 {
2431   expand_epilogue ();
2432   DONE;
2433 }")
2434
2435 (define_insn "return_internal"
2436   [(const_int 2)
2437    (return)]
2438   ""
2439   "rets"
2440   [(set_attr "cc" "clobber")])
2441
2442 ;; This insn restores the callee saved registers and does a return, it
2443 ;; can also deallocate stack space.
2444 (define_insn "return_internal_regs"
2445   [(const_int 0)
2446    (match_operand:SI 0  "const_int_operand" "i")
2447    (return)]
2448   ""
2449   "*
2450 {
2451   fputs (\"\\tret \", asm_out_file);
2452   mn10300_print_reg_list (asm_out_file, mn10300_get_live_callee_saved_regs ());
2453   fprintf (asm_out_file, \",%d\\n\", (int) INTVAL (operands[0]));
2454   return \"\";
2455 }"
2456   [(set_attr "cc" "clobber")])
2457
2458 ;; This instruction matches one generated by mn10300_gen_multiple_store()
2459 (define_insn "store_movm"
2460   [(match_parallel 0 "store_multiple_operation"
2461     [(set (reg:SI 9) (plus:SI (reg:SI 9) (match_operand 1 "" "")))])]
2462   ""
2463   "*
2464 {
2465   fputs (\"\\tmovm \", asm_out_file);
2466   mn10300_print_reg_list (asm_out_file,
2467                           store_multiple_operation (operands[0], VOIDmode));
2468   fprintf (asm_out_file, \",(sp)\\n\");
2469   return \"\";
2470 }"
2471   [(set_attr "cc" "clobber")])
2472
2473 (define_insn "return"
2474   [(return)]
2475   "can_use_return_insn ()"
2476   "*
2477 {
2478   rtx next = next_active_insn (insn);
2479
2480   if (next
2481       && GET_CODE (next) == JUMP_INSN
2482       && GET_CODE (PATTERN (next)) == RETURN)
2483     return \"\";
2484   else
2485     return \"rets\";
2486 }"
2487   [(set_attr "cc" "clobber")])
2488
2489 ;; Try to combine consecutive updates of the stack pointer (or any
2490 ;; other register for that matter).
2491 (define_peephole
2492   [(set (match_operand:SI 0 "register_operand" "=dxay")
2493         (plus:SI (match_dup 0)
2494                  (match_operand 1 "const_int_operand" "")))
2495    (set (match_dup 0)
2496         (plus:SI (match_dup 0)
2497                  (match_operand 2 "const_int_operand" "")))]
2498   ""
2499   "*
2500 {
2501   operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]));
2502   return \"add %1,%0\";
2503 }"
2504   [(set_attr "cc" "clobber")])
2505
2506 ;;
2507 ;; We had patterns to check eq/ne, but the they don't work because
2508 ;; 0x80000000 + 0x80000000 = 0x0 with a carry out.
2509 ;;
2510 ;; The Z flag and C flag would be set, and we have no way to
2511 ;; check for the Z flag set and C flag clear.
2512 ;;
2513 ;; This will work on the mn10200 because we can check the ZX flag
2514 ;; if the comparison is in HImode.
2515 (define_peephole
2516   [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2517    (set (pc) (if_then_else (ge (cc0) (const_int 0))
2518                            (match_operand 1 "" "")
2519                            (pc)))]
2520   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2521   "add %0,%0\;bcc %1"
2522   [(set_attr "cc" "clobber")])
2523
2524 (define_peephole
2525   [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2526    (set (pc) (if_then_else (lt (cc0) (const_int 0))
2527                            (match_operand 1 "" "")
2528                            (pc)))]
2529   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2530   "add %0,%0\;bcs %1"
2531   [(set_attr "cc" "clobber")])
2532
2533 (define_peephole
2534   [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2535    (set (pc) (if_then_else (ge (cc0) (const_int 0))
2536                            (pc)
2537                            (match_operand 1 "" "")))]
2538   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2539   "add %0,%0\;bcs %1"
2540   [(set_attr "cc" "clobber")])
2541
2542 (define_peephole
2543   [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2544    (set (pc) (if_then_else (lt (cc0) (const_int 0))
2545                            (pc)
2546                            (match_operand 1 "" "")))]
2547   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2548   "add %0,%0\;bcc %1"
2549   [(set_attr "cc" "clobber")])
2550
2551 (define_expand "int_label"
2552   [(unspec [(match_operand:SI 0 "" "")] UNSPEC_INT_LABEL)]
2553   "" "")
2554
2555 (define_expand "GOTaddr2picreg"
2556   [(match_dup 0)]
2557   "" "
2558 {
2559   /* It would be nice to be able to have int_label keep track of the
2560      counter and all, but if we add C code to it, we'll get an insn
2561      back, and we just want the pattern.  */
2562   operands[0] = gen_int_label (GEN_INT (mn10300_unspec_int_label_counter++));
2563   if (TARGET_AM33)
2564     emit_insn (gen_am33_loadPC (operands[0]));
2565   else
2566     emit_insn (gen_mn10300_loadPC (operands[0]));
2567   emit_insn (gen_add_GOT_to_pic_reg (copy_rtx (operands[0])));
2568   DONE;
2569 }
2570 ")
2571
2572 (define_insn "am33_loadPC"
2573   [(parallel
2574     [(set (reg:SI PIC_REG) (pc))
2575      (use (match_operand 0 "" ""))])]
2576   "TARGET_AM33"
2577   "%0:\;mov pc,a2")
2578
2579
2580 (define_insn_and_split "mn10300_loadPC"
2581   [(parallel
2582     [(set (reg:SI PIC_REG) (pc))
2583      (use (match_operand 0 "" ""))])]
2584   ""
2585   "#"
2586   "reload_completed"
2587   [(match_operand 0 "" "")]
2588   "
2589 {
2590   rtx sp_reg = gen_rtx_REG (SImode, SP_REG);
2591   int need_stack_space = (get_frame_size () == 0
2592                           && current_function_outgoing_args_size == 0);
2593
2594   if (need_stack_space)
2595     emit_move_insn (sp_reg, plus_constant (sp_reg, -4));
2596
2597   emit_insn (gen_call_next_insn (operands[0]));
2598
2599   if (need_stack_space)
2600     emit_insn (gen_pop_pic_reg ());
2601   else
2602     emit_move_insn (pic_offset_table_rtx, gen_rtx_MEM (SImode, sp_reg));
2603
2604   DONE;
2605 }")
2606
2607 (define_insn "call_next_insn"
2608   [(parallel
2609     [(set (mem:SI (reg:SI SP_REG)) (pc))
2610      (use (match_operand 0 "" ""))])]
2611   "reload_completed"
2612   "calls %0\;%0:")
2613
2614 (define_expand "add_GOT_to_pic_reg"
2615   [(set (reg:SI PIC_REG)
2616         (plus:SI
2617          (reg:SI PIC_REG)
2618          (const
2619           (unspec [(minus:SI
2620                     (match_dup 1)
2621                     (const (minus:SI
2622                             (const (match_operand:SI 0 "" ""))
2623                             (pc))))
2624                   ] UNSPEC_PIC))))]
2625   ""
2626   "
2627 {
2628   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
2629 }")
2630
2631 (define_expand "symGOT2reg"
2632   [(match_operand:SI 0 "" "")
2633    (match_operand:SI 1 "" "")]
2634   ""
2635   "
2636 {
2637   rtx insn = emit_insn (gen_symGOT2reg_i (operands[0], operands[1]));
2638
2639   MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
2640
2641   set_unique_reg_note (insn, REG_EQUAL, operands[1]);
2642
2643   DONE;
2644 }")
2645
2646 (define_expand "symGOT2reg_i"
2647   [(set (match_operand:SI 0 "" "")
2648         (mem:SI (plus:SI (reg:SI PIC_REG)
2649                          (const (unspec [(match_operand:SI 1 "" "")]
2650                                         UNSPEC_GOT)))))]
2651   ""
2652   "")
2653
2654 (define_expand "symGOTOFF2reg"
2655   [(match_operand:SI 0 "" "") (match_operand:SI 1 "" "")]
2656   ""
2657   "
2658 {
2659   rtx insn = emit_insn (gen_symGOTOFF2reg_i (operands[0], operands[1]));
2660
2661   set_unique_reg_note (insn, REG_EQUAL, operands[1]);
2662
2663   DONE;
2664 }")
2665
2666 (define_expand "symGOTOFF2reg_i"
2667   [(set (match_operand:SI 0 "" "")
2668         (const (unspec [(match_operand:SI 1 "" "")] UNSPEC_GOTOFF)))
2669   (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI PIC_REG)))]
2670   ""
2671   "")
2672
2673 (define_expand "sym2PIC"
2674   [(unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC)]
2675   "" "")
2676
2677 (define_expand "sym2PLT"
2678   [(unspec [(match_operand:SI 0 "" "")] UNSPEC_PLT)]
2679   "" "")