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