OSDN Git Service

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