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