]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/mn10300/mn10300.md
mn10300: Emit clr.
[thirdparty/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
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 )