Merge from mainline (168000:168310).
[official-gcc/graphite-test-results.git] / gcc / config / mn10300 / mn10300.md
blob3fad021b527d982028f346021f47f25267e451fc
1 ;; GCC machine description for Matsushita MN10300
2 ;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3 ;; 2005, 2006, 2007, 2008, 2009, 2010
4 ;; Free Software Foundation, Inc.
5 ;; Contributed by Jeff Law (law@cygnus.com).
7 ;; This file is part of GCC.
9 ;; GCC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 3, or (at your option)
12 ;; any later version.
14 ;; GCC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3.  If not see
21 ;; <http://www.gnu.org/licenses/>.
23 ;; The original PO technology requires these to be ordered by speed,
24 ;; so that assigner will pick the fastest.
26 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 (define_constants [
29   (PIC_REG 6)
30   (SP_REG  9)
31   (CC_REG 51)
33   (UNSPEC_INT_LABEL     0)
34   (UNSPEC_PIC           1)
35   (UNSPEC_GOT           2)
36   (UNSPEC_GOTOFF        3)
37   (UNSPEC_PLT           4)
38   (UNSPEC_GOTSYM_OFF    5)
41 (include "predicates.md")
42 (include "constraints.md")
44 ;; Processor type.  This attribute must exactly match the processor_type
45 ;; enumeration in mn10300.h.
46 (define_attr "cpu" "mn10300,am33,am33_2,am34"
47   (const (symbol_ref "(enum attr_cpu) mn10300_tune_cpu")))
50 ;; Pipeline description.
52 ;; The AM33 only has a single pipeline.  It has five stages (fetch,
53 ;; decode, execute, memory access, writeback) each of which normally
54 ;; takes a single CPU clock cycle.
56 ;; The timings attribute consists of two numbers, the first is the
57 ;; throughput, which is the number of cycles the instruction takes
58 ;; to execute and generate a result.  The second is the latency
59 ;; which is the effective number of cycles the instruction takes to
60 ;; execute if its result is used by the following instruction.  The
61 ;; latency is always greater than or equal to the throughput.
62 ;; These values were taken from the Appendix of the "MN103E Series
63 ;; Instruction Manual" and the timings for the AM34.
65 ;; Note - it would be nice to use strings rather than integers for
66 ;; the possible values of this attribute, so that we can have the
67 ;; gcc build mechanism check for values that are not supported by
68 ;; the reservations below.  But this will not work because the code
69 ;; in mn10300_adjust_sched_cost() needs integers not strings.
71 (define_attr "timings" "" (const_int 11))
73 (define_automaton "pipelining")
74 (define_cpu_unit "throughput" "pipelining")
76 (define_insn_reservation "throughput__1_latency__1"  1
77   (eq_attr "timings" "11") "throughput")
78 (define_insn_reservation "throughput__1_latency__2"  2
79   (eq_attr "timings" "12") "throughput,nothing")
80 (define_insn_reservation "throughput__1_latency__3"  3
81   (eq_attr "timings" "13") "throughput,nothing*2")
82 (define_insn_reservation "throughput__1_latency__4"  4
83   (eq_attr "timings" "14") "throughput,nothing*3")
84 (define_insn_reservation "throughput__2_latency__2"  2
85   (eq_attr "timings" "22") "throughput*2")
86 (define_insn_reservation "throughput__2_latency__3"  3
87   (eq_attr "timings" "23") "throughput*2,nothing")
88 (define_insn_reservation "throughput__2_latency__4"  4
89   (eq_attr "timings" "24") "throughput*2,nothing*2")
90 (define_insn_reservation "throughput__2_latency__5"  5
91   (eq_attr "timings" "25") "throughput*2,nothing*3")
92 (define_insn_reservation "throughput__3_latency__3"  3
93   (eq_attr "timings" "33") "throughput*3")
94 (define_insn_reservation "throughput__3_latency__7"  7
95   (eq_attr "timings" "37") "throughput*3,nothing*4")
96 (define_insn_reservation "throughput__4_latency__4"  4
97   (eq_attr "timings" "44") "throughput*4")
98 (define_insn_reservation "throughput__4_latency__7"  7
99   (eq_attr "timings" "47") "throughput*4,nothing*3")
100 (define_insn_reservation "throughput__4_latency__8"  8
101   (eq_attr "timings" "48") "throughput*4,nothing*4")
102 (define_insn_reservation "throughput__5_latency__5"  5
103   (eq_attr "timings" "55") "throughput*5")
104 (define_insn_reservation "throughput__6_latency__6"  6
105   (eq_attr "timings" "66") "throughput*6")
106 (define_insn_reservation "throughput__7_latency__7"  7
107   (eq_attr "timings" "77") "throughput*7")
108 (define_insn_reservation "throughput__7_latency__8"  8
109   (eq_attr "timings" "78") "throughput*7,nothing")
110 (define_insn_reservation "throughput__8_latency__8"  8
111   (eq_attr "timings" "88") "throughput*8")
112 (define_insn_reservation "throughput__9_latency__9"  9
113   (eq_attr "timings" "99") "throughput*9")
114 (define_insn_reservation "throughput__8_latency_14" 14
115   (eq_attr "timings" "814") "throughput*8,nothing*6")
116 (define_insn_reservation "throughput__9_latency_10" 10
117   (eq_attr "timings" "910") "throughput*9,nothing")
118 (define_insn_reservation "throughput_10_latency_10" 10
119   (eq_attr "timings" "1010") "throughput*10")
120 (define_insn_reservation "throughput_12_latency_16" 16
121   (eq_attr "timings" "1216") "throughput*12,nothing*4")
122 (define_insn_reservation "throughput_13_latency_13" 13
123   (eq_attr "timings" "1313") "throughput*13")
124 (define_insn_reservation "throughput_14_latency_14" 14
125   (eq_attr "timings" "1414") "throughput*14")
126 (define_insn_reservation "throughput_13_latency_17" 17
127   (eq_attr "timings" "1317") "throughput*13,nothing*4")
128 (define_insn_reservation "throughput_23_latency_27" 27
129   (eq_attr "timings" "2327") "throughput*23,nothing*4")
130 (define_insn_reservation "throughput_25_latency_31" 31
131   (eq_attr "timings" "2531") "throughput*25,nothing*6")
132 (define_insn_reservation "throughput_38_latency_39" 39
133   (eq_attr "timings" "3839") "throughput*38,nothing")
134 (define_insn_reservation "throughput_39_latency_40" 40
135   (eq_attr "timings" "3940") "throughput*39,nothing")
136 (define_insn_reservation "throughput_40_latency_40" 40
137   (eq_attr "timings" "4040") "throughput*40")
138 (define_insn_reservation "throughput_41_latency_42" 42
139   (eq_attr "timings" "4142") "throughput*41,nothing")
140 (define_insn_reservation "throughput_43_latency_44" 44
141   (eq_attr "timings" "4344") "throughput*43,nothing")
142 (define_insn_reservation "throughput_45_latency_46" 46
143   (eq_attr "timings" "4546") "throughput*45,nothing")
144 (define_insn_reservation "throughput_47_latency_53" 53
145   (eq_attr "timings" "4753") "throughput*47,nothing*6")
147 ;; Note - the conflict between memory load/store instructions
148 ;; and floating point instructions described in section 1-7-4
149 ;; of Chapter 3 of the MN103E Series Instruction Manual is
150 ;; handled by the mn10300_adjust_sched_cost function.
152 ;; ----------------------------------------------------------------------
153 ;; MOVE INSTRUCTIONS
154 ;; ----------------------------------------------------------------------
156 ;; movqi
158 (define_expand "movqi"
159   [(set (match_operand:QI 0 "nonimmediate_operand")
160         (match_operand:QI 1 "general_operand"))]
161   ""
162   "
164   /* One of the ops has to be in a register.  */
165   if (!register_operand (operand0, QImode)
166       && !register_operand (operand1, QImode))
167     operands[1] = copy_to_mode_reg (QImode, operand1);
170 (define_insn "*am33_movqi"
171   [(set (match_operand:QI 0 "nonimmediate_operand"
172                           ;; 0       1      2      3     4       5
173                           "=d*x*a*f, d*x*a, d*x*a, m,   *f,      d*x*a")
174         (match_operand:QI 1 "general_operand"
175                            "0,       d*xai, m,     d*xa, d*xa*f, *f"))]
176   "TARGET_AM33
177    && (register_operand (operands[0], QImode)
178        || register_operand (operands[1], QImode))"
179   "*
180   {
181     switch (which_alternative)
182       {
183       case 0:
184         return \"nop\";
185       case 1:
186         gcc_assert (! CONST_DOUBLE_P (operands[1]));
188         if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
189             && CONST_INT_P (operands[1]))
190           {
191             HOST_WIDE_INT val = INTVAL (operands[1]);
193             if (((val & 0x80) && ! (val & 0xffffff00))
194                 || ((val & 0x800000) && ! (val & 0xff000000)))
195               return \"movu %1,%0\";
196           }
197         return \"mov %1,%0\";
198       case 2:
199       case 3:
200         return \"movbu %1,%0\";
201       case 4:
202       case 5:
203         return \"fmov %1,%0\";
204       default:
205         gcc_unreachable ();
206       }
207   }"
208   [(set_attr_alternative "timings"
209                          [(const_int 11)
210                           (if_then_else (eq_attr "cpu" "am34")
211                                         (const_int 11) (const_int 22))
212                           (if_then_else (eq_attr "cpu" "am34")
213                                         (const_int 13) (const_int 24))
214                           (if_then_else (eq_attr "cpu" "am34")
215                                         (const_int 13) (const_int 24))
216                           (if_then_else (eq_attr "cpu" "am34")
217                                         (const_int 47) (const_int 25))
218                           (if_then_else (eq_attr "cpu" "am34")
219                                         (const_int 47) (const_int 25))
220                          ])
221   ]
224 (define_insn "*mn10300_movqi"
225   [(set (match_operand:QI 0 "nonimmediate_operand" "=d*a,d,d,!*a,d*a,d,m")
226         (match_operand:QI 1 "general_operand"       "0,  I,i,i,  da, m,d"))]
227   "register_operand (operands[0], QImode)
228    || register_operand (operands[1], QImode)"
229   "*
231   switch (which_alternative)
232     {
233     case 0:
234       return \"nop\";
235     case 1:
236     case 2:
237     case 3:
238     case 4:
239       gcc_assert (! CONST_DOUBLE_P (operands[1]));
240       return \"mov %1,%0\";
241     case 5:
242     case 6:
243       return \"movbu %1,%0\";
244     default:
245       gcc_unreachable ();
246     }
248   [(set_attr_alternative "timings"
249                          [(const_int 11)
250                           (const_int 11)
251                           (if_then_else (eq_attr "cpu" "am34")
252                                         (const_int 11) (const_int 22))
253                           (if_then_else (eq_attr "cpu" "am34")
254                                         (const_int 11) (const_int 22))
255                           (if_then_else (eq_attr "cpu" "am34")
256                                         (const_int 11) (const_int 22))
257                           (if_then_else (eq_attr "cpu" "am34")
258                                         (const_int 13) (const_int 24))
259                           (if_then_else (eq_attr "cpu" "am34")
260                                         (const_int 13) (const_int 24))
261                          ])
262   ]
265 ;; movhi
267 (define_expand "movhi"
268   [(set (match_operand:HI 0 "nonimmediate_operand")
269         (match_operand:HI 1 "general_operand"))]
270   ""
271   "
273   /* One of the ops has to be in a register.  */
274   if (!register_operand (operand1, HImode)
275       && !register_operand (operand0, HImode))
276     operands[1] = copy_to_mode_reg (HImode, operand1);
279 (define_insn "*am33_movhi"
280   [(set (match_operand:HI 0 "nonimmediate_operand"
281                           ;; 0       1       2      3     4         5
282                           "=d*x*a*f, d*x*a,  d*x*a, m,    *f,       d*x*a")
283         (match_operand:HI 1 "general_operand"
284                           "0,        d*x*ai, m,     d*x*a, d*x*a*f, *f"))]
285   "TARGET_AM33
286    && (register_operand (operands[0], HImode)
287        || register_operand (operands[1], HImode))"
288   "*
290   switch (which_alternative)
291     {
292     case 0:
293       return \"nop\";
294     case 1:
295       gcc_assert (! CONST_DOUBLE_P (operands[1]));
297       if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
298           && CONST_INT_P (operands[1]))
299         {
300           HOST_WIDE_INT val = INTVAL (operands[1]);
302           if (((val & 0x80) && ! (val & 0xffffff00))
303               || ((val & 0x800000) && ! (val & 0xff000000)))
304             return \"movu %1,%0\";
305         }
306       return \"mov %1,%0\";
307     case 2:
308     case 3:
309       return \"movhu %1,%0\";
310     case 4:
311     case 5:
312       return \"fmov %1,%0\";
313     default:
314       gcc_unreachable ();
315     }
317   [(set_attr_alternative "timings"
318                          [(const_int 11)
319                           (if_then_else (eq_attr "cpu" "am34")
320                                         (const_int 11) (const_int 22))
321                           (if_then_else (eq_attr "cpu" "am34")
322                                         (const_int 13) (const_int 24))
323                           (if_then_else (eq_attr "cpu" "am34")
324                                         (const_int 13) (const_int 24))
325                           (if_then_else (eq_attr "cpu" "am34")
326                                         (const_int 47) (const_int 25))
327                           (if_then_else (eq_attr "cpu" "am34")
328                                         (const_int 47) (const_int 25))
329                          ])
330   ]
333 (define_insn "*mn10300_movhi"
334   [(set (match_operand:HI 0 "nonimmediate_operand" "=d*a,d,d,!*a,d*a,d,m")
335         (match_operand:HI 1 "general_operand"       "0,  I,i,i,  da, m,d"))]
336   "register_operand (operands[0], HImode)
337    || register_operand (operands[1], HImode)"
338   "*
340   switch (which_alternative)
341     {
342     case 0:
343       return \"nop\";
344     case 1:
345     case 2:
346     case 3:
347     case 4:
348       gcc_assert (! CONST_DOUBLE_P (operands[1]));
349       return \"mov %1,%0\";
350     case 5:
351     case 6:
352       return \"movhu %1,%0\";
353     default:
354       gcc_unreachable ();
355     }
357   [(set_attr_alternative "timings"
358                          [(const_int 11)
359                           (const_int 11)
360                           (if_then_else (eq_attr "cpu" "am34")
361                                         (const_int 11) (const_int 22))
362                           (if_then_else (eq_attr "cpu" "am34")
363                                         (const_int 11) (const_int 22))
364                           (if_then_else (eq_attr "cpu" "am34")
365                                         (const_int 11) (const_int 22))
366                           (if_then_else (eq_attr "cpu" "am34")
367                                         (const_int 13) (const_int 24))
368                           (if_then_else (eq_attr "cpu" "am34")
369                                         (const_int 13) (const_int 24))
370                          ])
371   ]
374 ;; movsi and helpers
376 ;; We use this to handle addition of two values when one operand is the
377 ;; stack pointer and the other is a memory reference of some kind.  Reload
378 ;; does not handle them correctly without this expander.
379 (define_expand "reload_insi"
380   [(set (match_operand:SI     0 "register_operand" "=a")
381         (match_operand:SI     1 "impossible_plus_operand" ""))
382    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
383   ""
384   "
386   gcc_assert (REGNO (operands[0]) != REGNO (operands[2]));
388   if (XEXP (operands[1], 0) == stack_pointer_rtx)
389     {
390       if (GET_CODE (XEXP (operands[1], 1)) == SUBREG
391           && (GET_MODE_SIZE (GET_MODE (XEXP (operands[1], 1)))
392               > GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (operands[1], 1))))))
393         emit_move_insn (operands[2],
394                         gen_rtx_ZERO_EXTEND
395                         (GET_MODE (XEXP (operands[1], 1)),
396                          SUBREG_REG (XEXP (operands[1], 1))));
397       else
398         emit_move_insn (operands[2], XEXP (operands[1], 1));
399       emit_move_insn (operands[0], XEXP (operands[1], 0));
400     }
401   else
402     {
403       if (GET_CODE (XEXP (operands[1], 0)) == SUBREG
404           && (GET_MODE_SIZE (GET_MODE (XEXP (operands[1], 0)))
405               > GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (operands[1], 0))))))
406         emit_move_insn (operands[2],
407                         gen_rtx_ZERO_EXTEND
408                         (GET_MODE (XEXP (operands[1], 0)),
409                          SUBREG_REG (XEXP (operands[1], 0))));
410       else
411         emit_move_insn (operands[2], XEXP (operands[1], 0));
412       emit_move_insn (operands[0], XEXP (operands[1], 1));
413     }
414   emit_insn (gen_addsi3 (operands[0], operands[0], operands[2]));
415   DONE;
418 (define_insn "pop_pic_reg"
419   [(set (reg:SI PIC_REG)
420         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
421   "reload_completed"
422   "movm (sp),[a2]"
423   [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
424                                        (const_int 44) (const_int 33)))]
427 (define_expand "movsi"
428   [(set (match_operand:SI 0 "nonimmediate_operand")
429         (match_operand:SI 1 "general_operand"))]
430   ""
431   "
433   /* One of the ops has to be in a register.  */
434   if (!register_operand (operand1, SImode)
435       && !register_operand (operand0, SImode))
436     operands[1] = copy_to_mode_reg (SImode, operand1);
437   if (flag_pic)
438     {
439       rtx temp;
440       if (SYMBOLIC_CONST_P (operands[1]))
441         {
442           if (MEM_P (operands[0]))
443             operands[1] = force_reg (Pmode, operands[1]);
444           else
445             {
446               temp = (!can_create_pseudo_p ()
447                       ? operands[0]
448                       : gen_reg_rtx (Pmode));
449               operands[1] = mn10300_legitimize_pic_address (operands[1], temp);
450             }
451         }
452       else if (GET_CODE (operands[1]) == CONST
453                && GET_CODE (XEXP (operands[1], 0)) == PLUS
454                && SYMBOLIC_CONST_P (XEXP (XEXP (operands[1], 0), 0)))
455         {
456           temp = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
457           temp = mn10300_legitimize_pic_address (XEXP (XEXP (operands[1], 0), 0),
458                                                  temp);
459           operands[1] = expand_binop (SImode, add_optab, temp,
460                                       XEXP (XEXP (operands[1], 0), 1),
461                                       (!can_create_pseudo_p ()
462                                        ? temp
463                                        : gen_reg_rtx (Pmode)),
464                                       0, OPTAB_LIB_WIDEN);
465         }
466     }
469 (define_insn "*movsi_internal"
470   [(set (match_operand:SI 0 "nonimmediate_operand"
471                           "=dax, dax,  m,   dax, axR, !*y")
472         (match_operand:SI 1 "general_operand"
473                           "0,    Idax, dax, im,  !*y, axR"))
474   ]
475   "register_operand (operands[0], SImode)
476    || register_operand (operands[1], SImode)"
477   "*
478   {
479     if (which_alternative == 0)
480       return \"nop\";
482     gcc_assert (! CONST_DOUBLE_P (operands[1]));
484     if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
485         && CONST_INT_P (operands[1]))
486       {
487         HOST_WIDE_INT val = INTVAL (operands[1]);
489         if (((val & 0x80) && ! (val & 0xffffff00))
490             || ((val & 0x800000) && ! (val & 0xff000000)))
491           return \"movu %1, %0\";
492       }
494     return \"mov %1, %0\";
495   }"
496   [(set_attr_alternative "timings"
497                          [(const_int 11)
498                           (if_then_else (eq_attr "cpu" "am34")
499                                         (const_int 13) (const_int 24))
500                           (if_then_else (eq_attr "cpu" "am34")
501                                         (const_int 13) (const_int 24))
502                           (if_then_else (eq_attr "cpu" "am34")
503                                         (const_int 13) (const_int 24))
504                           (if_then_else (eq_attr "cpu" "am34")
505                                         (const_int 13) (const_int 24))
506                           (if_then_else (eq_attr "cpu" "am34")
507                                         (const_int 13) (const_int 24))
508                          ])
509   ]
512 (define_expand "movsf"
513   [(set (match_operand:SF 0 "nonimmediate_operand")
514         (match_operand:SF 1 "general_operand"))]
515   ""
516   "
518   /* One of the ops has to be in a register.  */
519   if (!register_operand (operand1, SFmode)
520       && !register_operand (operand0, SFmode))
521     operands[1] = copy_to_mode_reg (SFmode, operand1);
524 (define_insn "*movsf_internal"
525   [(set (match_operand:SF 0 "nonimmediate_operand"
526                           ;; 0    1    2       3     4     5
527                           "=fdxa, dxa, f,      dxaQ, daxm, dax")
528         (match_operand:SF 1 "general_operand"
529                           " 0,    G,   fdxaQF, f,    dax,  daxFm"))
530   ]
531   "register_operand (operands[0], SFmode)
532    || register_operand (operands[1], SFmode)"
533   "*
534   {
535     switch (which_alternative)
536       {
537       case 0:
538         return \"nop\";
539       /* case 1: below.  */
540       case 2:
541       case 3:
542         return \"fmov %1, %0\";
543       case 1:
544       case 4:
545       case 5:
546         if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
547             && CONST_INT_P (operands[1]))
548           {
549             HOST_WIDE_INT val = INTVAL (operands[1]);
551             if (((val & 0x80) && ! (val & 0xffffff00))
552                 || ((val & 0x800000) && ! (val & 0xff000000)))
553               return \"movu %1, %0\";
554           }
555         return \"mov %1, %0\";
556       default:
557         gcc_unreachable ();
558       }
559   }"
560   [(set_attr_alternative "timings"
561                          [(const_int 11)
562                           (if_then_else (eq_attr "cpu" "am34")
563                                         (const_int 13) (const_int 24))
564                           (if_then_else (eq_attr "cpu" "am34")
565                                         (const_int 47) (const_int 25))
566                           (if_then_else (eq_attr "cpu" "am34")
567                                         (const_int 47) (const_int 25))
568                           (if_then_else (eq_attr "cpu" "am34")
569                                         (const_int 13) (const_int 24))
570                           (if_then_else (eq_attr "cpu" "am34")
571                                         (const_int 13) (const_int 24))
572                          ])
573   ]
576 (define_expand "movdi"
577   [(set (match_operand:DI 0 "nonimmediate_operand")
578         (match_operand:DI 1 "general_operand"))]
579   ""
580   "
582   /* One of the ops has to be in a register.  */
583   if (!register_operand (operand1, DImode)
584       && !register_operand (operand0, DImode))
585     operands[1] = copy_to_mode_reg (DImode, operand1);
589 (define_insn "*movdi_internal"                   ;;   0 1  2  3 4   5   6  7 8  9
590   [(set (match_operand:DI 0 "nonimmediate_operand" "=dx,ax,dx,a,dxm,dxm,a, a,dx,a")
591         (match_operand:DI 1 "general_operand"        "0,0, I, I,dx, a,  dx,a,im,im"))]
592   "register_operand (operands[0], DImode)
593    || register_operand (operands[1], DImode)"
594   "*
596   long val[2];
597   REAL_VALUE_TYPE rv;
599   switch (which_alternative)
600     {
601       case 0:
602       case 1:
603         return \"nop\";
605       case 2:
606         return \"mov 0, %L0\;mov 0, %H0\";
608       case 3:
609         if (rtx_equal_p (operands[0], operands[1]))
610           return \"sub %L1,%L0\;mov %L0,%H0\";
611         else
612           return \"mov %1,%L0\;mov %L0,%H0\";
613       case 4:
614       case 5:
615       case 6:
616       case 7:
617       case 8:
618       case 9:
619         if (CONST_INT_P (operands[1]))
620           {
621             rtx low, high;
622             split_double (operands[1], &low, &high);
623             val[0] = INTVAL (low);
624             val[1] = INTVAL (high);
625           }
626         if (CONST_DOUBLE_P (operands[1]))
627           {
628             if (GET_MODE (operands[1]) == DFmode)
629               {
630                 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
631                 REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
632               }
633             else if (GET_MODE (operands[1]) == VOIDmode
634                      || GET_MODE (operands[1]) == DImode)
635               {
636                 val[0] = CONST_DOUBLE_LOW (operands[1]);
637                 val[1] = CONST_DOUBLE_HIGH (operands[1]);
638               }
639           }
641         if (MEM_P (operands[1])
642             && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
643           {
644             rtx temp = operands[0];
646             while (GET_CODE (temp) == SUBREG)
647               temp = SUBREG_REG (temp);
649             gcc_assert (REG_P (temp));
651             if (reg_overlap_mentioned_p (gen_rtx_REG (SImode, REGNO (temp)),
652                                          XEXP (operands[1], 0)))
653               return \"mov %H1,%H0\;mov %L1,%L0\";
654             else
655               return \"mov %L1,%L0\;mov %H1,%H0\";
657           }
658         else if (MEM_P (operands[1])
659                  && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
660                  && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
661           {
662             rtx xoperands[2];
664             xoperands[0] = operands[0];
665             xoperands[1] = XEXP (operands[1], 0);
667             output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\",
668                              xoperands);
669             return \"\";
670           }
671         else
672           {
673             if ((CONST_INT_P (operands[1])
674                  || CONST_DOUBLE_P (operands[1]))
675                 && val[0] == 0)
676               {
677                 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
678                   output_asm_insn (\"mov 0, %L0\", operands);
679                 else
680                   output_asm_insn (\"mov %L1,%L0\", operands);
681               }
682             else if ((CONST_INT_P (operands[1])
683                       || CONST_DOUBLE_P (operands[1]))
684                      && (REGNO_REG_CLASS (true_regnum (operands[0]))
685                          == EXTENDED_REGS)
686                      && (((val[0] & 0x80) && ! (val[0] & 0xffffff00))
687                          || ((val[0] & 0x800000) && ! (val[0] & 0xff000000))))
688               output_asm_insn (\"movu %L1,%L0\", operands);
689             else
690               output_asm_insn (\"mov %L1,%L0\", operands);
692             if ((CONST_INT_P (operands[1])
693                  || CONST_DOUBLE_P (operands[1]))
694                 && val[1] == 0)
695               {
696                 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
697                   output_asm_insn (\"mov 0, %H0\", operands);
698                 else
699                   output_asm_insn (\"mov %H1,%H0\", operands);
700               }
701             else if ((CONST_INT_P (operands[1])
702                       || CONST_DOUBLE_P (operands[1]))
703                      && val[0] == val[1])
704               output_asm_insn (\"mov %L0,%H0\", operands);
705             else if ((CONST_INT_P (operands[1])
706                       || CONST_DOUBLE_P (operands[1]))
707                      && (REGNO_REG_CLASS (true_regnum (operands[0]))
708                          == EXTENDED_REGS)
709                      && (((val[1] & 0x80) && ! (val[1] & 0xffffff00))
710                          || ((val[1] & 0x800000) && ! (val[1] & 0xff000000))))
711               output_asm_insn (\"movu %H1,%H0\", operands);
712             else
713               output_asm_insn (\"mov %H1,%H0\", operands);
714             return \"\";
715           }
716     default:
717       gcc_unreachable ();
718     }
719   }"
720   ;; The timing of "37" is an approximation of the worst case sceanario.
721   [(set_attr_alternative "timings"
722                          [(const_int 11)
723                           (const_int 11)
724                           (const_int 22)
725                           (const_int 22)
726                           (const_int 37)
727                           (const_int 37)
728                           (const_int 37)
729                           (const_int 37)
730                           (const_int 37)
731                           (const_int 37)
732                          ])
733   ]
736 (define_expand "movdf"
737   [(set (match_operand:DF 0 "nonimmediate_operand")
738         (match_operand:DF 1 "general_operand"))]
739   ""
740   "
742   /* One of the ops has to be in a register.  */
743   if (!register_operand (operand1, DFmode)
744       && !register_operand (operand0, DFmode))
745     operands[1] = copy_to_mode_reg (DFmode, operand1);
748 (define_insn "*am33_2_movdf"
749   [(set (match_operand:DF 0 "nonimmediate_operand"
750                           ;; 0   1   2    3    4 5 6   7   8  9 10 11
751                           "=fdax,dax,fdxa,f,   f,Q,dxm,dxm,a, a,dx,a")
752         (match_operand:DF 1 "general_operand"
753                           " 0,   G,  f,   dxaF,Q,f,dx, a,  dx,a,Fm,Fm"))]
754   "TARGET_AM33_2
755    && (register_operand (operands[0], DFmode)
756        || register_operand (operands[1], DFmode))"
757   "*
758   {
759     long val[2];
760     REAL_VALUE_TYPE rv;
762     switch (which_alternative)
763       {
764       case 0:
765         return \"nop\";
767       case 1:
768         return \"mov 0, %L0\; mov 0, %H0\";
770       case 2:
771       case 3:
772         return \"fmov %L1, %L0\; fmov %H1, %H0\";
774       case 4:
775         if (MEM_P (operands[1])
776             && CONST_INT_P (XEXP (operands[1], 0))
777             && (INTVAL (XEXP (operands[1], 0)) & 7) == 0)
778           return \"fmov %D1, %D0\";
779         else
780           return \"fmov %L1, %L0\; fmov %H1, %H0\";
782       case 5:
783         if (MEM_P (operands[0])
784             && CONST_INT_P (XEXP (operands[0], 0))
785             && (INTVAL (XEXP (operands[0], 0)) & 7) == 0)
786           return \"fmov %D1, %D0\";
787         else
788           return \"fmov %L1, %L0\; fmov %H1, %H0\";
790       case 6:
791       case 7:
792       case 8:
793       case 9:
794       case 10:
795       case 11:
796         if (CONST_INT_P (operands[1]))
797           {
798             rtx low, high;
799             split_double (operands[1], &low, &high);
800             val[0] = INTVAL (low);
801             val[1] = INTVAL (high);
802           }
803         if (CONST_DOUBLE_P (operands[1]))
804           {
805             if (GET_MODE (operands[1]) == DFmode)
806               {
807                 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
808                 REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
809               }
810             else if (GET_MODE (operands[1]) == VOIDmode
811                      || GET_MODE (operands[1]) == DImode)
812               {
813                 val[0] = CONST_DOUBLE_LOW (operands[1]);
814                 val[1] = CONST_DOUBLE_HIGH (operands[1]);
815               }
816           }
818         if (MEM_P (operands[1])
819             && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
820           {
821             rtx temp = operands[0];
823             while (GET_CODE (temp) == SUBREG)
824               temp = SUBREG_REG (temp);
826             gcc_assert (REG_P (temp));
828             if (reg_overlap_mentioned_p (gen_rtx_REG (SImode, REGNO (temp)),
829                                          XEXP (operands[1], 0)))
830               return \"mov %H1, %H0\; mov %L1, %L0\";
831             else
832               return \"mov %L1, %L0\; mov %H1, %H0\";
834           }
835         else if (MEM_P (operands[1])
836                  && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
837                  && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
838           {
839             rtx xoperands[2];
841             xoperands[0] = operands[0];
842             xoperands[1] = XEXP (operands[1], 0);
844             output_asm_insn (\"mov %1, %L0\; mov (4, %L0), %H0\; mov (%L0), %L0\",
845                              xoperands);
846             return \"\";
847           }
848         else
849           {
850             if ((CONST_INT_P (operands[1])
851                  || CONST_DOUBLE_P (operands[1]))
852                 && val[0] == 0)
853               {
854                 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
855                   output_asm_insn (\"mov 0, %L0\", operands);
856                 else
857                   output_asm_insn (\"mov %L1,%L0\", operands);
858               }
859             else if ((CONST_INT_P (operands[1])
860                       || CONST_DOUBLE_P (operands[1]))
861                      && (REGNO_REG_CLASS (true_regnum (operands[0]))
862                          == EXTENDED_REGS)
863                      && (((val[0] & 0x80) && ! (val[0] & 0xffffff00))
864                          || ((val[0] & 0x800000) && ! (val[0] & 0xff000000))))
865               output_asm_insn (\"movu %L1, %L0\", operands);
866             else
867               output_asm_insn (\"mov %L1, %L0\", operands);
869             if ((CONST_INT_P (operands[1])
870                  || CONST_DOUBLE_P (operands[1]))
871                 && val[1] == 0)
872               {
873                 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
874                   output_asm_insn (\"mov 0, %H0\", operands);
875                 else
876                   output_asm_insn (\"mov %H1, %H0\", operands);
877               }
878             else if ((CONST_INT_P (operands[1])
879                       || CONST_DOUBLE_P (operands[1]))
880                      && val[0] == val[1])
881               output_asm_insn (\"mov %L0,%H0\", operands);
882             else if ((CONST_INT_P (operands[1])
883                       || CONST_DOUBLE_P (operands[1]))
884                      && (REGNO_REG_CLASS (true_regnum (operands[0]))
885                          == EXTENDED_REGS)
886                      && (((val[1] & 0x80) && ! (val[1] & 0xffffff00))
887                          || ((val[1] & 0x800000) && ! (val[1] & 0xff000000))))
888               output_asm_insn (\"movu %H1, %H0\", operands);
889             else
890               output_asm_insn (\"mov %H1, %H0\", operands);
891             return \"\";
892           }
893     default:
894       gcc_unreachable ();
895     }
896   }"
897   ;; The timing of "37" is an approximation of the worst case sceanario.
898   [(set_attr_alternative "timings"
899                          [(const_int 11)
900                           (const_int 22)
901                           (const_int 22)
902                           (const_int 22)
903                           (const_int 22)
904                           (const_int 37)
905                           (const_int 37)
906                           (const_int 37)
907                           (const_int 37)
908                           (const_int 37)
909                           (const_int 37)
910                           (const_int 37)
911                          ])
912   ]
915 (define_insn "*mn10300_movdf"
916   [(set (match_operand:DF 0 "nonimmediate_operand"
917                           ;;0    1    2    3    4   5  6   7
918                           "=dxa, dax, dxm, dxm, a,  a, dx, a")
919         (match_operand:DF 1 "general_operand"
920                           " 0,   G,   dx,  a,   dx, a, Fm, Fm"))]
921   "register_operand (operands[0], DFmode)
922    || register_operand (operands[1], DFmode)"
923   "*
924   {
925     long val[2];
926     REAL_VALUE_TYPE rv;
928     switch (which_alternative)
929       {
930       case 0:
931         return \"nop\";
933       case 1:
934         return \"mov 0, %L0\; mov 0, %H0\";
936       case 2:
937       case 3:
938       case 4:
939       case 5:
940       case 6:
941       case 7:
942         if (CONST_INT_P (operands[1]))
943           {
944             rtx low, high;
945             split_double (operands[1], &low, &high);
946             val[0] = INTVAL (low);
947             val[1] = INTVAL (high);
948           }
949         if (CONST_DOUBLE_P (operands[1]))
950           {
951             if (GET_MODE (operands[1]) == DFmode)
952               {
953                 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
954                 REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
955               }
956             else if (GET_MODE (operands[1]) == VOIDmode
957                      || GET_MODE (operands[1]) == DImode)
958               {
959                 val[0] = CONST_DOUBLE_LOW (operands[1]);
960                 val[1] = CONST_DOUBLE_HIGH (operands[1]);
961               }
962           }
964         if (MEM_P (operands[1])
965             && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
966           {
967             rtx temp = operands[0];
969             while (GET_CODE (temp) == SUBREG)
970               temp = SUBREG_REG (temp);
972             gcc_assert (REG_P (temp));
974             if (reg_overlap_mentioned_p (gen_rtx_REG (SImode, REGNO (temp)),
975                                          XEXP (operands[1], 0)))
976               return \"mov %H1, %H0\; mov %L1, %L0\";
977             else
978               return \"mov %L1, %L0\; mov %H1, %H0\";
979           }
980         else if (MEM_P (operands[1])
981                  && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
982                  && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
983           {
984             rtx xoperands[2];
986             xoperands[0] = operands[0];
987             xoperands[1] = XEXP (operands[1], 0);
989             output_asm_insn (\"mov %1, %L0\; mov (4, %L0), %H0\; mov (%L0), %L0\",
990                              xoperands);
991             return \"\";
992           }
993         else
994           {
995             if ((CONST_INT_P (operands[1])
996                  || CONST_DOUBLE_P (operands[1]))
997                 && val[0] == 0)
998               {
999                 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
1000                   output_asm_insn (\"mov 0, %L0\", operands);
1001                 else
1002                   output_asm_insn (\"mov %L1, %L0\", operands);
1003               }
1004             else if ((CONST_INT_P (operands[1])
1005                       || CONST_DOUBLE_P (operands[1]))
1006                      && (REGNO_REG_CLASS (true_regnum (operands[0]))
1007                          == EXTENDED_REGS)
1008                      && (((val[0] & 0x80) && ! (val[0] & 0xffffff00))
1009                          || ((val[0] & 0x800000) && ! (val[0] & 0xff000000))))
1010               output_asm_insn (\"movu %L1, %L0\", operands);
1011             else
1012               output_asm_insn (\"mov %L1, %L0\", operands);
1014             if ((CONST_INT_P (operands[1])
1015                  || CONST_DOUBLE_P (operands[1]))
1016                 && val[1] == 0)
1017               {
1018                 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
1019                   output_asm_insn (\"mov 0, %H0\", operands);
1020                 else
1021                   output_asm_insn (\"mov %H1, %H0\", operands);
1022               }
1023             else if ((CONST_INT_P (operands[1])
1024                       || CONST_DOUBLE_P (operands[1]))
1025                      && val[0] == val[1])
1026               output_asm_insn (\"mov %L0, %H0\", operands);
1027             else if ((CONST_INT_P (operands[1])
1028                       || CONST_DOUBLE_P (operands[1]))
1029                      && (REGNO_REG_CLASS (true_regnum (operands[0]))
1030                          == EXTENDED_REGS)
1031                      && (((val[1] & 0x80) && ! (val[1] & 0xffffff00))
1032                          || ((val[1] & 0x800000) && ! (val[1] & 0xff000000))))
1033               output_asm_insn (\"movu %H1, %H0\", operands);
1034             else
1035               output_asm_insn (\"mov %H1, %H0\", operands);
1036             return \"\";
1037           }
1038     default:
1039       gcc_unreachable ();
1040     }
1041   }"
1042   ;; Timings of "37" is approximation of the worst case sceanario.
1043   [(set_attr_alternative "timings"
1044                          [(const_int 11)
1045                           (const_int 22)
1046                           (const_int 37)
1047                           (const_int 37)
1048                           (const_int 37)
1049                           (const_int 37)
1050                           (const_int 37)
1051                           (const_int 37)
1052                          ])
1053   ]
1056 ;; ----------------------------------------------------------------------
1057 ;; ADD INSTRUCTIONS
1058 ;; ----------------------------------------------------------------------
1060 (define_expand "addsi3"
1061   [(parallel [(set (match_operand:SI          0 "register_operand")
1062                    (plus:SI (match_operand:SI 1 "register_operand")
1063                             (match_operand:SI 2 "nonmemory_operand")))
1064               (clobber (reg:CC CC_REG))
1065              ])
1066   ]
1067   ""
1068   "")
1070 (define_insn "*am33_addsi3"
1071   [(set (match_operand:SI          0 "register_operand" "=dx,a,x,a,dax,!*y,!dax")
1072         (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,dax")
1073                  (match_operand:SI 2 "nonmemory_operand" "J,J,L,L,daxi,i,dax")))
1074    (clobber (reg:CC CC_REG))
1075   ]
1076   "TARGET_AM33"
1077   "*
1079   switch (which_alternative)
1080     {
1081     case 0:
1082     case 1:
1083       return \"inc %0\";
1084     case 2:
1085     case 3:
1086       return \"inc4 %0\";
1087     case 4:
1088     case 5:
1089       return \"add %2,%0\";
1090     case 6:
1091       {
1092         enum reg_class src1_class, src2_class, dst_class;
1094         src1_class = REGNO_REG_CLASS (true_regnum (operands[1]));
1095         src2_class = REGNO_REG_CLASS (true_regnum (operands[2]));
1096         dst_class = REGNO_REG_CLASS (true_regnum (operands[0]));
1098         /* I'm not sure if this can happen or not.  Might as well be prepared
1099           and generate the best possible code if it does happen.  */
1100         if (true_regnum (operands[0]) == true_regnum (operands[1]))
1101           return \"add %2,%0\";
1102         if (true_regnum (operands[0]) == true_regnum (operands[2]))
1103           return \"add %1,%0\";
1105         /* Catch cases where no extended register was used.  These should be
1106            handled just like the mn10300.  */
1107         if (src1_class != EXTENDED_REGS
1108             && src2_class != EXTENDED_REGS
1109             && dst_class != EXTENDED_REGS)
1110           {
1111             /* We have to copy one of the sources into the destination, then
1112                add the other source to the destination.
1114                Carefully select which source to copy to the destination; a
1115                naive implementation will waste a byte when the source classes
1116                are different and the destination is an address register.
1117                Selecting the lowest cost register copy will optimize this
1118                sequence.  */
1119             if (REGNO_REG_CLASS (true_regnum (operands[1]))
1120                 == REGNO_REG_CLASS (true_regnum (operands[0])))
1121               return \"mov %1,%0\;add %2,%0\";
1122             return \"mov %2,%0\;add %1,%0\";
1123           }
1125         /* At least one register is an extended register.  */
1127         /* The three operand add instruction on the am33 is a win iff the
1128            output register is an extended register, or if both source
1129            registers are extended registers.  */
1130         if (dst_class == EXTENDED_REGS
1131             || src1_class == src2_class)
1132           return \"add %2,%1,%0\";
1134       /* It is better to copy one of the sources to the destination, then
1135          perform a 2 address add.  The destination in this case must be
1136          an address or data register and one of the sources must be an
1137          extended register and the remaining source must not be an extended
1138          register.
1140          The best code for this case is to copy the extended reg to the
1141          destination, then emit a two address add.  */
1142       if (src1_class == EXTENDED_REGS)
1143         return \"mov %1,%0\;add %2,%0\";
1144       return \"mov %2,%0\;add %1,%0\";
1145       }
1146     default:
1147       gcc_unreachable ();
1148     }
1149   }"
1150   [(set_attr "timings" "11,11,11,11,11,11,22")]
1153 (define_insn "*mn10300_addsi3"
1154   [(set (match_operand:SI          0 "register_operand" "=dx,a,a,dax,!*y,!dax")
1155         (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,dax")
1156                  (match_operand:SI 2 "nonmemory_operand" "J,J,L,daxi,i,dax")))
1157    (clobber (reg:CC CC_REG))
1158   ]
1159   ""
1160   "*
1162   switch (which_alternative)
1163     {
1164     case 0:
1165     case 1:
1166       return \"inc %0\";
1167     case 2:
1168       return \"inc4 %0\";
1169     case 3:
1170     case 4:
1171       return \"add %2,%0\";
1172     case 5:
1173       /* I'm not sure if this can happen or not.  Might as well be prepared
1174          and generate the best possible code if it does happen.  */
1175       if (true_regnum (operands[0]) == true_regnum (operands[1]))
1176         return \"add %2,%0\";
1177       if (true_regnum (operands[0]) == true_regnum (operands[2]))
1178         return \"add %1,%0\";
1180       /* We have to copy one of the sources into the destination, then add
1181          the other source to the destination.
1183          Carefully select which source to copy to the destination; a naive
1184          implementation will waste a byte when the source classes are different
1185          and the destination is an address register.  Selecting the lowest
1186          cost register copy will optimize this sequence.  */
1187       if (REGNO_REG_CLASS (true_regnum (operands[1]))
1188           == REGNO_REG_CLASS (true_regnum (operands[0])))
1189         return \"mov %1,%0\;add %2,%0\";
1190       return \"mov %2,%0\;add %1,%0\";
1191     default:
1192       gcc_unreachable ();
1193     }
1195   [(set_attr "timings" "11,11,11,11,11,22")]
1198 ;; ----------------------------------------------------------------------
1199 ;; SUBTRACT INSTRUCTIONS
1200 ;; ----------------------------------------------------------------------
1202 (define_expand "subsi3"
1203   [(parallel [(set (match_operand:SI           0 "register_operand")
1204                    (minus:SI (match_operand:SI 1 "register_operand")
1205                              (match_operand:SI 2 "nonmemory_operand")))
1206               (clobber (reg:CC CC_REG))
1207              ])
1208   ]
1209   ""
1210   "")
1212 (define_insn "*am33_subsi3"
1213   [(set (match_operand:SI           0 "register_operand" "=dax,!dax")
1214         (minus:SI (match_operand:SI 1 "register_operand" "0,dax")
1215                   (match_operand:SI 2 "nonmemory_operand" "daxi,dax")))
1216    (clobber (reg:CC CC_REG))
1217   ]
1218   "TARGET_AM33"
1219   "*
1220   {
1221     if (true_regnum (operands[0]) == true_regnum (operands[1]))
1222       return \"sub %2,%0\";
1223     else
1224       {
1225         enum reg_class src1_class, src2_class, dst_class;
1227         src1_class = REGNO_REG_CLASS (true_regnum (operands[1]));
1228         src2_class = REGNO_REG_CLASS (true_regnum (operands[2]));
1229         dst_class = REGNO_REG_CLASS (true_regnum (operands[0]));
1231         /* If no extended registers are used, then the best way to handle
1232            this is to copy the first source operand into the destination
1233            and emit a two address subtraction.  */
1234         if (src1_class != EXTENDED_REGS
1235             && src2_class != EXTENDED_REGS
1236             && dst_class != EXTENDED_REGS
1237             && true_regnum (operands[0]) != true_regnum (operands[2]))
1238           return \"mov %1,%0\;sub %2,%0\";
1239         return \"sub %2,%1,%0\";
1240       }
1241   }"
1242   [(set_attr "timings" "11,22")]
1245 (define_insn "*mn10300_subsi3"
1246   [(set (match_operand:SI           0 "register_operand" "=dax")
1247         (minus:SI (match_operand:SI 1 "register_operand" "0")
1248                   (match_operand:SI 2 "nonmemory_operand" "daxi")))
1249    (clobber (reg:CC CC_REG))
1250   ]
1251   ""
1252   "sub %2,%0"
1253   [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
1254                                        (const_int 11) (const_int 22)))]
1257 (define_expand "negsi2"
1258   [(set (match_operand:SI         0 "register_operand")
1259         (neg:SI (match_operand:SI 1 "register_operand")))]
1260   ""
1261   "
1263   rtx target = gen_reg_rtx (SImode);
1265   emit_move_insn (target, const0_rtx);
1266   emit_insn (gen_subsi3 (target, target, operands[1]));
1267   emit_move_insn (operands[0], target);
1268   DONE;
1271 ;; ----------------------------------------------------------------------
1272 ;; MULTIPLY INSTRUCTIONS
1273 ;; ----------------------------------------------------------------------
1275 (define_insn "mulsidi3"
1276   [(set (match_operand:DI 0 "register_operand" "=dax")
1277         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "dax"))
1278                  (sign_extend:DI (match_operand:SI 2 "register_operand" "dax"))))
1279    (clobber (reg:CC CC_REG))
1280   ]
1281   "TARGET_AM33"
1282   "mul %1,%2,%H0,%L0"
1283   [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
1284                                        (const_int 24) (const_int 23)))]
1287 (define_insn "umulsidi3"
1288   [(set (match_operand:DI                          0 "register_operand" "=dax")
1289         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "dax"))
1290                  (zero_extend:DI (match_operand:SI 2 "register_operand" "dax"))))
1291    (clobber (reg:CC CC_REG))
1292   ]
1293   "TARGET_AM33"
1294   "mulu %1,%2,%H0,%L0"
1295   [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
1296                                        (const_int 24) (const_int 23)))]
1299 (define_expand "mulsi3"
1300   [(parallel [(set (match_operand:SI          0 "register_operand")
1301                    (mult:SI (match_operand:SI 1 "register_operand")
1302                             (match_operand:SI 2 "register_operand")))
1303               (clobber (reg:CC CC_REG))
1304              ])
1305   ]
1306   ""
1307   "")
1309 (define_insn "*am33_mulsi3"
1310   [(set (match_operand:SI          0 "register_operand" "=dx,!dax")
1311         (mult:SI (match_operand:SI 1 "register_operand" "%0,0")
1312                  (match_operand:SI 2 "nonmemory_operand" "dx,daxi")))
1313    (clobber (reg:CC CC_REG))
1314   ]
1315   "TARGET_AM33"
1316   "*
1318   if (TARGET_MULT_BUG)
1319     return \"nop\;nop\;mul %2,%0\";
1320   else
1321     return \"mul %2,%0\";
1323   [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") (const_int 24) (const_int 23)))]
1326 (define_insn "*mn10300_mulsi3"
1327   [(set (match_operand:SI          0 "register_operand" "=dx")
1328         (mult:SI (match_operand:SI 1 "register_operand" "%0")
1329                  (match_operand:SI 2 "register_operand" "dx")))
1330    (clobber (reg:CC CC_REG))
1331   ]
1332   ""
1333   "*
1335   if (TARGET_MULT_BUG)
1336     return \"nop\;nop\;mul %2,%0\";
1337   else
1338     return \"mul %2,%0\";
1340   [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
1341                                        (const_int 24) (const_int 23)))]
1344 (define_expand "udivmodsi4"
1345   [(parallel [(set (match_operand:SI          0 "register_operand")
1346                    (udiv:SI (match_operand:SI 1 "general_operand")
1347                             (match_operand:SI 2 "general_operand")))
1348               (set (match_operand:SI          3 "register_operand")
1349                    (umod:SI (match_dup 1) (match_dup 2)))
1350               (clobber (reg:CC CC_REG))
1351              ])
1352   ]
1353   ""
1354   "{
1355     if (!register_operand (operands[1], SImode))
1356       operands[1] = copy_to_mode_reg (SImode, operands[1]);
1357     if (!register_operand (operands[2], SImode))
1358       operands[2] = copy_to_mode_reg (SImode, operands[2]);
1359    }"
1362 (define_insn "*udivmodsi4"
1363   [(set (match_operand:SI          0 "register_operand" "=dx")
1364         (udiv:SI (match_operand:SI 1 "register_operand" "0")
1365                  (match_operand:SI 2 "register_operand" "dx")))
1366    (set (match_operand:SI          3 "register_operand" "=&d")
1367         (umod:SI (match_dup 1) (match_dup 2)))
1368    (clobber (reg:CC CC_REG))
1369   ]
1370   ""
1371   "*
1373   output_asm_insn (\"sub %3,%3\;mov %3,mdr\", operands);
1375   if (find_reg_note (insn, REG_UNUSED, operands[3]))
1376     return \"divu %2,%0\";
1377   else
1378     return \"divu %2,%0\;mov mdr,%3\";
1380   ;; Timings:  AM33   AM34
1381   ;;  SUB       1/1    1/1
1382   ;;  MOV       1/1    1/1
1383   ;;  DIVU     38/39  42/43
1384   ;;  MOV       1/1    1/1
1385   ;;  --------------------
1386   ;;  total    41/42  45/46  (worst case sceanario)
1387   [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
1388                                        (const_int 4546) (const_int 4142)))]
1391 (define_insn "divmodsi4"
1392   [(set (match_operand:SI          0 "register_operand" "=dx")
1393         (div:SI (match_operand:SI  1 "register_operand"  "0")
1394                  (match_operand:SI 2 "register_operand"  "dx")))
1395    (set (match_operand:SI          3 "register_operand" "=d")
1396         (mod:SI (match_dup 1) (match_dup 2)))
1397    (clobber (reg:CC CC_REG))
1398   ]
1399   ""
1400   "*
1402   if (find_reg_note (insn, REG_UNUSED, operands[3]))
1403     return \"ext %0\;div %2,%0\";
1404   else
1405     return \"ext %0\;div %2,%0\;mov mdr,%3\";
1407   ;; Timings:  AM33   AM34
1408   ;;  EXT       1/1    1/1
1409   ;;  DIV      38/39  42/43
1410   ;;  --------------------
1411   ;;  total    39/40  43/44  (worst case sceanario)
1412   [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
1413                                        (const_int 4344) (const_int 3940)))]
1417 ;; ----------------------------------------------------------------------
1418 ;; AND INSTRUCTIONS
1419 ;; ----------------------------------------------------------------------
1421 (define_expand "andsi3"
1422   [(parallel [(set (match_operand:SI         0 "register_operand")
1423                    (and:SI (match_operand:SI 1 "register_operand")
1424                            (match_operand:SI 2 "nonmemory_operand")))
1425               (clobber (reg:CC CC_REG))
1426              ])
1427   ]
1428   ""
1429   "")
1431 (define_insn "*am33_andsi3"
1432   [(set (match_operand:SI         0 "register_operand" "=dx,dx,!dax")
1433         (and:SI (match_operand:SI 1 "register_operand" "%0,0,dax")
1434                 (match_operand:SI 2 "nonmemory_operand" "N,dxi,dax")))
1435    (clobber (reg:CC CC_REG))
1436   ]
1437   "TARGET_AM33"
1438   {
1439     if (CONST_INT_P (operands[2]))
1440       switch (INTVAL (operands[2]))
1441         {
1442         case 0xff:       return "extbu %0";
1443         case 0xffff:     return "exthu %0";
1444         case 0x7fffffff: return "add  %0, %0; lsr 1, %0";
1445         case 0x3fffffff: return "asl2 %0; lsr 2, %0";
1446         case 0x1fffffff: return "add  %0, %0; asl2 %0; lsr 3, %0";
1447         case 0x0fffffff: return "asl2 %0; asl2 %0; lsr 4, %0";
1448         case 0xfffffffe: return "lsr 1, %0; add  %0, %0";
1449         case 0xfffffffc: return "lsr 2, %0; asl2 %0";
1450         case 0xfffffff8: return "lsr 3, %0; add  %0, %0; asl2 %0";
1451         case 0xfffffff0: return "lsr 4, %0; asl2 %0; asl2 %0";
1452         }
1453       
1454     if (REG_P (operands[2]) && REG_P (operands[1])
1455         && true_regnum (operands[0]) != true_regnum (operands[1])
1456         && true_regnum (operands[0]) != true_regnum (operands[2])
1457         && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1458         && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1459         && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
1460       return "mov %1, %0; and %2, %0";
1461     if (REG_P (operands[2]) && REG_P (operands[1])
1462         && true_regnum (operands[0]) != true_regnum (operands[1])
1463         && true_regnum (operands[0]) != true_regnum (operands[2]))
1464       return "and %1, %2, %0";
1465     if (REG_P (operands[2]) && REG_P (operands[0])
1466         && true_regnum (operands[2]) == true_regnum (operands[0]))
1467       return "and %1, %0";
1469     return "and %2, %0";
1470   }
1471   [(set_attr "timings" "33")]
1474 (define_insn "*mn10300_andsi3"
1475   [(set (match_operand:SI         0 "register_operand" "=dx,dx")
1476         (and:SI (match_operand:SI 1 "register_operand" "%0,0")
1477                 (match_operand:SI 2 "nonmemory_operand" "N,dxi")))
1478    (clobber (reg:CC CC_REG))
1479   ]
1480   ""
1481   {
1482     if (CONST_INT_P (operands[2]))
1483       switch (INTVAL (operands[2]))
1484         {
1485         case 0xff:       return "extbu %0";
1486         case 0xffff:     return "exthu %0";
1487         case 0x7fffffff: return "add  %0, %0; lsr 1, %0";
1488         case 0x3fffffff: return "asl2 %0; lsr 2, %0";
1489         case 0x1fffffff: return "add  %0, %0; asl2 %0; lsr 3, %0";
1490         case 0x0fffffff: return "asl2 %0; asl2 %0; lsr 4, %0";
1491         case 0xfffffffe: return "lsr 1, %0; add  %0, %0";
1492         case 0xfffffffc: return "lsr 2, %0; asl2 %0";
1493         case 0xfffffff8: return "lsr 3, %0; add  %0, %0; asl2 %0";
1494         case 0xfffffff0: return "lsr 4, %0; asl2 %0; asl2 %0";
1495         }
1497     return "and %2, %0";
1498   }
1499   [(set_attr "timings" "33")]
1502 ;; ----------------------------------------------------------------------
1503 ;; OR INSTRUCTIONS
1504 ;; ----------------------------------------------------------------------
1506 (define_expand "iorsi3"
1507   [(parallel [(set (match_operand:SI         0 "register_operand")
1508                    (ior:SI (match_operand:SI 1 "register_operand")
1509                            (match_operand:SI 2 "nonmemory_operand")))
1510               (clobber (reg:CC CC_REG))
1511              ])
1512   ]
1513   ""
1514   "")
1516 (define_insn "*am33_iorsi3"
1517   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1518         (ior:SI (match_operand:SI 1 "register_operand" "%0,dax")
1519                 (match_operand:SI 2 "nonmemory_operand" "dxi,dax")))
1520    (clobber (reg:CC CC_REG))
1521   ]
1522   "TARGET_AM33"
1523   "*
1524   {
1525     if (REG_P (operands[2]) && REG_P (operands[1])
1526         && true_regnum (operands[0]) != true_regnum (operands[1])
1527         && true_regnum (operands[0]) != true_regnum (operands[2])
1528         && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1529         && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1530         && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
1531       return \"mov %1,%0\;or %2,%0\";
1532     if (REG_P (operands[2]) && REG_P (operands[1])
1533         && true_regnum (operands[0]) != true_regnum (operands[1])
1534         && true_regnum (operands[0]) != true_regnum (operands[2]))
1535       return \"or %1,%2,%0\";
1536     if (REG_P (operands[2]) && REG_P (operands[0])
1537         && true_regnum (operands[2]) == true_regnum (operands[0]))
1538       return \"or %1,%0\";
1539     return \"or %2,%0\";
1540   }"
1541   [(set_attr "timings" "22")]
1544 (define_insn "*mn10300_iorsi3"
1545   [(set (match_operand:SI         0 "register_operand" "=dx")
1546         (ior:SI (match_operand:SI 1 "register_operand" "%0")
1547                 (match_operand:SI 2 "nonmemory_operand" "dxi")))
1548    (clobber (reg:CC CC_REG))
1549   ]
1550   ""
1551   "or %2,%0"
1552   [(set_attr "timings" "33")]
1555 ;; ----------------------------------------------------------------------
1556 ;; XOR INSTRUCTIONS
1557 ;; ----------------------------------------------------------------------
1559 (define_expand "xorsi3"
1560   [(parallel [(set (match_operand:SI         0 "register_operand")
1561                    (xor:SI (match_operand:SI 1 "register_operand")
1562                            (match_operand:SI 2 "nonmemory_operand")))
1563               (clobber (reg:CC CC_REG))
1564              ])
1565   ]
1566   ""
1567   "")
1569 (define_insn "*am33_xorsi3"
1570   [(set (match_operand:SI         0 "register_operand" "=dx,!dax")
1571         (xor:SI (match_operand:SI 1 "register_operand" "%0,dax")
1572                 (match_operand:SI 2 "nonmemory_operand" "dxi,dax")))
1573    (clobber (reg:CC CC_REG))
1574   ]
1575   "TARGET_AM33"
1576   "*
1577   {
1578     if (REG_P (operands[2]) && REG_P (operands[1])
1579         && true_regnum (operands[0]) != true_regnum (operands[1])
1580         && true_regnum (operands[0]) != true_regnum (operands[2])
1581         && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1582         && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1583         && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
1584       return \"mov %1,%0\;xor %2,%0\";
1585     if (REG_P (operands[2]) && REG_P (operands[1])
1586         && true_regnum (operands[0]) != true_regnum (operands[1])
1587         && true_regnum (operands[0]) != true_regnum (operands[2]))
1588       return \"xor %1,%2,%0\";
1589     if (REG_P (operands[2]) && REG_P (operands[0])
1590         && true_regnum (operands[2]) == true_regnum (operands[0]))
1591       return \"xor %1,%0\";
1592     return \"xor %2,%0\";
1593   }"
1594   [(set_attr "timings" "22")]
1597 (define_insn "*mn10300_xorsi3"
1598   [(set (match_operand:SI         0 "register_operand" "=dx")
1599         (xor:SI (match_operand:SI 1 "register_operand" "%0")
1600                 (match_operand:SI 2 "nonmemory_operand" "dxi")))
1601    (clobber (reg:CC CC_REG))
1602   ]
1603   ""
1604   "xor %2,%0"
1605   [(set_attr "timings" "11")]
1608 ;; ----------------------------------------------------------------------
1609 ;; NOT INSTRUCTIONS
1610 ;; ----------------------------------------------------------------------
1612 (define_expand "one_cmplsi2"
1613   [(parallel [(set (match_operand:SI         0 "register_operand")
1614                    (not:SI (match_operand:SI 1 "register_operand")))
1615               (clobber (reg:CC CC_REG))
1616              ])
1617   ]
1618   ""
1619   "")
1621 (define_insn "*am33_cmplsi2"
1622   [(set (match_operand:SI         0 "register_operand" "=dx,!dax")
1623         (not:SI (match_operand:SI 1 "register_operand" "0,0")))
1624    (clobber (reg:CC CC_REG))
1625   ]
1626   "TARGET_AM33"
1627   "not %0"
1630 (define_insn "*mn10300_cmplsi2"
1631   [(set (match_operand:SI         0 "register_operand" "=dx")
1632         (not:SI (match_operand:SI 1 "register_operand" "0")))
1633    (clobber (reg:CC CC_REG))
1634   ]
1635   ""
1636   "not %0"
1639 ;; -----------------------------------------------------------------
1640 ;; BIT FIELDS
1641 ;; -----------------------------------------------------------------
1644 ;; These set/clear memory in byte sized chunks.
1646 ;; They are no smaller/faster than loading the value into a register
1647 ;; and storing the register, but they don't need a scratch register
1648 ;; which may allow for better code generation.
1649 (define_insn "*byte_clear"
1650   [(set (match_operand:QI 0 "nonimmediate_operand" "=R,d") (const_int 0))
1651    (clobber (reg:CC CC_REG))
1652    ]
1653   "(! MEM_P (operands[0])) || (! MEM_VOLATILE_P (operands[0])
1654                                && GET_CODE (XEXP (operands[0], 0)) != PLUS)"
1655   "@
1656   bclr 255,%A0
1657   clr %0"
1658   [(set_attr_alternative "timings"
1659                          [(if_then_else (eq_attr "cpu" "am34")
1660                                         (const_int 66) (const_int 77))
1661                           (const_int 11)
1662                          ])
1663   ]
1666 (define_insn "*byte_set"
1667   [(set (match_operand:QI 0 "nonimmediate_operand" "=R,d") (const_int -1))
1668    (clobber (reg:CC CC_REG))
1669   ]
1670   "(! MEM_P (operands[0])) || (! MEM_VOLATILE_P (operands[0])
1671                                && GET_CODE (XEXP (operands[0], 0)) != PLUS)"
1672   "@
1673   bset 255,%A0
1674   mov -1,%0"
1675   [(set_attr_alternative "timings"
1676                          [(if_then_else (eq_attr "cpu" "am34")
1677                                         (const_int 66) (const_int 77))
1678                           (const_int 11)
1679                          ])
1680   ]
1683 (define_insn "*bit_clear1"
1684   [(set (match_operand:QI 0 "nonimmediate_operand" "+R,d")
1685         (subreg:QI
1686           (and:SI (subreg:SI (match_dup 0) 0)
1687                   (match_operand:SI 1 "const_int_operand" "i,i")) 0))
1688    (clobber (reg:CC CC_REG))
1689   ]
1690   ""
1691   "@
1692   bclr %N1,%A0
1693   and %1,%0"
1694   [(set_attr_alternative "timings"
1695                          [(if_then_else (eq_attr "cpu" "am34")
1696                                         (const_int 66) (const_int 77))
1697                           (const_int 11)
1698                          ])
1699   ]
1702 (define_insn "*bit_clear2"
1703   [(set (match_operand:QI 0 "memory_operand" "=R,T")
1704         (and:QI
1705          (match_dup 0)
1706          (not:QI (match_operand:QI 1 "nonmemory_operand" "i,d"))))
1707    (clobber (reg:CC CC_REG))
1708   ]
1709   ""
1710   "@
1711   bclr %U1,%A0
1712   bclr %1,%0"
1713   [(set_attr_alternative "timings"
1714                          [(if_then_else (eq_attr "cpu" "am34")
1715                                         (const_int 66) (const_int 77))
1716                           (const_int 66)
1717                          ])
1718   ]
1721 (define_insn "*bit_set"
1722   [(set (match_operand:QI 0 "nonimmediate_operand" "+R,d")
1723         (subreg:QI
1724           (ior:SI (subreg:SI (match_dup 0) 0)
1725                   (match_operand:SI 1 "const_int_operand" "i,i")) 0))
1726    (clobber (reg:CC CC_REG))
1727   ]
1728   ""
1729   "@
1730   bset %U1,%A0
1731   or %1,%0"
1732   [(set_attr_alternative "timings"
1733                          [(if_then_else (eq_attr "cpu" "am34")
1734                                         (const_int 66) (const_int 77))
1735                           (const_int 11)
1736                          ])
1737   ]
1740 (define_expand "iorqi3"
1741   [(parallel [(set (match_operand:QI         0 "nonimmediate_operand")
1742                    (ior:QI (match_operand:QI 1 "nonimmediate_operand")
1743                            (match_operand:QI 2 "nonmemory_operand")))
1744               (clobber (reg:CC CC_REG))
1745              ])
1746   ]
1747   ""
1748   "")
1750 (define_insn "*am33_iorqi3"
1751   [(set (match_operand:QI         0 "nonimmediate_operand" "=R,T,r")
1752         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
1753                 ;; This constraint should really be nonmemory_operand,
1754                 ;; but making it general_operand, along with the
1755                 ;; condition that not both input operands are MEMs,
1756                 ;; helps combine do a better job.
1757                 (match_operand:QI 2 "general_operand" "i,d,ir")))
1758    (clobber (reg:CC CC_REG))
1759   ]
1760   "TARGET_AM33 && 
1761    ((! MEM_P (operands[2])) || (! MEM_P (operands[1])))"
1762   "@
1763   bset %U2,%A0
1764   bset %2,%0
1765   or %2,%0"
1766   [(set_attr_alternative "timings"
1767                          [(if_then_else (eq_attr "cpu" "am34")
1768                                         (const_int 66) (const_int 77))
1769                           (const_int 66)
1770                           (const_int 11)
1771                          ])
1772   ]
1775 (define_insn "*mn10300_iorqi3"
1776   [(set (match_operand:QI         0 "nonimmediate_operand" "=R,T,d")
1777         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
1778                 ;; This constraint should really be nonmemory_operand,
1779                 ;; but making it general_operand, along with the
1780                 ;; condition that not both input operands are MEMs,
1781                 ;; helps combine do a better job.
1782                 (match_operand:QI 2 "general_operand" "i,d,id")))
1783    (clobber (reg:CC CC_REG))
1784   ]
1785   "(! MEM_P (operands[2])) || (! MEM_P (operands[1]))"
1786   "@
1787   bset %U2,%A0
1788   bset %2,%0
1789   or %2,%0"
1790   [(set_attr_alternative "timings"
1791                          [(if_then_else (eq_attr "cpu" "am34")
1792                                         (const_int 66) (const_int 77))
1793                           (const_int 66)
1794                           (const_int 11)
1795                          ])
1796   ]
1799 (define_insn "*test_int_bitfield"
1800   [(set (reg:CC CC_REG)
1801      (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "dx")
1802                                (match_operand 1 "const_int_operand" "")
1803                                (match_operand 2 "const_int_operand" ""))
1804               (const_int 0)))]
1805   ""
1806   "*
1808   int len = INTVAL (operands[1]);
1809   int bit = INTVAL (operands[2]);
1810   int mask = 0;
1811   rtx xoperands[2];
1813   while (len > 0)
1814     {
1815       mask |= (1 << bit);
1816       bit++;
1817       len--;
1818     }
1820   xoperands[0] = operands[0];
1821   xoperands[1] = GEN_INT (trunc_int_for_mode (mask, SImode));
1822   output_asm_insn (\"btst %1,%0\", xoperands);
1823   return \"\";
1827 (define_insn "*test_byte_bitfield"
1828   [(set (reg:CC CC_REG)
1829      (compare (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "R,dx")
1830                                (match_operand 1 "const_int_operand" "")
1831                                (match_operand 2 "const_int_operand" ""))
1832               (const_int 0)))]
1833   "mn10300_mask_ok_for_mem_btst (INTVAL (operands[1]), INTVAL (operands[2]))"
1834   "*
1836   int len = INTVAL (operands[1]);
1837   int bit = INTVAL (operands[2]);
1838   int mask = 0;
1839   rtx xoperands[2];
1841   while (len > 0)
1842     {
1843       mask |= (1 << bit);
1844       bit++;
1845       len--;
1846     }
1848   /* If the source operand is not a reg (i.e. it is memory), then extract the
1849      bits from mask that we actually want to test.  Note that the mask will
1850      never cross a byte boundary.  */
1851   if (!REG_P (operands[0]))
1852     {
1853       if (mask & 0xff)
1854         mask = mask & 0xff;
1855       else if (mask & 0xff00)
1856         mask = (mask >> 8) & 0xff;
1857       else if (mask & 0xff0000)
1858         mask = (mask >> 16) & 0xff;
1859       else if (mask & 0xff000000)
1860         mask = (mask >> 24) & 0xff;
1861     }
1863   xoperands[0] = operands[0];
1864   xoperands[1] = GEN_INT (trunc_int_for_mode (mask, SImode));
1865   if (REG_P (operands[0]))
1866     output_asm_insn (\"btst %1,%0\", xoperands);
1867   else
1868     output_asm_insn (\"btst %U1,%A0\", xoperands);
1869   return \"\";
1871   [(set_attr_alternative "timings"
1872                          [(if_then_else (eq_attr "cpu" "am34")
1873                                         (const_int 11) (const_int 22))
1874                           (if_then_else (eq_attr "cpu" "am34")
1875                                         (const_int 44) (const_int 55))
1876                          ])
1877   ]
1880 (define_insn "*bit_test"
1881   [(set (reg:CC CC_REG)
1882         (compare (and:SI (match_operand:SI 0 "register_operand" "dx")
1883                          (match_operand:SI 1 "const_int_operand" ""))
1884                  (const_int 0)))
1885   ]
1886   ""
1887   "btst %1,%0"
1888   [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
1889                                        (const_int 11) (const_int 22)))]
1892 (define_insn "*subreg_bit_test"
1893   [(set (reg:CC CC_REG)
1894      (compare (and:SI
1895                (subreg:SI (match_operand:QI 0 "nonimmediate_operand" "R,dx") 0)
1896                (match_operand:SI 1 "const_8bit_operand" ""))
1897               (const_int 0)))]
1898   ""
1899   "@
1900   btst %U1,%A0
1901   btst %1,%0"
1902   [(set_attr_alternative "timings"
1903                          [(if_then_else (eq_attr "cpu" "am34")
1904                                         (const_int 44) (const_int 55))
1905                           (if_then_else (eq_attr "cpu" "am34")
1906                                         (const_int 11) (const_int 22))
1907                          ])
1908   ]
1912 ;; ----------------------------------------------------------------------
1913 ;; COMPARE AND BRANCH INSTRUCTIONS
1914 ;; ----------------------------------------------------------------------
1916 ;; We expand the comparison into a single insn so that it will not be split
1917 ;; up by reload.
1918 (define_expand "cbranchsi4"
1919   [(set (pc)
1920         (if_then_else
1921               (match_operator                    0 "ordered_comparison_operator"
1922                               [(match_operand:SI 1 "register_operand")
1923                                (match_operand:SI 2 "nonmemory_operand")])
1924               (label_ref (match_operand          3 ""))
1925               (pc)))]
1926   ""
1927   ""
1930 (define_insn_and_split "*cbranchsi4_post_reload"
1931   [(set (pc)
1932         (if_then_else (match_operator           3 "ordered_comparison_operator"
1933                        [(match_operand:SI       0 "register_operand"  "dax")
1934                         (match_operand:SI       1 "nonmemory_operand" "daxi")])
1935                       (label_ref (match_operand 2 "" ""))
1936                       (pc)))
1937    ]
1938   ""
1939   "#"
1940   "reload_completed"
1941   [(const_int 0)]
1942   "
1943   /* We construct the split by hand as otherwise the JUMP_LABEL
1944      attribute is not set correctly on the jump insn.  */
1945   emit_insn (gen_cmpsi (operands[0], operands[1]));
1946   
1947   emit_jump_insn (gen_integer_conditional_branch
1948                       (gen_rtx_fmt_ee (GET_CODE (operands[3]),
1949                                        CCmode,
1950                                        gen_rtx_REG (CCmode, CC_REG),
1951                                                     const0_rtx),
1952                                        operands[2]));
1953   "
1956 ;; Ordinarily, the cmp instruction will set the Z bit of cc0 to 1 if
1957 ;; its operands hold equal values, but the operands of a cmp
1958 ;; instruction must be distinct registers.  In the case where we'd
1959 ;; like to compare a register to itself, we can achieve this effect
1960 ;; with a btst 0,d0 instead.  (This will not alter the contents of d0
1961 ;; but will have the proper effect on cc0.  Using d0 is arbitrary; any
1962 ;; data register would work.)
1964 ;; Even though the first alternative would be preferable if it can
1965 ;; possibly match, reload must not be given the opportunity to attempt
1966 ;; to use it.  It assumes that such matches can only occur when one of
1967 ;; the operands is used for input and the other for output.  Since
1968 ;; this is not the case, it abort()s.  Indeed, such a reload cannot be
1969 ;; possibly satisfied, so just mark the alternative with a `!', so
1970 ;; that it is not considered by reload.
1972 (define_insn "cmpsi"
1973   [(set (reg:CC CC_REG)
1974         (compare (match_operand:SI 0 "register_operand" "!*d*a*x,dax,dax")
1975                  (match_operand:SI 1 "nonmemory_operand" "*0,I,daxi")))]
1976   ""
1977   {
1978     if (which_alternative == 0)
1979       return \"btst 0,d0\";
1980     if (which_alternative == 1)
1981       return mn10300_output_cmp (operands[0], insn);
1982     return \"cmp %1,%0\";
1983   }
1984   [(set_attr_alternative "timings"
1985                          [(const_int 11)
1986                           (if_then_else (eq_attr "cpu" "am34")
1987                                         (const_int 11) (const_int 22))
1988                           (const_int 22)
1989                          ])
1990   ]
1993 (define_insn "integer_conditional_branch"
1994   [(set (pc)
1995         (if_then_else (match_operator 0 "comparison_operator"
1996                                       [(reg:CC CC_REG) (const_int 0)])
1997                       (label_ref (match_operand 1 "" ""))
1998                       (pc)))]
1999   ""
2000   "b%b0 %1"
2003 (define_expand "cbranchsf4"
2004   [(set (pc)
2005       (if_then_else
2006             (match_operator                    0 "ordered_comparison_operator"
2007                             [(match_operand:SF 1 "register_operand")
2008                              (match_operand:SF 2 "nonmemory_operand")])
2009             (label_ref (match_operand          3 ""))
2010             (pc)))]
2011   "TARGET_AM33_2"
2012   ""
2015 (define_insn_and_split "*cbranchsf4_post_reload"
2016   [(set (pc)
2017         (if_then_else (match_operator            3 "ordered_comparison_operator"
2018                         [(match_operand:SF       0 "register_operand"  "f")
2019                          (match_operand:SF       1 "nonmemory_operand" "fF")])
2020                       (label_ref (match_operand  2 "" ""))
2021                       (pc)))
2022    ]
2023   "TARGET_AM33_2"
2024   "#"
2025   "&& reload_completed"
2026   [(const_int 0)]
2027   "
2028   /* We construct the split by hand as otherwise the JUMP_LABEL
2029      attribute is not set correctly on the jump insn.  */
2030   emit_insn (gen_am33_cmpsf (operands[0], operands[1]));
2031   
2032   emit_jump_insn (gen_float_conditional_branch
2033                      (gen_rtx_fmt_ee (GET_CODE (operands[3]),
2034                                       CC_FLOATmode,
2035                                       gen_rtx_REG (CC_FLOATmode, CC_REG),
2036                                       const0_rtx),
2037                                       operands[2]));
2038   "
2041 (define_insn "am33_cmpsf"
2042   [(set (reg:CC_FLOAT CC_REG)
2043         (compare:CC_FLOAT (match_operand:SF 0 "register_operand"  "f")
2044                           (match_operand:SF 1 "nonmemory_operand" "fF")))]
2045   "TARGET_AM33_2"
2046   "fcmp %1, %0"
2047   [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
2048                                        (const_int 17) (const_int 25)))]
2051 (define_insn "float_conditional_branch"
2052   [(set (pc)
2053         (if_then_else (match_operator 0 "comparison_operator"
2054                                       [(reg:CC_FLOAT CC_REG) (const_int 0)])
2055                       (label_ref (match_operand 1 "" ""))
2056                       (pc)))]
2057   "TARGET_AM33_2"
2058   "fb%b0 %1"
2059   [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
2060                                        (const_int 44) (const_int 33)))]
2063 ;; Unconditional and other jump instructions.
2065 (define_insn "jump"
2066   [(set (pc)
2067         (label_ref (match_operand 0 "" "")))]
2068   ""
2069   "jmp %l0"
2070   [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
2071                                        (const_int 11) (const_int 44)))]
2074 (define_insn "indirect_jump"
2075   [(set (pc) (match_operand:SI 0 "register_operand" "a"))]
2076   ""
2077   "jmp (%0)"
2078   [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
2079                                        (const_int 11) (const_int 33)))]
2082 (define_expand "builtin_setjmp_receiver"
2083   [(match_operand 0 "" "")]
2084   "flag_pic"
2085   "
2087   if (flag_pic)
2088     emit_insn (gen_GOTaddr2picreg ());
2090   DONE;
2093 (define_expand "casesi"
2094   [(match_operand:SI 0 "register_operand")
2095    (match_operand:SI 1 "immediate_operand")
2096    (match_operand:SI 2 "immediate_operand")
2097    (match_operand 3 "" "") (match_operand 4 "")]
2098   ""
2099   "
2101   rtx table = gen_reg_rtx (SImode);
2102   rtx index = gen_reg_rtx (SImode);
2103   rtx addr = gen_reg_rtx (Pmode);
2104   rtx test;
2106   emit_move_insn (table, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
2107   emit_insn (gen_addsi3 (index, operands[0], GEN_INT (- INTVAL (operands[1]))));
2108   test = gen_rtx_fmt_ee (GTU, VOIDmode, index, operands[2]);
2109   emit_jump_insn (gen_cbranchsi4 (test, index, operands[2], operands[4]));
2111   emit_insn (gen_ashlsi3 (index, index, const2_rtx));
2112   emit_move_insn (addr, gen_rtx_MEM (SImode,
2113                                      gen_rtx_PLUS (SImode, table, index)));
2114   if (flag_pic)
2115     emit_insn (gen_addsi3 (addr, addr, table));
2117   emit_jump_insn (gen_tablejump (addr, operands[3]));
2118   DONE;
2121 (define_insn "tablejump"
2122   [(set (pc) (match_operand:SI 0 "register_operand" "a"))
2123    (use (label_ref (match_operand 1 "" "")))]
2124   ""
2125   "jmp (%0)"
2126   [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
2127                                        (const_int 11) (const_int 33)))]
2130 ;; Call subroutine with no return value.
2132 (define_expand "call"
2133   [(call (match_operand:QI 0 "general_operand")
2134          (match_operand:SI 1 "general_operand"))]
2135   ""
2137   rtx fn = XEXP (operands[0], 0);
2139   if (flag_pic && GET_CODE (fn) == SYMBOL_REF)
2140     {
2141       if (MN10300_GLOBAL_P (fn))
2142         {
2143           /* The PLT code won't run on AM30, but then, there's no
2144              shared library support for AM30 either, so we just assume
2145              the linker is going to adjust all @PLT relocs to the
2146              actual symbols.  */
2147           emit_use (pic_offset_table_rtx);
2148           fn = gen_rtx_UNSPEC (SImode, gen_rtvec (1, fn), UNSPEC_PLT);
2149         }
2150       else
2151         fn = gen_rtx_UNSPEC (SImode, gen_rtvec (1, fn), UNSPEC_PIC);
2152     }
2153   if (! call_address_operand (fn, VOIDmode))
2154     fn = force_reg (SImode, fn);
2156   XEXP (operands[0], 0) = fn;
2159 (define_insn "*call_internal"
2160   [(call (mem:QI (match_operand:SI 0 "call_address_operand" "a,S"))
2161          (match_operand:SI 1 "" ""))]
2162   ""
2163   "@
2164    calls %C0
2165    call %C0,[],0"
2166   [(set_attr_alternative "timings"
2167                          [(if_then_else (eq_attr "cpu" "am34")
2168                                         (const_int 33) (const_int 44))
2169                           (if_then_else (eq_attr "cpu" "am34")
2170                                         (const_int 55) (const_int 33))
2171                          ])
2172   ]
2175 ;; Call subroutine, returning value in operand 0
2176 ;; (which must be a hard register).
2178 (define_expand "call_value"
2179   [(set (match_operand 0 "")
2180         (call (match_operand:QI 1 "general_operand")
2181               (match_operand:SI 2 "general_operand")))]
2182   ""
2184   rtx fn = XEXP (operands[1], 0);
2186   if (flag_pic && GET_CODE (fn) == SYMBOL_REF)
2187     {
2188       if (MN10300_GLOBAL_P (fn))
2189         {
2190           /* The PLT code won't run on AM30, but then, there's no
2191              shared library support for AM30 either, so we just assume
2192              the linker is going to adjust all @PLT relocs to the
2193              actual symbols.  */
2194           emit_use (pic_offset_table_rtx);
2195           fn = gen_rtx_UNSPEC (SImode, gen_rtvec (1, fn), UNSPEC_PLT);
2196         }
2197       else
2198         fn = gen_rtx_UNSPEC (SImode, gen_rtvec (1, fn), UNSPEC_PIC);
2199     }
2200   if (! call_address_operand (fn, VOIDmode))
2201     fn = force_reg (SImode, fn);
2203   XEXP (operands[1], 0) = fn;
2206 (define_insn "call_value_internal"
2207   [(set (match_operand 0 "" "")
2208         (call (mem:QI (match_operand:SI 1 "call_address_operand" "a,S"))
2209               (match_operand:SI 2 "" "")))]
2210   ""
2211   "@
2212    calls %C1
2213    call %C1,[],0"
2214   [(set_attr_alternative "timings"
2215                          [(if_then_else (eq_attr "cpu" "am34")
2216                                         (const_int 33) (const_int 44))
2217                           (if_then_else (eq_attr "cpu" "am34")
2218                                         (const_int 55) (const_int 33))
2219                          ])
2220   ]
2223 (define_expand "untyped_call"
2224   [(parallel [(call (match_operand 0 "")
2225                     (const_int 0))
2226               (match_operand 1 "")
2227               (match_operand 2 "")])]
2228   ""
2229   "
2231   int i;
2233   emit_call_insn (gen_call (operands[0], const0_rtx));
2235   for (i = 0; i < XVECLEN (operands[2], 0); i++)
2236     {
2237       rtx set = XVECEXP (operands[2], 0, i);
2238       emit_move_insn (SET_DEST (set), SET_SRC (set));
2239     }
2240   DONE;
2243 (define_insn "nop"
2244   [(const_int 0)]
2245   ""
2246   "nop"
2249 ;; ----------------------------------------------------------------------
2250 ;; EXTEND INSTRUCTIONS
2251 ;; ----------------------------------------------------------------------
2253 (define_expand "zero_extendqisi2"
2254   [(set (match_operand:SI 0 "register_operand")
2255         (zero_extend:SI
2256          (match_operand:QI 1 "nonimmediate_operand")))]
2257   ""
2258   "")
2260 (define_insn "*zero_extendqisi2_am33"
2261   [(set (match_operand:SI 0 "register_operand" "=dx,dx,dx,!dax,!dax,!dax")
2262         (zero_extend:SI
2263          (match_operand:QI 1 "nonimmediate_operand" "0,dax,m,0,dax,m")))]
2264   "TARGET_AM33"
2265   "@
2266   extbu %0
2267   mov %1,%0\;extbu %0
2268   movbu %1,%0
2269   extbu %0
2270   mov %1,%0\;extbu %0
2271   movbu %1,%0"
2272   [(set_attr_alternative "timings"
2273                          [(const_int 11)
2274                           (const_int 22)
2275                           (if_then_else (eq_attr "cpu" "am34")
2276                                         (const_int 13) (const_int 24))
2277                           (const_int 11)
2278                           (const_int 22)
2279                           (if_then_else (eq_attr "cpu" "am34")
2280                                         (const_int 13) (const_int 24))
2281                          ])
2282   ]
2285 (define_insn "*zero_extendqisi2_mn10300"
2286   [(set (match_operand:SI 0 "register_operand" "=dx,dx,dx")
2287         (zero_extend:SI
2288          (match_operand:QI 1 "nonimmediate_operand" "0,d,m")))]
2289   ""
2290   "@
2291   extbu %0
2292   mov %1,%0\;extbu %0
2293   movbu %1,%0"
2294   [(set_attr_alternative "timings"
2295                          [(const_int 11)
2296                           (const_int 22)
2297                           (if_then_else (eq_attr "cpu" "am34")
2298                                         (const_int 13) (const_int 24))
2299                          ])
2300   ]
2303 (define_expand "zero_extendhisi2"
2304   [(set (match_operand:SI 0 "register_operand")
2305         (zero_extend:SI
2306          (match_operand:HI 1 "nonimmediate_operand")))]
2307   ""
2308   "")
2310 (define_insn "*zero_extendhisi2_am33"
2311   [(set (match_operand:SI 0 "register_operand" "=dx,dx,dx,!dax,!dax,!dax")
2312         (zero_extend:SI
2313          (match_operand:HI 1 "nonimmediate_operand" "0,dax,m,0,dax,m")))]
2314   "TARGET_AM33"
2315   "@
2316   exthu %0
2317   mov %1,%0\;exthu %0
2318   movhu %1,%0
2319   exthu %0
2320   mov %1,%0\;exthu %0
2321   movhu %1,%0"
2322   [(set_attr_alternative "timings"
2323                          [(const_int 11)
2324                           (const_int 22)
2325                           (if_then_else (eq_attr "cpu" "am34")
2326                                         (const_int 13) (const_int 24))
2327                           (const_int 11)
2328                           (const_int 22)
2329                           (if_then_else (eq_attr "cpu" "am34")
2330                                         (const_int 13) (const_int 24))
2331                          ])
2332   ]
2335 (define_insn "*zero_extendhisi2_mn10300"
2336   [(set (match_operand:SI 0 "register_operand" "=dx,dx,dx")
2337         (zero_extend:SI
2338          (match_operand:HI 1 "nonimmediate_operand" "0,dx,m")))]
2339   ""
2340   "@
2341   exthu %0
2342   mov %1,%0\;exthu %0
2343   movhu %1,%0"
2344   [(set_attr_alternative "timings"
2345                          [(const_int 11)
2346                           (const_int 22)
2347                           (if_then_else (eq_attr "cpu" "am34")
2348                                         (const_int 13) (const_int 24))
2349                          ])
2350   ]
2353 ;;- sign extension instructions
2355 (define_expand "extendqisi2"
2356   [(set (match_operand:SI 0 "register_operand")
2357         (sign_extend:SI
2358          (match_operand:QI 1 "register_operand")))]
2359   ""
2360   "")
2362 (define_insn "*extendqisi2_am33"
2363   [(set (match_operand:SI 0 "register_operand" "=dx,dx,!dax,!dax")
2364         (sign_extend:SI
2365          (match_operand:QI 1 "register_operand" "0,dx,0,dax")))]
2366   "TARGET_AM33"
2367   "@
2368   extb %0
2369   mov %1,%0\;extb %0
2370   extb %0
2371   mov %1,%0\;extb %0"
2372   [(set_attr "timings" "11,22,11,22")]
2375 (define_insn "*extendqisi2_mn10300"
2376   [(set (match_operand:SI 0 "register_operand" "=dx,dx")
2377         (sign_extend:SI
2378          (match_operand:QI 1 "register_operand" "0,dx")))]
2379   ""
2380   "@
2381   extb %0
2382   mov %1,%0\;extb %0"
2383   [(set_attr "timings" "11,22")]
2386 (define_expand "extendhisi2"
2387   [(set (match_operand:SI 0 "register_operand")
2388         (sign_extend:SI
2389          (match_operand:HI 1 "register_operand")))]
2390   ""
2391   "")
2393 (define_insn "*extendhisi2_am33"
2394   [(set (match_operand:SI 0 "register_operand" "=dx,dx,!dax,!dax")
2395         (sign_extend:SI
2396          (match_operand:HI 1 "register_operand" "0,dax,0,dax")))]
2397   "TARGET_AM33"
2398   "@
2399   exth %0
2400   mov %1,%0\;exth %0
2401   exth %0
2402   mov %1,%0\;exth %0"
2403   [(set_attr "timings" "11,22,11,22")]
2406 (define_insn "*extendhisi2_mn10300"
2407   [(set (match_operand:SI 0 "register_operand" "=dx,dx")
2408         (sign_extend:SI
2409          (match_operand:HI 1 "register_operand" "0,dx")))]
2410   ""
2411   "@
2412   exth %0
2413   mov %1,%0\;exth %0"
2414   [(set_attr "timings" "11,22")]
2417 ;; ----------------------------------------------------------------------
2418 ;; SHIFTS
2419 ;; ----------------------------------------------------------------------
2421 (define_expand "ashlsi3"
2422   [(parallel [(set (match_operand:SI 0 "register_operand")
2423                    (ashift:SI
2424                     (match_operand:SI 1 "register_operand")
2425                     (match_operand:QI 2 "nonmemory_operand")))
2426               (clobber (reg:CC CC_REG))
2427              ])
2428   ]
2429   ""
2430   "")
2432 (define_insn "*am33_ashlsi3"
2433   [(set (match_operand:SI 0 "register_operand" "=dax,dx,!dax")
2434         (ashift:SI
2435          (match_operand:SI 1 "register_operand" "0,0,dax")
2436          (match_operand:QI 2 "nonmemory_operand" "J,dxi,dax")))
2437    (clobber (reg:CC CC_REG))
2438   ]
2439   "TARGET_AM33"
2440   "*
2441   {
2442     if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 1)
2443       return \"add %0,%0\";
2445     if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 2)
2446       return \"asl2 %0\";
2448     if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 3
2449         && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS)
2450       return \"asl2 %0\;add %0,%0\";
2452     if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 4
2453         && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS)
2454       return \"asl2 %0\;asl2 %0\";
2456     if (true_regnum (operands[1]) == true_regnum (operands[0]))
2457       return \"asl %S2,%0\";
2459     if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
2460         && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
2461         && true_regnum (operands[0]) != true_regnum (operands[2]))
2462       return \"mov %1,%0\;asl %S2,%0\";
2463     return \"asl %2,%1,%0\";
2464   }"
2465   [(set_attr "timings" "22")]
2468 (define_insn "*mn10300_ashlsi3"
2469   [(set (match_operand:SI 0 "register_operand" "=dax,dx,dx,dx,dx")
2470         (ashift:SI
2471          (match_operand:SI 1 "register_operand" "0,0,0,0,0")
2472          (match_operand:QI 2 "nonmemory_operand" "J,K,M,L,dxi")))
2473    (clobber (reg:CC CC_REG))
2474   ]
2475   ""
2476   "@
2477   add %0,%0
2478   asl2 %0
2479   asl2 %0\;add %0,%0
2480   asl2 %0\;asl2 %0
2481   asl %S2,%0"
2482   [(set_attr "timings" "11,11,22,22,11")]
2485 (define_expand "lshrsi3"
2486   [(parallel [(set (match_operand:SI 0 "register_operand")
2487                    (lshiftrt:SI
2488                     (match_operand:SI 1 "register_operand")
2489                     (match_operand:QI 2 "nonmemory_operand")))
2490               (clobber (reg:CC CC_REG))
2491              ])
2492   ]
2493   ""
2494   "")
2496 (define_insn "*am33_lshrsi3"
2497   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
2498         (lshiftrt:SI
2499          (match_operand:SI 1 "register_operand" "0,dax")
2500          (match_operand:QI 2 "nonmemory_operand" "dxi,dax")))
2501    (clobber (reg:CC CC_REG))
2502   ]
2503   "TARGET_AM33"
2504   "*
2505   {
2506     if (true_regnum (operands[1]) == true_regnum (operands[0]))
2507       return \"lsr %S2,%0\";
2509     if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
2510         && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
2511         && true_regnum (operands[0]) != true_regnum (operands[2]))
2512       return \"mov %1,%0\;lsr %S2,%0\";
2513     return \"lsr %2,%1,%0\";
2514   }"
2515   [(set_attr "timings" "22")]
2518 (define_insn "*mn10300_lshrsi3"
2519   [(set (match_operand:SI 0 "register_operand" "=dx")
2520         (lshiftrt:SI
2521          (match_operand:SI 1 "register_operand" "0")
2522          (match_operand:QI 2 "nonmemory_operand" "dxi")))
2523    (clobber (reg:CC CC_REG))
2524   ]
2525   ""
2526   "lsr %S2,%0"
2527   [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
2528                                        (const_int 11) (const_int 22)))]
2531 (define_expand "ashrsi3"
2532   [(parallel [(set (match_operand:SI 0 "register_operand")
2533                    (ashiftrt:SI
2534                     (match_operand:SI 1 "register_operand")
2535                     (match_operand:QI 2 "nonmemory_operand")))
2536               (clobber (reg:CC CC_REG))
2537              ])
2538   ]
2539   ""
2540   "")
2542 (define_insn "*am33_ashrisi3"
2543   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
2544         (ashiftrt:SI
2545          (match_operand:SI 1 "register_operand" "0,dax")
2546          (match_operand:QI 2 "nonmemory_operand" "dxi,dax")))
2547    (clobber (reg:CC CC_REG))
2548   ]
2549   "TARGET_AM33"
2550   "*
2551   {
2552     if (true_regnum (operands[1]) == true_regnum (operands[0]))
2553       return \"asr %S2,%0\";
2555     if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
2556         && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
2557         && true_regnum (operands[0]) != true_regnum (operands[2]))
2558       return \"mov %1,%0\;asr %S2,%0\";
2559     return \"asr %2,%1,%0\";
2560   }"
2561   [(set_attr "timings" "22")]
2564 (define_insn "*mn10300_ashrsi3"
2565   [(set (match_operand:SI 0 "register_operand" "=dx")
2566         (ashiftrt:SI
2567          (match_operand:SI 1 "register_operand" "0")
2568          (match_operand:QI 2 "nonmemory_operand" "dxi")))
2569    (clobber (reg:CC CC_REG))
2570   ]
2571   ""
2572   "asr %S2,%0"
2573   [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
2574                                        (const_int 11) (const_int 22)))]
2577 ;; ----------------------------------------------------------------------
2578 ;; FP INSTRUCTIONS
2579 ;; ----------------------------------------------------------------------
2581 ;; The mn103 series does not have floating point instructions, but since
2582 ;; FP values are held in integer regs, we can clear the high bit easily
2583 ;; which gives us an efficient inline floating point absolute value.
2585 ;; Similarly for negation of a FP value.
2588 (define_expand "absdf2"
2589   [(set (match_operand:DF         0 "register_operand")
2590         (abs:DF (match_operand:DF 1 "register_operand")))]
2591   ""
2592   "
2594   rtx target, result, insns;
2596   start_sequence ();
2597   target = operand_subword (operands[0], 1, 1, DFmode);
2598   result = expand_binop (SImode, and_optab,
2599                          operand_subword_force (operands[1], 1, DFmode),
2600                          GEN_INT (0x7fffffff), target, 0, OPTAB_WIDEN);
2602   gcc_assert (result);
2604   if (result != target)
2605     emit_move_insn (result, target);
2607   emit_move_insn (operand_subword (operands[0], 0, 1, DFmode),
2608                   operand_subword_force (operands[1], 0, DFmode));
2610   insns = get_insns ();
2611   end_sequence ();
2613   emit_insn (insns);
2614   DONE;
2617 (define_expand "abssf2"
2618   [(set (match_operand:SF         0 "register_operand")
2619         (abs:SF (match_operand:SF 1 "register_operand")))]
2620   ""
2621   "
2623   rtx result;
2624   rtx target;
2626   if (TARGET_AM33_2)
2627     {
2628       emit_insn (gen_abssf2_am33_2 (operands[0], operands[1]));
2629       DONE;
2630     }
2632   target = operand_subword_force (operands[0], 0, SFmode);
2633   result = expand_binop (SImode, and_optab,
2634                          operand_subword_force (operands[1], 0, SFmode),
2635                          GEN_INT (0x7fffffff), target, 0, OPTAB_WIDEN);
2636   gcc_assert (result);
2638   if (result != target)
2639     emit_move_insn (result, target);
2641   /* Make a place for REG_EQUAL.  */
2642   emit_move_insn (operands[0], operands[0]);
2643   DONE;
2647 (define_insn "abssf2_am33_2"
2648   [(set (match_operand:SF         0 "register_operand" "=f,f")
2649         (abs:SF (match_operand:SF 1 "register_operand" "0,?f")))]
2650   "TARGET_AM33_2"
2651   "@
2652    fabs %0
2653    fabs %1, %0"
2654   [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
2655                                        (const_int 17) (const_int 14)))]
2658 (define_expand "negdf2"
2659   [(set (match_operand:DF         0 "register_operand")
2660         (neg:DF (match_operand:DF 1 "register_operand")))]
2661   ""
2662   "
2664   rtx target, result, insns;
2666   start_sequence ();
2667   target = operand_subword (operands[0], 1, 1, DFmode);
2668   result = expand_binop (SImode, xor_optab,
2669                          operand_subword_force (operands[1], 1, DFmode),
2670                          GEN_INT (trunc_int_for_mode (0x80000000, SImode)),
2671                          target, 0, OPTAB_WIDEN);
2673   gcc_assert (result);
2675   if (result != target)
2676     emit_move_insn (result, target);
2678   emit_move_insn (operand_subword (operands[0], 0, 1, DFmode),
2679                   operand_subword_force (operands[1], 0, DFmode));
2681   insns = get_insns ();
2682   end_sequence ();
2684   emit_insn (insns);
2685   DONE;
2688 (define_expand "negsf2"
2689   [(set (match_operand:SF         0 "register_operand")
2690         (neg:SF (match_operand:SF 1 "register_operand")))]
2691   ""
2692   "
2694   rtx result;
2695   rtx target;
2697   if (TARGET_AM33_2)
2698     {
2699       emit_insn (gen_negsf2_am33_2 (operands[0], operands[1]));
2700       DONE;
2701     }
2703   target = operand_subword_force (operands[0], 0, SFmode);
2704   result = expand_binop (SImode, xor_optab,
2705                          operand_subword_force (operands[1], 0, SFmode),
2706                          GEN_INT (trunc_int_for_mode (0x80000000, SImode)),
2707                          target, 0, OPTAB_WIDEN);
2708   gcc_assert (result);
2710   if (result != target)
2711     emit_move_insn (result, target);
2713   /* Make a place for REG_EQUAL.  */
2714   emit_move_insn (operands[0], operands[0]);
2715   DONE;
2718 (define_insn "negsf2_am33_2"
2719   [(set (match_operand:SF         0 "register_operand" "=f,f")
2720         (neg:SF (match_operand:SF 1 "register_operand" "0,?f")))]
2721   "TARGET_AM33_2"
2722   "@
2723    fneg %0
2724    fneg %1, %0"
2725   [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
2726                                        (const_int 17) (const_int 14)))]
2729 (define_expand "sqrtsf2"
2730   [(parallel [(set (match_operand:SF          0 "register_operand" "")
2731                    (sqrt:SF (match_operand:SF 1 "register_operand" "")))
2732               (clobber (reg:CC_FLOAT CC_REG))
2733              ])
2734   ]
2735   "TARGET_AM33_2 && flag_unsafe_math_optimizations"
2736   "
2737   {
2738     rtx scratch = gen_reg_rtx (SFmode);
2739     emit_insn (gen_rsqrtsf2 (scratch, operands[1], CONST1_RTX (SFmode)));
2740     emit_insn (gen_divsf3 (operands[0], force_reg (SFmode, CONST1_RTX (SFmode)),
2741                            scratch));
2742     DONE;
2743   }")
2745 (define_insn "rsqrtsf2"
2746   [(set (match_operand:SF                  0 "register_operand" "=f,f")
2747         (div:SF (match_operand:SF          2 "const_1f_operand" "F,F")
2748                 (sqrt:SF (match_operand:SF 1 "register_operand" "0,?f"))))
2749    (clobber (reg:CC_FLOAT CC_REG))
2750   ]
2751   "TARGET_AM33_2"
2752   "@
2753    frsqrt %0
2754    frsqrt %1, %0"
2755   [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
2756                                        (const_int 4753) (const_int 2327)))]
2759 (define_expand "addsf3"
2760   [(parallel [(set (match_operand:SF          0 "register_operand")
2761                    (plus:SF (match_operand:SF 1 "register_operand")
2762                             (match_operand:SF 2 "nonmemory_operand")))
2763               (clobber (reg:CC_FLOAT CC_REG))])
2764   ]
2765   "TARGET_AM33_2"
2766   ""
2769 (define_insn "*addsf3_internal"
2770   [(set (match_operand:SF          0 "register_operand" "=f,f")
2771         (plus:SF (match_operand:SF 1 "register_operand" "%0,f")
2772                  (match_operand:SF 2 "nonmemory_operand" "f,?fF")))
2773    (clobber (reg:CC_FLOAT CC_REG))
2774   ]
2775   "TARGET_AM33_2"
2776   "@
2777    fadd %2, %0
2778    fadd %2, %1, %0"
2779   [(set_attr_alternative "timings"
2780                          [(if_then_else (eq_attr "cpu" "am34")
2781                                         (const_int 17) (const_int 14))
2782                           (if_then_else (eq_attr "cpu" "am34")
2783                                         (const_int 17) (const_int 25))
2784                          ])
2785   ]
2788 (define_expand "subsf3"
2789   [(parallel [(set (match_operand:SF           0 "register_operand")
2790                    (minus:SF (match_operand:SF 1 "register_operand")
2791                              (match_operand:SF 2 "nonmemory_operand")))
2792               (clobber (reg:CC_FLOAT CC_REG))])
2793   ]
2794   "TARGET_AM33_2"
2795   ""
2798 (define_insn "*subsf3_internal"
2799   [(set (match_operand:SF           0 "register_operand" "=f,f")
2800         (minus:SF (match_operand:SF 1 "register_operand" "0,f")
2801                   (match_operand:SF 2 "nonmemory_operand" "f,?fF")))
2802    (clobber (reg:CC_FLOAT CC_REG))
2803   ]
2804   "TARGET_AM33_2"
2805   "@
2806    fsub %2, %0
2807    fsub %2, %1, %0"
2808   [(set_attr_alternative "timings"
2809                          [(if_then_else (eq_attr "cpu" "am34")
2810                                         (const_int 17) (const_int 14))
2811                           (if_then_else (eq_attr "cpu" "am34")
2812                                         (const_int 17) (const_int 25))
2813                          ])
2814   ]
2817 (define_expand "mulsf3"
2818   [(parallel [(set (match_operand:SF          0 "register_operand")
2819                    (mult:SF (match_operand:SF 1 "register_operand")
2820                             (match_operand:SF 2 "nonmemory_operand")))
2821               (clobber (reg:CC_FLOAT CC_REG))])
2822   ]
2823   "TARGET_AM33_2"
2824   ""
2827 (define_insn "*mulsf3_internal"
2828   [(set (match_operand:SF          0 "register_operand" "=f,f")
2829         (mult:SF (match_operand:SF 1 "register_operand" "%0,f")
2830                  (match_operand:SF 2 "nonmemory_operand" "f,?fF")))
2831   (clobber (reg:CC_FLOAT CC_REG))
2832   ]
2833   "TARGET_AM33_2"
2834   "@
2835    fmul %2, %0
2836    fmul %2, %1, %0"
2837   [(set_attr_alternative "timings"
2838                          [(if_then_else (eq_attr "cpu" "am34")
2839                                         (const_int 17) (const_int 14))
2840                           (if_then_else (eq_attr "cpu" "am34")
2841                                         (const_int 17) (const_int 25))
2842                          ])
2843   ]
2846 (define_insn "divsf3"
2847   [(set (match_operand:SF         0 "register_operand" "=f,f")
2848         (div:SF (match_operand:SF 1 "register_operand"  "0,f")
2849                 (match_operand:SF 2 "nonmemory_operand" "f,?fF")))
2850    (clobber (reg:CC_FLOAT CC_REG))
2851   ]
2852   "TARGET_AM33_2"
2853   "@
2854    fdiv %2, %0
2855    fdiv %2, %1, %0"
2856   [(set_attr_alternative "timings"
2857                          [(if_then_else (eq_attr "cpu" "am34")
2858                                         (const_int 2531) (const_int 1216))
2859                           (if_then_else (eq_attr "cpu" "am34")
2860                                         (const_int 2531) (const_int 1317))
2861                          ])
2862   ]
2865 (define_insn "fmasf4"
2866   [(set (match_operand:SF         0 "register_operand" "=A")
2867         (fma:SF (match_operand:SF 1 "register_operand" "f")
2868                 (match_operand:SF 2 "register_operand" "f")
2869                 (match_operand:SF 3 "register_operand" "f")))
2870    (clobber (reg:CC_FLOAT CC_REG))
2871   ]
2872   "TARGET_AM33_2"
2873   "fmadd %1, %2, %3, %0"
2874   [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
2875                                        (const_int 17) (const_int 24)))]
2878 (define_insn "fmssf4"
2879   [(set (match_operand:SF                 0 "register_operand" "=A")
2880         (fma:SF (match_operand:SF         1 "register_operand" "f")
2881                 (match_operand:SF         2 "register_operand" "f")
2882                 (neg:SF (match_operand:SF 3 "register_operand" "f"))))
2883    (clobber (reg:CC_FLOAT CC_REG))
2884   ]
2885   "TARGET_AM33_2"
2886   "fmsub %1, %2, %3, %0"
2887   [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
2888                                        (const_int 17) (const_int 24)))]
2891 (define_insn "fnmasf4"
2892   [(set (match_operand:SF                 0 "register_operand" "=A")
2893         (fma:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
2894                 (match_operand:SF         2 "register_operand" "f")
2895                 (match_operand:SF         3 "register_operand" "f")))
2896    (clobber (reg:CC_FLOAT CC_REG))
2897   ]
2898   "TARGET_AM33_2"
2899   "fnmadd %1, %2, %3, %0"
2900   [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
2901                                        (const_int 17) (const_int 24)))]
2904 (define_insn "fnmssf4"
2905   [(set (match_operand:SF                 0 "register_operand" "=A")
2906         (fma:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
2907                 (match_operand:SF         2 "register_operand" "f")
2908                 (neg:SF (match_operand:SF 3 "register_operand" "f"))))
2909    (clobber (reg:CC_FLOAT CC_REG))
2910   ]
2911   "TARGET_AM33_2"
2912   "fnmsub %1, %2, %3, %0"
2913   [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
2914                                        (const_int 17) (const_int 24)))]
2917 ;; ----------------------------------------------------------------------
2918 ;; PROLOGUE/EPILOGUE
2919 ;; ----------------------------------------------------------------------
2920 (define_expand "prologue"
2921   [(const_int 0)]
2922   ""
2923   "mn10300_expand_prologue (); DONE;")
2925 (define_expand "epilogue"
2926   [(return)]
2927   ""
2928   "
2929   {
2930     mn10300_expand_epilogue ();
2931     DONE;
2932   }")
2934 (define_insn "return_internal"
2935   [(const_int 2)
2936    (return)]
2937   ""
2938   "rets"
2939   [(set_attr "timings" "66")]
2942 ;; This insn restores the callee saved registers and does a return, it
2943 ;; can also deallocate stack space.
2944 (define_insn "return_internal_regs"
2945   [(const_int 0)
2946    (match_operand:SI 0  "const_int_operand" "i")
2947    (return)]
2948   ""
2949   "*
2950   {
2951     fputs (\"\\tret \", asm_out_file);
2952     mn10300_print_reg_list (asm_out_file, mn10300_get_live_callee_saved_regs ());
2953     fprintf (asm_out_file, \",%d\\n\", (int) INTVAL (operands[0]));
2954     return \"\";
2955   }"
2956   ;; Assumes that there will be no more than 8 regs to pop
2957   [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
2958                                        (const_int 1414) (const_int 1313)))]
2961 ;; This instruction matches one generated by mn10300_gen_multiple_store()
2962 (define_insn "store_movm"
2963   [(match_parallel 0 "mn10300_store_multiple_operation"
2964     [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_operand 1 "" "")))])]
2965   ""
2966   "*
2967   {
2968     fputs (\"\\tmovm \", asm_out_file);
2969     mn10300_print_reg_list (asm_out_file,
2970                             mn10300_store_multiple_operation (operands[0],
2971                                                               VOIDmode));
2972     fprintf (asm_out_file, \",(sp)\\n\");
2973     return \"\";
2974   }"
2975   ;; Assume that no more than 8 registers will be pushed.
2976   [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
2977                                        (const_int 99) (const_int 88)))]
2980 (define_insn "return"
2981   [(return)]
2982   "mn10300_can_use_return_insn ()"
2983   "*
2985   rtx next = next_active_insn (insn);
2987   if (next
2988       && JUMP_P (next)
2989       && GET_CODE (PATTERN (next)) == RETURN)
2990     return \"\";
2991   else
2992     return \"rets\";
2994   [(set_attr "timings" "66")]
2997 ;; Try to combine consecutive updates of the stack pointer (or any
2998 ;; other register for that matter).
2999 (define_peephole
3000   [(parallel [(set (match_operand:SI 0 "register_operand" "=dxay")
3001                    (plus:SI (match_dup 0)
3002                             (match_operand 1 "const_int_operand" "")))
3003               (clobber (reg:CC CC_REG))
3004              ])
3005    (parallel [(set (match_dup 0)
3006                    (plus:SI (match_dup 0)
3007                             (match_operand 2 "const_int_operand" "")))
3008               (clobber (reg:CC CC_REG))
3009              ])
3010   ]
3011   ""
3012   "*
3014   operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]));
3015   return \"add %1,%0\";
3019 (define_expand "int_label"
3020   [(unspec [(match_operand:SI 0 "" "")] UNSPEC_INT_LABEL)]
3021   "" "")
3023 (define_expand "GOTaddr2picreg"
3024   [(match_dup 0)]
3025   "" "
3027   /* It would be nice to be able to have int_label keep track of the
3028      counter and all, but if we add C code to it, we'll get an insn
3029      back, and we just want the pattern.  */
3030   operands[0] = gen_int_label (GEN_INT (mn10300_unspec_int_label_counter++));
3031   if (TARGET_AM33)
3032     emit_insn (gen_am33_loadPC (operands[0]));
3033   else
3034     emit_insn (gen_mn10300_loadPC (operands[0]));
3035   emit_insn (gen_add_GOT_to_pic_reg (copy_rtx (operands[0])));
3036   DONE;
3040 (define_insn "am33_loadPC"
3041   [(parallel
3042     [(set (reg:SI PIC_REG) (pc))
3043      (use (match_operand 0 "" ""))])]
3044   "TARGET_AM33"
3045   "%0:\;mov pc,a2"
3048 (define_insn_and_split "mn10300_loadPC"
3049   [(parallel
3050     [(set (reg:SI PIC_REG) (pc))
3051      (use (match_operand 0 "" ""))])]
3052   "! TARGET_AM33"
3053   "#"
3054   "&& reload_completed"
3055   [(match_operand 0 "" "")]
3056   {
3057     rtx sp_reg = gen_rtx_REG (SImode, SP_REG);
3058     int need_stack_space = (get_frame_size () == 0
3059                             && crtl->outgoing_args_size == 0);
3061     if (need_stack_space)
3062       emit_insn (gen_addsi3 (sp_reg, sp_reg, GEN_INT (-4)));
3064     emit_insn (gen_call_next_insn (operands[0]));
3066     if (need_stack_space)
3067       emit_insn (gen_pop_pic_reg ());
3068     else
3069       emit_move_insn (pic_offset_table_rtx, gen_rtx_MEM (SImode, sp_reg));
3070     DONE;
3071   }
3074 (define_insn "call_next_insn"
3075   [(parallel
3076     [(set (mem:SI (reg:SI SP_REG)) (pc))
3077      (use (match_operand 0 "" ""))])]
3078   "reload_completed"
3079   "calls %0\;%0:"
3080   [(set_attr "timings" "44")]
3083 (define_expand "add_GOT_to_pic_reg"
3084   [(parallel [(set (reg:SI PIC_REG)
3085                    (plus:SI
3086                     (reg:SI PIC_REG)
3087                     (const:SI
3088                      (unspec:SI [(minus:SI
3089                                (match_dup 1)
3090                                (const (minus:SI
3091                                        (const (match_operand:SI 0 "" ""))
3092                                        (pc))))
3093                               ] UNSPEC_PIC))))
3094               (clobber (reg:CC CC_REG))
3095               ])
3096   ]
3097   ""
3098   "operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);"
3101 (define_expand "add_GOT_to_any_reg"
3102   [(parallel [(set (match_operand:SI 0 "" "")
3103                    (plus:SI
3104                     (match_operand:SI 1 "" "")
3105                     (const
3106                      (unspec [(minus:SI
3107                                (match_dup 3)
3108                                (const (minus:SI
3109                                        (const (match_operand:SI 2 "" ""))
3110                                        (pc))))
3111                               ] UNSPEC_PIC))))
3112               (clobber (reg:CC CC_REG))
3113              ])
3114   ]
3115   ""
3116   "operands[3] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);"