]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/mn10300/mn10300.md
mn10300-protos.h: New file.
[thirdparty/gcc.git] / gcc / config / mn10300 / mn10300.md
1 ;; GCC machine description for Matsushita MN10300
2 ;; Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
3 ;; Contributed by Jeff Law (law@cygnus.com).
4
5 ;; This file is part of GNU CC.
6
7 ;; GNU CC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 2, or (at your option)
10 ;; any later version.
11
12 ;; GNU CC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ;; GNU General Public License for more details.
16
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GNU CC; see the file COPYING. If not, write to
19 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
20 ;; Boston, MA 02111-1307, USA.
21
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
24
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
26
27 ;; Condition code settings.
28 ;; none - insn does not affect cc
29 ;; none_0hit - insn does not affect cc but it does modify operand 0
30 ;; This attribute is used to keep track of when operand 0 changes.
31 ;; See the description of NOTICE_UPDATE_CC for more info.
32 ;; set_znv - insn sets z,n,v to usable values; c is unusable.
33 ;; set_zn - insn sets z,n to usable values; v,c are unusable.
34 ;; compare - compare instruction
35 ;; invert -- like compare, but flags are inverted.
36 ;; clobber - value of cc is unknown
37 (define_attr "cc" "none,none_0hit,set_znv,set_zn,compare,clobber,invert"
38 (const_string "clobber"))
39 \f
40 ;; ----------------------------------------------------------------------
41 ;; MOVE INSTRUCTIONS
42 ;; ----------------------------------------------------------------------
43
44 ;; movqi
45
46 (define_expand "movqi"
47 [(set (match_operand:QI 0 "general_operand" "")
48 (match_operand:QI 1 "general_operand" ""))]
49 ""
50 "
51 {
52 /* One of the ops has to be in a register */
53 if (!register_operand (operand0, QImode)
54 && !register_operand (operand1, QImode))
55 operands[1] = copy_to_mode_reg (QImode, operand1);
56 }")
57
58 (define_insn ""
59 [(set (match_operand:QI 0 "general_operand" "=dx,a,dx,a,dx,a,dx,a,dxa,m")
60 (match_operand:QI 1 "general_operand" "0,0,I,I,a,dx,dxi,ia,m,dxa"))]
61 "TARGET_AM33
62 && (register_operand (operands[0], QImode)
63 || register_operand (operands[1], QImode))"
64 "*
65 {
66 switch (which_alternative)
67 {
68 case 0:
69 case 1:
70 return \"nop\";
71 case 2:
72 return \"clr %0\";
73 case 3:
74 case 4:
75 case 5:
76 case 6:
77 case 7:
78 if (GET_CODE (operands[1]) == CONST_DOUBLE)
79 {
80 rtx xoperands[2];
81 xoperands[0] = operands[0];
82 xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
83 output_asm_insn (\"mov %1,%0\", xoperands);
84 return \"\";
85 }
86
87 if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
88 && GET_CODE (operands[1]) == CONST_INT)
89 {
90 HOST_WIDE_INT val = INTVAL (operands[1]);
91
92 if (((val & 0x80) && ! (val & 0xffffff00))
93 || ((val & 0x800000) && ! (val & 0xff000000)))
94 return \"movu %1,%0\";
95 }
96 return \"mov %1,%0\";
97 case 8:
98 case 9:
99 return \"movbu %1,%0\";
100 default:
101 abort();
102 }
103 }"
104 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
105
106 (define_insn ""
107 [(set (match_operand:QI 0 "general_operand" "=dx,*a,dx,*a,dx,*a,dx,*a,dx,m")
108 (match_operand:QI 1 "general_operand" "0,0,I,I,a,dx,dxi,ia,m,dx"))]
109 "register_operand (operands[0], QImode)
110 || register_operand (operands[1], QImode)"
111 "*
112 {
113 switch (which_alternative)
114 {
115 case 0:
116 case 1:
117 return \"nop\";
118 case 2:
119 return \"clr %0\";
120 case 3:
121 case 4:
122 case 5:
123 case 6:
124 case 7:
125 if (GET_CODE (operands[1]) == CONST_DOUBLE)
126 {
127 rtx xoperands[2];
128 xoperands[0] = operands[0];
129 xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
130 output_asm_insn (\"mov %1,%0\", xoperands);
131 return \"\";
132 }
133
134 return \"mov %1,%0\";
135 case 8:
136 case 9:
137 return \"movbu %1,%0\";
138 default:
139 abort();
140 }
141 }"
142 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
143
144 ;; movhi
145
146 (define_expand "movhi"
147 [(set (match_operand:HI 0 "general_operand" "")
148 (match_operand:HI 1 "general_operand" ""))]
149 ""
150 "
151 {
152 /* One of the ops has to be in a register */
153 if (!register_operand (operand1, HImode)
154 && !register_operand (operand0, HImode))
155 operands[1] = copy_to_mode_reg (HImode, operand1);
156 }")
157
158 (define_insn ""
159 [(set (match_operand:HI 0 "general_operand" "=dx,a,dx,a,dx,a,dx,a,dxa,m")
160 (match_operand:HI 1 "general_operand" "0,0,I,I,a,dx,dxi,ia,m,dxa"))]
161 "TARGET_AM33
162 && (register_operand (operands[0], HImode)
163 || register_operand (operands[1], HImode))"
164 "*
165 {
166 switch (which_alternative)
167 {
168 case 0:
169 case 1:
170 return \"nop\";
171 case 2:
172 return \"clr %0\";
173 case 3:
174 case 4:
175 case 5:
176 case 6:
177 case 7:
178 if (GET_CODE (operands[1]) == CONST_DOUBLE)
179 {
180 rtx xoperands[2];
181 xoperands[0] = operands[0];
182 xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
183 output_asm_insn (\"mov %1,%0\", xoperands);
184 return \"\";
185 }
186
187 if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
188 && GET_CODE (operands[1]) == CONST_INT)
189 {
190 HOST_WIDE_INT val = INTVAL (operands[1]);
191
192 if (((val & 0x80) && ! (val & 0xffffff00))
193 || ((val & 0x800000) && ! (val & 0xff000000)))
194 return \"movu %1,%0\";
195 }
196 return \"mov %1,%0\";
197 case 8:
198 case 9:
199 return \"movhu %1,%0\";
200 default:
201 abort();
202 }
203 }"
204 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
205
206 (define_insn ""
207 [(set (match_operand:HI 0 "general_operand" "=dx,*a,dx,*a,dx,*a,dx,*a,dx,m")
208 (match_operand:HI 1 "general_operand" "0,0,I,I,a,dx,dxi,ia,m,dx"))]
209 "register_operand (operands[0], HImode)
210 || register_operand (operands[1], HImode)"
211 "*
212 {
213 switch (which_alternative)
214 {
215 case 0:
216 case 1:
217 return \"nop\";
218 case 2:
219 return \"clr %0\";
220 case 3:
221 case 4:
222 case 5:
223 case 6:
224 case 7:
225 if (GET_CODE (operands[1]) == CONST_DOUBLE)
226 {
227 rtx xoperands[2];
228 xoperands[0] = operands[0];
229 xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
230 output_asm_insn (\"mov %1,%0\", xoperands);
231 return \"\";
232 }
233 return \"mov %1,%0\";
234 case 8:
235 case 9:
236 return \"movhu %1,%0\";
237 default:
238 abort();
239 }
240 }"
241 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
242
243 ;; movsi and helpers
244
245 ;; We use this to handle addition of two values when one operand is the
246 ;; stack pointer and the other is a memory reference of some kind. Reload
247 ;; does not handle them correctly without this expander.
248 (define_expand "reload_insi"
249 [(set (match_operand:SI 0 "register_operand" "=a")
250 (match_operand:SI 1 "impossible_plus_operand" ""))
251 (clobber (match_operand:SI 2 "register_operand" "=&r"))]
252 ""
253 "
254 {
255 if (XEXP (operands[1], 0) == stack_pointer_rtx)
256 {
257 if (GET_CODE (XEXP (operands[1], 1)) == SUBREG
258 && (GET_MODE_SIZE (GET_MODE (XEXP (operands[1], 1)))
259 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (operands[1], 1))))))
260 emit_move_insn (operands[2],
261 gen_rtx_ZERO_EXTEND
262 (GET_MODE (XEXP (operands[1], 1)),
263 SUBREG_REG (XEXP (operands[1], 1))));
264 else
265 emit_move_insn (operands[2], XEXP (operands[1], 1));
266 emit_move_insn (operands[0], XEXP (operands[1], 0));
267 }
268 else
269 {
270 if (GET_CODE (XEXP (operands[1], 0)) == SUBREG
271 && (GET_MODE_SIZE (GET_MODE (XEXP (operands[1], 0)))
272 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (operands[1], 0))))))
273 emit_move_insn (operands[2],
274 gen_rtx_ZERO_EXTEND
275 (GET_MODE (XEXP (operands[1], 0)),
276 SUBREG_REG (XEXP (operands[1], 0))));
277 else
278 emit_move_insn (operands[2], XEXP (operands[1], 0));
279 emit_move_insn (operands[0], XEXP (operands[1], 1));
280 }
281 emit_insn (gen_addsi3 (operands[0], operands[0], operands[2]));
282 DONE;
283 }")
284
285 (define_expand "movsi"
286 [(set (match_operand:SI 0 "general_operand" "")
287 (match_operand:SI 1 "general_operand" ""))]
288 ""
289 "
290 {
291 /* One of the ops has to be in a register */
292 if (!register_operand (operand1, SImode)
293 && !register_operand (operand0, SImode))
294 operands[1] = copy_to_mode_reg (SImode, operand1);
295 }")
296
297 (define_insn ""
298 [(set (match_operand:SI 0 "general_operand"
299 "=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax,axR,y")
300 (match_operand:SI 1 "general_operand"
301 "0,0,I,I,dx,ax,dx,ax,dixm,aixm,dixm,aixm,xy,axR"))]
302 "register_operand (operands[0], SImode)
303 || register_operand (operands[1], SImode)"
304 "*
305 {
306 switch (which_alternative)
307 {
308 case 0:
309 case 1:
310 return \"nop\";
311 case 2:
312 return \"clr %0\";
313 case 3:
314 case 4:
315 case 5:
316 case 6:
317 case 7:
318 case 8:
319 case 9:
320 case 10:
321 case 11:
322 case 12:
323 case 13:
324 if (GET_CODE (operands[1]) == CONST_DOUBLE)
325 {
326 rtx xoperands[2];
327 xoperands[0] = operands[0];
328 xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
329 output_asm_insn (\"mov %1,%0\", xoperands);
330 return \"\";
331 }
332
333 if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
334 && GET_CODE (operands[1]) == CONST_INT)
335 {
336 HOST_WIDE_INT val = INTVAL (operands[1]);
337
338 if (((val & 0x80) && ! (val & 0xffffff00))
339 || ((val & 0x800000) && ! (val & 0xff000000)))
340 return \"movu %1,%0\";
341 }
342 return \"mov %1,%0\";
343 default:
344 abort();
345 }
346 }"
347 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
348
349 (define_expand "movsf"
350 [(set (match_operand:SF 0 "general_operand" "")
351 (match_operand:SF 1 "general_operand" ""))]
352 ""
353 "
354 {
355 /* One of the ops has to be in a register */
356 if (!register_operand (operand1, SFmode)
357 && !register_operand (operand0, SFmode))
358 operands[1] = copy_to_mode_reg (SFmode, operand1);
359 }")
360
361 (define_insn ""
362 [(set (match_operand:SF 0 "general_operand" "=dx,ax,dx,a,daxm,dax")
363 (match_operand:SF 1 "general_operand" "0,0,G,G,dax,daxim"))]
364 "register_operand (operands[0], SFmode)
365 || register_operand (operands[1], SFmode)"
366 "*
367 {
368 switch (which_alternative)
369 {
370 case 0:
371 case 1:
372 return \"nop\";
373 case 2:
374 return \"clr %0\";
375 case 3:
376 case 4:
377 case 5:
378 if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
379 && GET_CODE (operands[1]) == CONST_INT)
380 {
381 HOST_WIDE_INT val = INTVAL (operands[1]);
382
383 if (((val & 0x80) && ! (val & 0xffffff00))
384 || ((val & 0x800000) && ! (val & 0xff000000)))
385 return \"movu %1,%0\";
386 }
387 return \"mov %1,%0\";
388 default:
389 abort();
390 }
391 }"
392 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit")])
393
394 (define_expand "movdi"
395 [(set (match_operand:DI 0 "general_operand" "")
396 (match_operand:DI 1 "general_operand" ""))]
397 ""
398 "
399 {
400 /* One of the ops has to be in a register */
401 if (!register_operand (operand1, DImode)
402 && !register_operand (operand0, DImode))
403 operands[1] = copy_to_mode_reg (DImode, operand1);
404 }")
405
406 (define_insn ""
407 [(set (match_operand:DI 0 "general_operand"
408 "=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax")
409 (match_operand:DI 1 "general_operand"
410 "0,0,I,I,dx,ax,dx,ax,dxim,axim,dxim,axim"))]
411 "register_operand (operands[0], DImode)
412 || register_operand (operands[1], DImode)"
413 "*
414 {
415 long val[2];
416 REAL_VALUE_TYPE rv;
417
418 switch (which_alternative)
419 {
420 case 0:
421 case 1:
422 return \"nop\";
423
424 case 2:
425 return \"clr %L0\;clr %H0\";
426
427 case 3:
428 if (rtx_equal_p (operands[0], operands[1]))
429 return \"sub %L1,%L0\;mov %L0,%H0\";
430 else
431 return \"mov %1,%L0\;mov %L0,%H0\";
432 case 4:
433 case 5:
434 case 6:
435 case 7:
436 case 8:
437 case 9:
438 case 10:
439 case 11:
440 if (GET_CODE (operands[1]) == CONST_INT)
441 {
442 val[0] = INTVAL (operands[1]);
443 val[1] = val[0] < 0 ? -1 : 0;
444 }
445 if (GET_CODE (operands[1]) == CONST_DOUBLE)
446 {
447 if (GET_MODE (operands[1]) == DFmode)
448 {
449 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
450 REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
451 }
452 else if (GET_MODE (operands[1]) == VOIDmode
453 || GET_MODE (operands[1]) == DImode)
454 {
455 val[0] = CONST_DOUBLE_LOW (operands[1]);
456 val[1] = CONST_DOUBLE_HIGH (operands[1]);
457 }
458 }
459
460 if (GET_CODE (operands[1]) == MEM
461 && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
462 {
463 rtx temp = operands[0];
464
465 while (GET_CODE (temp) == SUBREG)
466 temp = SUBREG_REG (temp);
467
468 if (GET_CODE (temp) != REG)
469 abort ();
470
471 if (reg_overlap_mentioned_p (gen_rtx_REG (SImode, REGNO (temp)),
472 XEXP (operands[1], 0)))
473 return \"mov %H1,%H0\;mov %L1,%L0\";
474 else
475 return \"mov %L1,%L0\;mov %H1,%H0\";
476
477 }
478 else if (GET_CODE (operands[1]) == MEM
479 && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
480 && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
481 {
482 rtx xoperands[2];
483
484 xoperands[0] = operands[0];
485 xoperands[1] = XEXP (operands[1], 0);
486
487 output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\",
488 xoperands);
489 return \"\";
490 }
491 else
492 {
493 if ((GET_CODE (operands[1]) == CONST_INT
494 || GET_CODE (operands[1]) == CONST_DOUBLE)
495 && val[0] == 0)
496 {
497 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
498 output_asm_insn (\"clr %L0\", operands);
499 else
500 output_asm_insn (\"mov %L1,%L0\", operands);
501 }
502 else if ((REGNO_REG_CLASS (true_regnum (operands[0]))
503 == EXTENDED_REGS)
504 && (((val[0] & 0x80) && ! (val[0] & 0xffffff00))
505 || ((val[0] & 0x800000) && ! (val[0] & 0xff000000))))
506 output_asm_insn (\"movu %1,%0\", operands);
507 else
508 output_asm_insn (\"mov %L1,%L0\", operands);
509
510 if ((GET_CODE (operands[1]) == CONST_INT
511 || GET_CODE (operands[1]) == CONST_DOUBLE)
512 && val[1] == 0)
513 {
514 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
515 output_asm_insn (\"clr %H0\", operands);
516 else
517 output_asm_insn (\"mov %H1,%H0\", operands);
518 }
519 else if ((GET_CODE (operands[1]) == CONST_INT
520 || GET_CODE (operands[1]) == CONST_DOUBLE)
521 && val[0] == val[1])
522 output_asm_insn (\"mov %L0,%H0\", operands);
523 else if ((REGNO_REG_CLASS (true_regnum (operands[0]))
524 == EXTENDED_REGS)
525 && (((val[1] & 0x80) && ! (val[1] & 0xffffff00))
526 || ((val[1] & 0x800000) && ! (val[1] & 0xff000000))))
527 output_asm_insn (\"movu %1,%0\", operands);
528 else
529 output_asm_insn (\"mov %H1,%H0\", operands);
530 return \"\";
531 }
532 default:
533 abort();
534 }
535 }"
536 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
537
538 (define_expand "movdf"
539 [(set (match_operand:DF 0 "general_operand" "")
540 (match_operand:DF 1 "general_operand" ""))]
541 ""
542 "
543 {
544 /* One of the ops has to be in a register */
545 if (!register_operand (operand1, DFmode)
546 && !register_operand (operand0, DFmode))
547 operands[1] = copy_to_mode_reg (DFmode, operand1);
548 }")
549
550 (define_insn ""
551 [(set (match_operand:DF 0 "general_operand"
552 "=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax")
553 (match_operand:DF 1 "general_operand"
554 "0,0,G,G,dx,ax,dx,ax,dxim,axim,dxim,axim"))]
555 "register_operand (operands[0], DFmode)
556 || register_operand (operands[1], DFmode)"
557 "*
558 {
559 long val[2];
560 REAL_VALUE_TYPE rv;
561
562 switch (which_alternative)
563 {
564 case 0:
565 case 1:
566 return \"nop\";
567
568 case 2:
569 return \"clr %L0\;clr %H0\";
570
571 case 3:
572 if (rtx_equal_p (operands[0], operands[1]))
573 return \"sub %L1,%L0\;mov %L0,%H0\";
574 else
575 return \"mov %1,%L0\;mov %L0,%H0\";
576 case 4:
577 case 5:
578 case 6:
579 case 7:
580 case 8:
581 case 9:
582 case 10:
583 case 11:
584 if (GET_CODE (operands[1]) == CONST_INT)
585 {
586 val[0] = INTVAL (operands[1]);
587 val[1] = val[0] < 0 ? -1 : 0;
588 }
589 if (GET_CODE (operands[1]) == CONST_DOUBLE)
590 {
591 if (GET_MODE (operands[1]) == DFmode)
592 {
593 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
594 REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
595 }
596 else if (GET_MODE (operands[1]) == VOIDmode
597 || GET_MODE (operands[1]) == DImode)
598 {
599 val[0] = CONST_DOUBLE_LOW (operands[1]);
600 val[1] = CONST_DOUBLE_HIGH (operands[1]);
601 }
602 }
603
604 if (GET_CODE (operands[1]) == MEM
605 && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
606 {
607 rtx temp = operands[0];
608
609 while (GET_CODE (temp) == SUBREG)
610 temp = SUBREG_REG (temp);
611
612 if (GET_CODE (temp) != REG)
613 abort ();
614
615 if (reg_overlap_mentioned_p (gen_rtx_REG (SImode, REGNO (temp)),
616 XEXP (operands[1], 0)))
617 return \"mov %H1,%H0\;mov %L1,%L0\";
618 else
619 return \"mov %L1,%L0\;mov %H1,%H0\";
620
621 }
622 else if (GET_CODE (operands[1]) == MEM
623 && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
624 && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
625 {
626 rtx xoperands[2];
627
628 xoperands[0] = operands[0];
629 xoperands[1] = XEXP (operands[1], 0);
630
631 output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\",
632 xoperands);
633 return \"\";
634 }
635 else
636 {
637 if ((GET_CODE (operands[1]) == CONST_INT
638 || GET_CODE (operands[1]) == CONST_DOUBLE)
639 && val[0] == 0)
640 {
641 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
642 output_asm_insn (\"clr %L0\", operands);
643 else
644 output_asm_insn (\"mov %L1,%L0\", operands);
645 }
646 else if ((REGNO_REG_CLASS (true_regnum (operands[0]))
647 == EXTENDED_REGS)
648 && (((val[0] & 0x80) && ! (val[0] & 0xffffff00))
649 || ((val[0] & 0x800000) && ! (val[0] & 0xff000000))))
650 output_asm_insn (\"movu %1,%0\", operands);
651 else
652 output_asm_insn (\"mov %L1,%L0\", operands);
653
654 if ((GET_CODE (operands[1]) == CONST_INT
655 || GET_CODE (operands[1]) == CONST_DOUBLE)
656 && val[1] == 0)
657 {
658 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
659 output_asm_insn (\"clr %H0\", operands);
660 else
661 output_asm_insn (\"mov %H1,%H0\", operands);
662 }
663 else if ((GET_CODE (operands[1]) == CONST_INT
664 || GET_CODE (operands[1]) == CONST_DOUBLE)
665 && val[0] == val[1])
666 output_asm_insn (\"mov %L0,%H0\", operands);
667 else if ((REGNO_REG_CLASS (true_regnum (operands[0]))
668 == EXTENDED_REGS)
669 && (((val[1] & 0x80) && ! (val[1] & 0xffffff00))
670 || ((val[1] & 0x800000) && ! (val[1] & 0xff000000))))
671 output_asm_insn (\"movu %1,%0\", operands);
672 else
673 output_asm_insn (\"mov %H1,%H0\", operands);
674 return \"\";
675 }
676 default:
677 abort();
678 }
679 }"
680 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
681
682
683 \f
684 ;; ----------------------------------------------------------------------
685 ;; TEST INSTRUCTIONS
686 ;; ----------------------------------------------------------------------
687
688 ;; Go ahead and define tstsi so we can eliminate redundant tst insns
689 ;; when we start trying to optimize this port.
690 (define_insn "tstsi"
691 [(set (cc0) (match_operand:SI 0 "register_operand" "dax"))]
692 ""
693 "* return output_tst (operands[0], insn);"
694 [(set_attr "cc" "set_znv")])
695
696 (define_insn ""
697 [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "dx,!a")))]
698 "TARGET_AM33"
699 "* return output_tst (operands[0], insn);"
700 [(set_attr "cc" "set_znv")])
701
702 (define_insn ""
703 [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "dx")))]
704 ""
705 "* return output_tst (operands[0], insn);"
706 [(set_attr "cc" "set_znv")])
707
708 (define_insn ""
709 [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "dx,!a")))]
710 "TARGET_AM33"
711 "* return output_tst (operands[0], insn);"
712 [(set_attr "cc" "set_znv")])
713
714 (define_insn ""
715 [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "dx")))]
716 ""
717 "* return output_tst (operands[0], insn);"
718 [(set_attr "cc" "set_znv")])
719
720 (define_insn "cmpsi"
721 [(set (cc0)
722 (compare (match_operand:SI 0 "register_operand" "!*d*a*x,dax")
723 (match_operand:SI 1 "nonmemory_operand" "!*0,daxi")))]
724 ""
725 "@
726 add 0,%0
727 cmp %1,%0"
728 [(set_attr "cc" "invert,compare")])
729 \f
730 ;; ----------------------------------------------------------------------
731 ;; ADD INSTRUCTIONS
732 ;; ----------------------------------------------------------------------
733
734 (define_expand "addsi3"
735 [(set (match_operand:SI 0 "register_operand" "")
736 (plus:SI (match_operand:SI 1 "register_operand" "")
737 (match_operand:SI 2 "nonmemory_operand" "")))]
738 ""
739 "
740 {
741 /* We can't add a variable amount directly to the stack pointer;
742 so do so via a temporary register. */
743 if (operands[0] == stack_pointer_rtx
744 && GET_CODE (operands[1]) != CONST_INT
745 && GET_CODE (operands[2]) != CONST_INT)
746 {
747 rtx temp = gen_reg_rtx (SImode);
748 emit_move_insn (temp, gen_rtx_PLUS (SImode, operands[1], operands[2]));
749 emit_move_insn (operands[0], temp);
750 DONE;
751 }
752 }")
753
754 (define_insn ""
755 [(set (match_operand:SI 0 "register_operand" "=dx,ax,ax,dax,xy,!dax")
756 (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,dax")
757 (match_operand:SI 2 "nonmemory_operand" "J,J,L,daxi,i,dax")))]
758 "TARGET_AM33"
759 "*
760 {
761 switch (which_alternative)
762 {
763 case 0:
764 case 1:
765 return \"inc %0\";
766 case 2:
767 return \"inc4 %0\";
768 case 3:
769 case 4:
770 return \"add %2,%0\";
771 case 5:
772 {
773 enum reg_class src1_class, src2_class, dst_class;
774
775 src1_class = REGNO_REG_CLASS (true_regnum (operands[1]));
776 src2_class = REGNO_REG_CLASS (true_regnum (operands[2]));
777 dst_class = REGNO_REG_CLASS (true_regnum (operands[0]));
778
779 /* I'm not sure if this can happen or not. Might as well be prepared
780 and generate the best possible code if it does happen. */
781 if (true_regnum (operands[0]) == true_regnum (operands[1]))
782 return \"add %2,%0\";
783 if (true_regnum (operands[0]) == true_regnum (operands[2]))
784 return \"add %1,%0\";
785
786 /* Catch cases where no extended register was used. These should be
787 handled just like the mn10300. */
788 if (src1_class != EXTENDED_REGS
789 && src2_class != EXTENDED_REGS
790 && dst_class != EXTENDED_REGS)
791 {
792 /* We have to copy one of the sources into the destination, then
793 add the other source to the destination.
794
795 Carefully select which source to copy to the destination; a naive
796 implementation will waste a byte when the source classes are
797 different and the destination is an address register. Selecting
798 the lowest cost register copy will optimize this sequence. */
799 if (REGNO_REG_CLASS (true_regnum (operands[1]))
800 == REGNO_REG_CLASS (true_regnum (operands[0])))
801 return \"mov %1,%0\;add %2,%0\";
802 return \"mov %2,%0\;add %1,%0\";
803 }
804
805 /* At least one register is an extended register. */
806
807 /* The three operand add instruction on the am33 is a win iff the
808 output register is an extended register, or if both source
809 registers are extended registers. */
810 if (dst_class == EXTENDED_REGS
811 || src1_class == src2_class)
812 return \"add %2,%1,%0\";
813
814 /* It is better to copy one of the sources to the destination, then
815 perform a 2 address add. The destination in this case must be
816 an address or data register and one of the sources must be an
817 extended register and the remaining source must not be an extended
818 register.
819
820 The best code for this case is to copy the extended reg to the
821 destination, then emit a two address add. */
822 if (src1_class == EXTENDED_REGS)
823 return \"mov %1,%0\;add %2,%0\";
824 return \"mov %2,%0\;add %1,%0\";
825 }
826 default:
827 abort();
828 }
829 }"
830 [(set_attr "cc" "set_zn,none_0hit,none_0hit,set_zn,none_0hit,set_zn")])
831
832 (define_insn ""
833 [(set (match_operand:SI 0 "register_operand" "=dx,ax,ax,dax,xy,!dax")
834 (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,dax")
835 (match_operand:SI 2 "nonmemory_operand" "J,J,L,daxi,i,dax")))]
836 ""
837 "*
838 {
839 switch (which_alternative)
840 {
841 case 0:
842 case 1:
843 return \"inc %0\";
844 case 2:
845 return \"inc4 %0\";
846 case 3:
847 case 4:
848 return \"add %2,%0\";
849 case 5:
850 /* I'm not sure if this can happen or not. Might as well be prepared
851 and generate the best possible code if it does happen. */
852 if (true_regnum (operands[0]) == true_regnum (operands[1]))
853 return \"add %2,%0\";
854 if (true_regnum (operands[0]) == true_regnum (operands[2]))
855 return \"add %1,%0\";
856
857 /* We have to copy one of the sources into the destination, then add
858 the other source to the destination.
859
860 Carefully select which source to copy to the destination; a naive
861 implementation will waste a byte when the source classes are different
862 and the destination is an address register. Selecting the lowest
863 cost register copy will optimize this sequence. */
864 if (REGNO_REG_CLASS (true_regnum (operands[1]))
865 == REGNO_REG_CLASS (true_regnum (operands[0])))
866 return \"mov %1,%0\;add %2,%0\";
867 return \"mov %2,%0\;add %1,%0\";
868 default:
869 abort();
870 }
871 }"
872 [(set_attr "cc" "set_zn,none_0hit,none_0hit,set_zn,none_0hit,set_zn")])
873
874 ;; ----------------------------------------------------------------------
875 ;; SUBTRACT INSTRUCTIONS
876 ;; ----------------------------------------------------------------------
877
878 (define_expand "subsi3"
879 [(set (match_operand:SI 0 "register_operand" "")
880 (minus:SI (match_operand:SI 1 "register_operand" "")
881 (match_operand:SI 2 "nonmemory_operand" "")))]
882 ""
883 "")
884
885 (define_insn ""
886 [(set (match_operand:SI 0 "register_operand" "=dax,!dax")
887 (minus:SI (match_operand:SI 1 "register_operand" "0,dax")
888 (match_operand:SI 2 "nonmemory_operand" "daxi,dax")))]
889 "TARGET_AM33"
890 "*
891 {
892 if (true_regnum (operands[0]) == true_regnum (operands[1]))
893 return \"sub %2,%0\";
894 else
895 {
896 enum reg_class src1_class, src2_class, dst_class;
897
898 src1_class = REGNO_REG_CLASS (true_regnum (operands[1]));
899 src2_class = REGNO_REG_CLASS (true_regnum (operands[2]));
900 dst_class = REGNO_REG_CLASS (true_regnum (operands[0]));
901
902 /* If no extended registers are used, then the best way to handle
903 this is to copy the first source operand into the destination
904 and emit a two address subtraction. */
905 if (src1_class != EXTENDED_REGS
906 && src2_class != EXTENDED_REGS
907 && dst_class != EXTENDED_REGS
908 && true_regnum (operands[0]) != true_regnum (operands[2]))
909 return \"mov %1,%0\;sub %2,%0\";
910 return \"sub %2,%1,%0\";
911 }
912 }"
913 [(set_attr "cc" "set_zn")])
914
915 (define_insn ""
916 [(set (match_operand:SI 0 "register_operand" "=dax")
917 (minus:SI (match_operand:SI 1 "register_operand" "0")
918 (match_operand:SI 2 "nonmemory_operand" "daxi")))]
919 ""
920 "sub %2,%0"
921 [(set_attr "cc" "set_zn")])
922
923 (define_expand "negsi2"
924 [(set (match_operand:SI 0 "register_operand" "")
925 (neg:SI (match_operand:SI 1 "register_operand" "")))]
926 ""
927 "
928 {
929 rtx target = gen_reg_rtx (SImode);
930
931 emit_move_insn (target, GEN_INT (0));
932 emit_insn (gen_subsi3 (target, target, operands[1]));
933 emit_move_insn (operands[0], target);
934 DONE;
935 }")
936
937 ;; ----------------------------------------------------------------------
938 ;; MULTIPLY INSTRUCTIONS
939 ;; ----------------------------------------------------------------------
940
941 (define_insn "mulsidi3"
942 [(set (match_operand:DI 0 "register_operand" "=dax")
943 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "dax"))
944 (sign_extend:DI (match_operand:SI 2 "register_operand" "dax"))))]
945 "TARGET_AM33"
946 "mul %1,%2,%H0,%L0"
947 [(set_attr "cc" "set_zn")])
948
949 (define_insn "umulsidi3"
950 [(set (match_operand:DI 0 "register_operand" "=dax")
951 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "dax"))
952 (zero_extend:DI (match_operand:SI 2 "register_operand" "dax"))))]
953 "TARGET_AM33"
954 "mulu %1,%2,%H0,%L0"
955 [(set_attr "cc" "set_zn")])
956
957 (define_expand "mulsi3"
958 [(set (match_operand:SI 0 "register_operand" "")
959 (mult:SI (match_operand:SI 1 "register_operand" "")
960 (match_operand:SI 2 "register_operand" "")))]
961 ""
962 "")
963
964 (define_insn ""
965 [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
966 (mult:SI (match_operand:SI 1 "register_operand" "%0,0")
967 (match_operand:SI 2 "nonmemory_operand" "dx,daxi")))]
968 "TARGET_AM33"
969 "*
970 {
971 if (TARGET_MULT_BUG)
972 return \"nop\;nop\;mul %2,%0\";
973 else
974 return \"mul %2,%0\";
975 }"
976 [(set_attr "cc" "set_zn")])
977
978 (define_insn ""
979 [(set (match_operand:SI 0 "register_operand" "=dx")
980 (mult:SI (match_operand:SI 1 "register_operand" "%0")
981 (match_operand:SI 2 "register_operand" "dx")))]
982 ""
983 "*
984 {
985 if (TARGET_MULT_BUG)
986 return \"nop\;nop\;mul %2,%0\";
987 else
988 return \"mul %2,%0\";
989 }"
990 [(set_attr "cc" "set_zn")])
991
992 (define_insn "udivmodsi4"
993 [(set (match_operand:SI 0 "general_operand" "=dx")
994 (udiv:SI (match_operand:SI 1 "general_operand" "0")
995 (match_operand:SI 2 "general_operand" "dx")))
996 (set (match_operand:SI 3 "general_operand" "=&d")
997 (umod:SI (match_dup 1) (match_dup 2)))]
998 ""
999 "*
1000 {
1001 output_asm_insn (\"sub %3,%3\;mov %3,mdr\", operands);
1002
1003 if (find_reg_note (insn, REG_UNUSED, operands[3]))
1004 return \"divu %2,%0\";
1005 else
1006 return \"divu %2,%0\;mov mdr,%3\";
1007 }"
1008 [(set_attr "cc" "set_zn")])
1009
1010 (define_insn "divmodsi4"
1011 [(set (match_operand:SI 0 "general_operand" "=dx")
1012 (div:SI (match_operand:SI 1 "general_operand" "0")
1013 (match_operand:SI 2 "general_operand" "dx")))
1014 (set (match_operand:SI 3 "general_operand" "=d")
1015 (mod:SI (match_dup 1) (match_dup 2)))]
1016 ""
1017 "*
1018 {
1019 if (find_reg_note (insn, REG_UNUSED, operands[3]))
1020 return \"ext %0\;div %2,%0\";
1021 else
1022 return \"ext %0\;div %2,%0\;mov mdr,%3\";
1023 }"
1024 [(set_attr "cc" "set_zn")])
1025
1026 \f
1027 ;; ----------------------------------------------------------------------
1028 ;; AND INSTRUCTIONS
1029 ;; ----------------------------------------------------------------------
1030
1031 (define_expand "andsi3"
1032 [(set (match_operand:SI 0 "register_operand" "")
1033 (and:SI (match_operand:SI 1 "register_operand" "")
1034 (match_operand:SI 2 "nonmemory_operand" "")))]
1035 ""
1036 "")
1037
1038 (define_insn ""
1039 [(set (match_operand:SI 0 "register_operand" "=dx,dx,!dax")
1040 (and:SI (match_operand:SI 1 "register_operand" "%0,0,dax")
1041 (match_operand:SI 2 "nonmemory_operand" "N,dxi,dax")))]
1042 "TARGET_AM33"
1043 "*
1044 {
1045 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff)
1046 return \"extbu %0\";
1047 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xffff)
1048 return \"exthu %0\";
1049 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x7fffffff)
1050 return \"add %0,%0\;lsr 1,%0\";
1051 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x3fffffff)
1052 return \"asl2 %0\;lsr 2,%0\";
1053 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x1fffffff)
1054 return \"add %0,%0\;asl2 %0\;lsr 3,%0\";
1055 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x0fffffff)
1056 return \"asl2 %0\;asl2 %0\;lsr 4,%0\";
1057 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffe)
1058 return \"lsr 1,%0\;add %0,%0\";
1059 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffc)
1060 return \"lsr 2,%0\;asl2 %0\";
1061 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff8)
1062 return \"lsr 3,%0\;add %0,%0\;asl2 %0\";
1063 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff0)
1064 return \"lsr 4,%0\;asl2 %0\;asl2 %0\";
1065 if (REG_P (operands[2]) && REG_P (operands[1])
1066 && true_regnum (operands[0]) != true_regnum (operands[1])
1067 && true_regnum (operands[0]) != true_regnum (operands[2])
1068 && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1069 && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1070 && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
1071 return \"mov %1,%0\;and %2,%0\";
1072 if (REG_P (operands[2]) && REG_P (operands[1])
1073 && true_regnum (operands[0]) != true_regnum (operands[1])
1074 && true_regnum (operands[0]) != true_regnum (operands[2]))
1075 return \"and %1,%2,%0\";
1076 if (REG_P (operands[2]) && REG_P (operands[0])
1077 && true_regnum (operands[2]) == true_regnum (operands[0]))
1078 return \"and %1,%0\";
1079 return \"and %2,%0\";
1080 }"
1081 [(set_attr "cc" "none_0hit,set_znv,set_znv")])
1082
1083 (define_insn ""
1084 [(set (match_operand:SI 0 "register_operand" "=dx,dx")
1085 (and:SI (match_operand:SI 1 "register_operand" "%0,0")
1086 (match_operand:SI 2 "nonmemory_operand" "N,dxi")))]
1087 ""
1088 "*
1089 {
1090 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff)
1091 return \"extbu %0\";
1092 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xffff)
1093 return \"exthu %0\";
1094 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x7fffffff)
1095 return \"add %0,%0\;lsr 1,%0\";
1096 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x3fffffff)
1097 return \"asl2 %0\;lsr 2,%0\";
1098 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x1fffffff)
1099 return \"add %0,%0\;asl2 %0\;lsr 3,%0\";
1100 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x0fffffff)
1101 return \"asl2 %0\;asl2 %0\;lsr 4,%0\";
1102 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffe)
1103 return \"lsr 1,%0\;add %0,%0\";
1104 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffc)
1105 return \"lsr 2,%0\;asl2 %0\";
1106 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff8)
1107 return \"lsr 3,%0\;add %0,%0\;asl2 %0\";
1108 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff0)
1109 return \"lsr 4,%0\;asl2 %0\;asl2 %0\";
1110 return \"and %2,%0\";
1111 }"
1112 [(set_attr "cc" "none_0hit,set_znv")])
1113
1114 ;; ----------------------------------------------------------------------
1115 ;; OR INSTRUCTIONS
1116 ;; ----------------------------------------------------------------------
1117
1118 (define_expand "iorsi3"
1119 [(set (match_operand:SI 0 "register_operand" "")
1120 (ior:SI (match_operand:SI 1 "register_operand" "")
1121 (match_operand:SI 2 "nonmemory_operand" "")))]
1122 ""
1123 "")
1124
1125 (define_insn ""
1126 [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1127 (ior:SI (match_operand:SI 1 "register_operand" "%0,dax")
1128 (match_operand:SI 2 "nonmemory_operand" "dxi,dax")))]
1129 "TARGET_AM33"
1130 "*
1131 {
1132 if (REG_P (operands[2]) && REG_P (operands[1])
1133 && true_regnum (operands[0]) != true_regnum (operands[1])
1134 && true_regnum (operands[0]) != true_regnum (operands[2])
1135 && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1136 && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1137 && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
1138 return \"mov %1,%0\;or %2,%0\";
1139 if (REG_P (operands[2]) && REG_P (operands[1])
1140 && true_regnum (operands[0]) != true_regnum (operands[1])
1141 && true_regnum (operands[0]) != true_regnum (operands[2]))
1142 return \"or %1,%2,%0\";
1143 if (REG_P (operands[2]) && REG_P (operands[0])
1144 && true_regnum (operands[2]) == true_regnum (operands[0]))
1145 return \"or %1,%0\";
1146 return \"or %2,%0\";
1147 }"
1148 [(set_attr "cc" "set_znv")])
1149
1150 (define_insn ""
1151 [(set (match_operand:SI 0 "register_operand" "=dx")
1152 (ior:SI (match_operand:SI 1 "register_operand" "%0")
1153 (match_operand:SI 2 "nonmemory_operand" "dxi")))]
1154 ""
1155 "or %2,%0"
1156 [(set_attr "cc" "set_znv")])
1157
1158 ;; ----------------------------------------------------------------------
1159 ;; XOR INSTRUCTIONS
1160 ;; ----------------------------------------------------------------------
1161
1162 (define_expand "xorsi3"
1163 [(set (match_operand:SI 0 "register_operand" "")
1164 (xor:SI (match_operand:SI 1 "register_operand" "")
1165 (match_operand:SI 2 "nonmemory_operand" "")))]
1166 ""
1167 "")
1168
1169 (define_insn ""
1170 [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1171 (xor:SI (match_operand:SI 1 "register_operand" "%0,dax")
1172 (match_operand:SI 2 "nonmemory_operand" "dxi,dax")))]
1173 "TARGET_AM33"
1174 "*
1175 {
1176 if (REG_P (operands[2]) && REG_P (operands[1])
1177 && true_regnum (operands[0]) != true_regnum (operands[1])
1178 && true_regnum (operands[0]) != true_regnum (operands[2])
1179 && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1180 && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1181 && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
1182 return \"mov %1,%0\;xor %2,%0\";
1183 if (REG_P (operands[2]) && REG_P (operands[1])
1184 && true_regnum (operands[0]) != true_regnum (operands[1])
1185 && true_regnum (operands[0]) != true_regnum (operands[2]))
1186 return \"xor %1,%2,%0\";
1187 if (REG_P (operands[2]) && REG_P (operands[0])
1188 && true_regnum (operands[2]) == true_regnum (operands[0]))
1189 return \"xor %1,%0\";
1190 return \"xor %2,%0\";
1191 }"
1192 [(set_attr "cc" "set_znv")])
1193
1194 (define_insn ""
1195 [(set (match_operand:SI 0 "register_operand" "=dx")
1196 (xor:SI (match_operand:SI 1 "register_operand" "%0")
1197 (match_operand:SI 2 "nonmemory_operand" "dxi")))]
1198 ""
1199 "xor %2,%0"
1200 [(set_attr "cc" "set_znv")])
1201
1202 ;; ----------------------------------------------------------------------
1203 ;; NOT INSTRUCTIONS
1204 ;; ----------------------------------------------------------------------
1205
1206 (define_expand "one_cmplsi2"
1207 [(set (match_operand:SI 0 "register_operand" "")
1208 (not:SI (match_operand:SI 1 "register_operand" "")))]
1209 ""
1210 "")
1211
1212 (define_insn ""
1213 [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1214 (not:SI (match_operand:SI 1 "register_operand" "0,0")))]
1215 "TARGET_AM33"
1216 "not %0"
1217 [(set_attr "cc" "set_znv")])
1218
1219 (define_insn ""
1220 [(set (match_operand:SI 0 "register_operand" "=dx")
1221 (not:SI (match_operand:SI 1 "register_operand" "0")))]
1222 ""
1223 "not %0"
1224 [(set_attr "cc" "set_znv")])
1225 \f
1226 ;; -----------------------------------------------------------------
1227 ;; BIT FIELDS
1228 ;; -----------------------------------------------------------------
1229
1230
1231 ;; These set/clear memory in byte sized chunks.
1232 ;;
1233 ;; They are no smaller/faster than loading the value into a register
1234 ;; and storing the register, but they don't need a scratch register
1235 ;; which may allow for better code generation.
1236 (define_insn ""
1237 [(set (match_operand:QI 0 "general_operand" "=R,d") (const_int 0))]
1238 ""
1239 "@
1240 bclr 255,%A0
1241 clr %0"
1242 [(set_attr "cc" "clobber")])
1243
1244 (define_insn ""
1245 [(set (match_operand:QI 0 "general_operand" "=R,d") (const_int -1))]
1246 ""
1247 "@
1248 bset 255,%A0
1249 mov -1,%0"
1250 [(set_attr "cc" "clobber,none_0hit")])
1251
1252 (define_insn ""
1253 [(set (match_operand:QI 0 "general_operand" "+R,d")
1254 (subreg:QI
1255 (and:SI (subreg:SI (match_dup 0) 0)
1256 (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
1257 ""
1258 "@
1259 bclr %N1,%A0
1260 and %1,%0"
1261 [(set_attr "cc" "clobber,set_znv")])
1262
1263 (define_insn ""
1264 [(set (match_operand:QI 0 "general_operand" "+R,d")
1265 (subreg:QI
1266 (ior:SI (subreg:SI (match_dup 0) 0)
1267 (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
1268 ""
1269 "@
1270 bset %1,%A0
1271 or %1,%0"
1272 [(set_attr "cc" "clobber,set_znv")])
1273
1274 (define_insn ""
1275 [(set (cc0)
1276 (zero_extract:SI (match_operand:SI 0 "register_operand" "dx")
1277 (match_operand 1 "const_int_operand" "")
1278 (match_operand 2 "const_int_operand" "")))]
1279 ""
1280 "*
1281 {
1282 int len = INTVAL (operands[1]);
1283 int bit = INTVAL (operands[2]);
1284 int mask = 0;
1285 rtx xoperands[2];
1286
1287 while (len > 0)
1288 {
1289 mask |= (1 << bit);
1290 bit++;
1291 len--;
1292 }
1293
1294 xoperands[0] = operands[0];
1295 xoperands[1] = GEN_INT (mask);
1296 output_asm_insn (\"btst %1,%0\", xoperands);
1297 return \"\";
1298 }"
1299 [(set_attr "cc" "clobber")])
1300
1301 (define_insn ""
1302 [(set (cc0)
1303 (zero_extract:SI (match_operand:QI 0 "general_operand" "R,dx")
1304 (match_operand 1 "const_int_operand" "")
1305 (match_operand 2 "const_int_operand" "")))]
1306 "mask_ok_for_mem_btst (INTVAL (operands[1]), INTVAL (operands[2]))"
1307 "*
1308 {
1309 int len = INTVAL (operands[1]);
1310 int bit = INTVAL (operands[2]);
1311 int mask = 0;
1312 rtx xoperands[2];
1313
1314 while (len > 0)
1315 {
1316 mask |= (1 << bit);
1317 bit++;
1318 len--;
1319 }
1320
1321 /* If the source operand is not a reg (ie it is memory), then extract the
1322 bits from mask that we actually want to test. Note that the mask will
1323 never cross a byte boundary. */
1324 if (!REG_P (operands[0]))
1325 {
1326 if (mask & 0xff)
1327 mask = mask & 0xff;
1328 else if (mask & 0xff00)
1329 mask = (mask >> 8) & 0xff;
1330 else if (mask & 0xff0000)
1331 mask = (mask >> 16) & 0xff;
1332 else if (mask & 0xff000000)
1333 mask = (mask >> 24) & 0xff;
1334 }
1335
1336 xoperands[0] = operands[0];
1337 xoperands[1] = GEN_INT (mask);
1338 if (GET_CODE (operands[0]) == REG)
1339 output_asm_insn (\"btst %1,%0\", xoperands);
1340 else
1341 output_asm_insn (\"btst %1,%A0\", xoperands);
1342 return \"\";
1343 }"
1344 [(set_attr "cc" "clobber")])
1345
1346 (define_insn ""
1347 [(set (cc0) (and:SI (match_operand:SI 0 "register_operand" "dx")
1348 (match_operand:SI 1 "const_int_operand" "")))]
1349 ""
1350 "btst %1,%0"
1351 [(set_attr "cc" "clobber")])
1352
1353 (define_insn ""
1354 [(set (cc0)
1355 (and:SI
1356 (subreg:SI (match_operand:QI 0 "general_operand" "R,dx") 0)
1357 (match_operand:SI 1 "const_8bit_operand" "")))]
1358 ""
1359 "@
1360 btst %1,%A0
1361 btst %1,%0"
1362 [(set_attr "cc" "clobber")])
1363
1364 \f
1365 ;; ----------------------------------------------------------------------
1366 ;; JUMP INSTRUCTIONS
1367 ;; ----------------------------------------------------------------------
1368
1369 ;; Conditional jump instructions
1370
1371 (define_expand "ble"
1372 [(set (pc)
1373 (if_then_else (le (cc0)
1374 (const_int 0))
1375 (label_ref (match_operand 0 "" ""))
1376 (pc)))]
1377 ""
1378 "")
1379
1380 (define_expand "bleu"
1381 [(set (pc)
1382 (if_then_else (leu (cc0)
1383 (const_int 0))
1384 (label_ref (match_operand 0 "" ""))
1385 (pc)))]
1386 ""
1387 "")
1388
1389 (define_expand "bge"
1390 [(set (pc)
1391 (if_then_else (ge (cc0)
1392 (const_int 0))
1393 (label_ref (match_operand 0 "" ""))
1394 (pc)))]
1395 ""
1396 "")
1397
1398 (define_expand "bgeu"
1399 [(set (pc)
1400 (if_then_else (geu (cc0)
1401 (const_int 0))
1402 (label_ref (match_operand 0 "" ""))
1403 (pc)))]
1404 ""
1405 "")
1406
1407 (define_expand "blt"
1408 [(set (pc)
1409 (if_then_else (lt (cc0)
1410 (const_int 0))
1411 (label_ref (match_operand 0 "" ""))
1412 (pc)))]
1413 ""
1414 "")
1415
1416 (define_expand "bltu"
1417 [(set (pc)
1418 (if_then_else (ltu (cc0)
1419 (const_int 0))
1420 (label_ref (match_operand 0 "" ""))
1421 (pc)))]
1422 ""
1423 "")
1424
1425 (define_expand "bgt"
1426 [(set (pc)
1427 (if_then_else (gt (cc0)
1428 (const_int 0))
1429 (label_ref (match_operand 0 "" ""))
1430 (pc)))]
1431 ""
1432 "")
1433
1434 (define_expand "bgtu"
1435 [(set (pc)
1436 (if_then_else (gtu (cc0)
1437 (const_int 0))
1438 (label_ref (match_operand 0 "" ""))
1439 (pc)))]
1440 ""
1441 "")
1442
1443 (define_expand "beq"
1444 [(set (pc)
1445 (if_then_else (eq (cc0)
1446 (const_int 0))
1447 (label_ref (match_operand 0 "" ""))
1448 (pc)))]
1449 ""
1450 "")
1451
1452 (define_expand "bne"
1453 [(set (pc)
1454 (if_then_else (ne (cc0)
1455 (const_int 0))
1456 (label_ref (match_operand 0 "" ""))
1457 (pc)))]
1458 ""
1459 "")
1460
1461 (define_insn ""
1462 [(set (pc)
1463 (if_then_else (match_operator 1 "comparison_operator"
1464 [(cc0) (const_int 0)])
1465 (label_ref (match_operand 0 "" ""))
1466 (pc)))]
1467 ""
1468 "*
1469 {
1470 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1471 && (GET_CODE (operands[1]) == GT
1472 || GET_CODE (operands[1]) == GE
1473 || GET_CODE (operands[1]) == LE
1474 || GET_CODE (operands[1]) == LT))
1475 return 0;
1476 return \"b%b1 %0\";
1477 }"
1478 [(set_attr "cc" "none")])
1479
1480 (define_insn ""
1481 [(set (pc)
1482 (if_then_else (match_operator 1 "comparison_operator"
1483 [(cc0) (const_int 0)])
1484 (pc)
1485 (label_ref (match_operand 0 "" ""))))]
1486 ""
1487 "*
1488 {
1489 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1490 && (GET_CODE (operands[1]) == GT
1491 || GET_CODE (operands[1]) == GE
1492 || GET_CODE (operands[1]) == LE
1493 || GET_CODE (operands[1]) == LT))
1494 return 0;
1495 return \"b%B1 %0\";
1496 }"
1497 [(set_attr "cc" "none")])
1498
1499 ;; Unconditional and other jump instructions.
1500
1501 (define_insn "jump"
1502 [(set (pc)
1503 (label_ref (match_operand 0 "" "")))]
1504 ""
1505 "jmp %l0"
1506 [(set_attr "cc" "none")])
1507
1508 (define_insn "indirect_jump"
1509 [(set (pc) (match_operand:SI 0 "register_operand" "a"))]
1510 ""
1511 "jmp (%0)"
1512 [(set_attr "cc" "none")])
1513
1514 (define_insn "tablejump"
1515 [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1516 (use (label_ref (match_operand 1 "" "")))]
1517 ""
1518 "jmp (%0)"
1519 [(set_attr "cc" "none")])
1520
1521 ;; Call subroutine with no return value.
1522
1523 (define_expand "call"
1524 [(call (match_operand:QI 0 "general_operand" "")
1525 (match_operand:SI 1 "general_operand" ""))]
1526 ""
1527 "
1528 {
1529 if (! call_address_operand (XEXP (operands[0], 0), VOIDmode))
1530 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
1531 emit_call_insn (gen_call_internal (XEXP (operands[0], 0), operands[1]));
1532 DONE;
1533 }")
1534
1535 (define_insn "call_internal"
1536 [(call (mem:QI (match_operand:SI 0 "call_address_operand" "aS"))
1537 (match_operand:SI 1 "general_operand" "g"))]
1538 ""
1539 "*
1540 {
1541 if (REG_P (operands[0]))
1542 return \"calls %C0\";
1543 else
1544 return \"call %C0,[],0\";
1545 }"
1546 [(set_attr "cc" "clobber")])
1547
1548 ;; Call subroutine, returning value in operand 0
1549 ;; (which must be a hard register).
1550
1551 (define_expand "call_value"
1552 [(set (match_operand 0 "" "")
1553 (call (match_operand:QI 1 "general_operand" "")
1554 (match_operand:SI 2 "general_operand" "")))]
1555 ""
1556 "
1557 {
1558 if (! call_address_operand (XEXP (operands[1], 0), VOIDmode))
1559 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
1560 emit_call_insn (gen_call_value_internal (operands[0],
1561 XEXP (operands[1], 0),
1562 operands[2]));
1563 DONE;
1564 }")
1565
1566 (define_insn "call_value_internal"
1567 [(set (match_operand 0 "" "=dax")
1568 (call (mem:QI (match_operand:SI 1 "call_address_operand" "aS"))
1569 (match_operand:SI 2 "general_operand" "g")))]
1570 ""
1571 "*
1572 {
1573 if (REG_P (operands[1]))
1574 return \"calls %C1\";
1575 else
1576 return \"call %C1,[],0\";
1577 }"
1578 [(set_attr "cc" "clobber")])
1579
1580 (define_expand "untyped_call"
1581 [(parallel [(call (match_operand 0 "" "")
1582 (const_int 0))
1583 (match_operand 1 "" "")
1584 (match_operand 2 "" "")])]
1585 ""
1586 "
1587 {
1588 int i;
1589
1590 emit_call_insn (gen_call (operands[0], const0_rtx));
1591
1592 for (i = 0; i < XVECLEN (operands[2], 0); i++)
1593 {
1594 rtx set = XVECEXP (operands[2], 0, i);
1595 emit_move_insn (SET_DEST (set), SET_SRC (set));
1596 }
1597 DONE;
1598 }")
1599
1600 (define_insn "nop"
1601 [(const_int 0)]
1602 ""
1603 "nop"
1604 [(set_attr "cc" "none")])
1605 \f
1606 ;; ----------------------------------------------------------------------
1607 ;; EXTEND INSTRUCTIONS
1608 ;; ----------------------------------------------------------------------
1609
1610 (define_expand "zero_extendqisi2"
1611 [(set (match_operand:SI 0 "general_operand" "")
1612 (zero_extend:SI
1613 (match_operand:QI 1 "general_operand" "")))]
1614 ""
1615 "")
1616
1617 (define_insn ""
1618 [(set (match_operand:SI 0 "general_operand" "=dx,dx,dx,!dax,!dax,!dax")
1619 (zero_extend:SI
1620 (match_operand:QI 1 "general_operand" "0,dax,m,0,dax,m")))]
1621 "TARGET_AM33"
1622 "@
1623 extbu %0
1624 mov %1,%0\;extbu %0
1625 movbu %1,%0
1626 extbu %0
1627 mov %1,%0\;extbu %0
1628 movbu %1,%0"
1629 [(set_attr "cc" "none_0hit")])
1630
1631 (define_insn ""
1632 [(set (match_operand:SI 0 "general_operand" "=dx,dx,dx")
1633 (zero_extend:SI
1634 (match_operand:QI 1 "general_operand" "0,d,m")))]
1635 ""
1636 "@
1637 extbu %0
1638 mov %1,%0\;extbu %0
1639 movbu %1,%0"
1640 [(set_attr "cc" "none_0hit")])
1641
1642 (define_expand "zero_extendhisi2"
1643 [(set (match_operand:SI 0 "general_operand" "")
1644 (zero_extend:SI
1645 (match_operand:HI 1 "general_operand" "")))]
1646 ""
1647 "")
1648
1649 (define_insn ""
1650 [(set (match_operand:SI 0 "general_operand" "=dx,dx,dx,!dax,!dax,!dax")
1651 (zero_extend:SI
1652 (match_operand:HI 1 "general_operand" "0,dax,m,0,dax,m")))]
1653 "TARGET_AM33"
1654 "@
1655 exthu %0
1656 mov %1,%0\;exthu %0
1657 movhu %1,%0
1658 exthu %0
1659 mov %1,%0\;exthu %0
1660 movhu %1,%0"
1661 [(set_attr "cc" "none_0hit")])
1662
1663 (define_insn ""
1664 [(set (match_operand:SI 0 "general_operand" "=dx,dx,dx")
1665 (zero_extend:SI
1666 (match_operand:HI 1 "general_operand" "0,dx,m")))]
1667 ""
1668 "@
1669 exthu %0
1670 mov %1,%0\;exthu %0
1671 movhu %1,%0"
1672 [(set_attr "cc" "none_0hit")])
1673
1674 ;;- sign extension instructions
1675
1676 (define_expand "extendqisi2"
1677 [(set (match_operand:SI 0 "general_operand" "")
1678 (sign_extend:SI
1679 (match_operand:QI 1 "general_operand" "")))]
1680 ""
1681 "")
1682
1683 (define_insn ""
1684 [(set (match_operand:SI 0 "general_operand" "=dx,dx,!dax,!dax")
1685 (sign_extend:SI
1686 (match_operand:QI 1 "general_operand" "0,dx,0,dax")))]
1687 "TARGET_AM33"
1688 "@
1689 extb %0
1690 mov %1,%0\;extb %0
1691 extb %0
1692 mov %1,%0\;extb %0"
1693 [(set_attr "cc" "none_0hit")])
1694
1695 (define_insn ""
1696 [(set (match_operand:SI 0 "general_operand" "=dx,dx")
1697 (sign_extend:SI
1698 (match_operand:QI 1 "general_operand" "0,dx")))]
1699 ""
1700 "@
1701 extb %0
1702 mov %1,%0\;extb %0"
1703 [(set_attr "cc" "none_0hit")])
1704
1705 (define_expand "extendhisi2"
1706 [(set (match_operand:SI 0 "general_operand" "")
1707 (sign_extend:SI
1708 (match_operand:HI 1 "general_operand" "")))]
1709 ""
1710 "")
1711
1712 (define_insn ""
1713 [(set (match_operand:SI 0 "general_operand" "=dx,dx,!dax,!dax")
1714 (sign_extend:SI
1715 (match_operand:HI 1 "general_operand" "0,dax,0,dax")))]
1716 "TARGET_AM33"
1717 "@
1718 exth %0
1719 mov %1,%0\;exth %0
1720 exth %0
1721 mov %1,%0\;exth %0"
1722 [(set_attr "cc" "none_0hit")])
1723
1724 (define_insn ""
1725 [(set (match_operand:SI 0 "general_operand" "=dx,dx")
1726 (sign_extend:SI
1727 (match_operand:HI 1 "general_operand" "0,dx")))]
1728 ""
1729 "@
1730 exth %0
1731 mov %1,%0\;exth %0"
1732 [(set_attr "cc" "none_0hit")])
1733 \f
1734 ;; ----------------------------------------------------------------------
1735 ;; SHIFTS
1736 ;; ----------------------------------------------------------------------
1737
1738 (define_expand "ashlsi3"
1739 [(set (match_operand:SI 0 "register_operand" "")
1740 (ashift:SI
1741 (match_operand:SI 1 "register_operand" "")
1742 (match_operand:QI 2 "nonmemory_operand" "")))]
1743 ""
1744 "")
1745
1746 (define_insn ""
1747 [(set (match_operand:SI 0 "register_operand" "=dax,dx,!dax")
1748 (ashift:SI
1749 (match_operand:SI 1 "register_operand" "0,0,dax")
1750 (match_operand:QI 2 "nonmemory_operand" "J,dxi,dax")))]
1751 "TARGET_AM33"
1752 "*
1753 {
1754 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 1)
1755 return \"add %0,%0\";
1756
1757 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 2)
1758 return \"asl2 %0\";
1759
1760 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 3
1761 && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS)
1762 return \"asl2 %0\;add %0,%0\";
1763
1764 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 4
1765 && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS)
1766 return \"asl2 %0\;asl2 %0\";
1767
1768 if (true_regnum (operands[1]) == true_regnum (operands[0]))
1769 return \"asl %S2,%0\";
1770
1771 if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1772 && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1773 && true_regnum (operands[0]) != true_regnum (operands[2]))
1774 return \"mov %1,%0\;asl %S2,%0\";
1775 return \"asl %2,%1,%0\";
1776 }"
1777 [(set_attr "cc" "set_zn")])
1778
1779 (define_insn ""
1780 [(set (match_operand:SI 0 "register_operand" "=dax,dx,dx,dx,dx")
1781 (ashift:SI
1782 (match_operand:SI 1 "register_operand" "0,0,0,0,0")
1783 (match_operand:QI 2 "nonmemory_operand" "J,K,M,L,dxi")))]
1784 ""
1785 "@
1786 add %0,%0
1787 asl2 %0
1788 asl2 %0\;add %0,%0
1789 asl2 %0\;asl2 %0
1790 asl %S2,%0"
1791 [(set_attr "cc" "set_zn")])
1792
1793 (define_expand "lshrsi3"
1794 [(set (match_operand:SI 0 "register_operand" "")
1795 (lshiftrt:SI
1796 (match_operand:SI 1 "register_operand" "")
1797 (match_operand:QI 2 "nonmemory_operand" "")))]
1798 ""
1799 "")
1800
1801 (define_insn ""
1802 [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1803 (lshiftrt:SI
1804 (match_operand:SI 1 "register_operand" "0,dax")
1805 (match_operand:QI 2 "nonmemory_operand" "dxi,dax")))]
1806 "TARGET_AM33"
1807 "*
1808 {
1809 if (true_regnum (operands[1]) == true_regnum (operands[0]))
1810 return \"lsr %S2,%0\";
1811
1812 if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1813 && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1814 && true_regnum (operands[0]) != true_regnum (operands[2]))
1815 return \"mov %1,%0\;lsr %S2,%0\";
1816 return \"lsr %2,%1,%0\";
1817 }"
1818 [(set_attr "cc" "set_zn")])
1819
1820 (define_insn ""
1821 [(set (match_operand:SI 0 "register_operand" "=dx")
1822 (lshiftrt:SI
1823 (match_operand:SI 1 "register_operand" "0")
1824 (match_operand:QI 2 "nonmemory_operand" "dxi")))]
1825 ""
1826 "lsr %S2,%0"
1827 [(set_attr "cc" "set_zn")])
1828
1829 (define_expand "ashrsi3"
1830 [(set (match_operand:SI 0 "register_operand" "")
1831 (ashiftrt:SI
1832 (match_operand:SI 1 "register_operand" "")
1833 (match_operand:QI 2 "nonmemory_operand" "")))]
1834 ""
1835 "")
1836
1837 (define_insn ""
1838 [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1839 (ashiftrt:SI
1840 (match_operand:SI 1 "register_operand" "0,dax")
1841 (match_operand:QI 2 "nonmemory_operand" "dxi,dax")))]
1842 "TARGET_AM33"
1843 "*
1844 {
1845 if (true_regnum (operands[1]) == true_regnum (operands[0]))
1846 return \"asr %S2,%0\";
1847
1848 if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1849 && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1850 && true_regnum (operands[0]) != true_regnum (operands[2]))
1851 return \"mov %1,%0\;asr %S2,%0\";
1852 return \"asr %2,%1,%0\";
1853 }"
1854 [(set_attr "cc" "set_zn")])
1855
1856 (define_insn ""
1857 [(set (match_operand:SI 0 "register_operand" "=dx")
1858 (ashiftrt:SI
1859 (match_operand:SI 1 "register_operand" "0")
1860 (match_operand:QI 2 "nonmemory_operand" "dxi")))]
1861 ""
1862 "asr %S2,%0"
1863 [(set_attr "cc" "set_zn")])
1864
1865 ;; ----------------------------------------------------------------------
1866 ;; FP INSTRUCTIONS
1867 ;; ----------------------------------------------------------------------
1868 ;;
1869 ;; The mn103 series does not have floating point instructions, but since
1870 ;; FP values are held in integer regs, we can clear the high bit easily
1871 ;; which gives us an efficient inline floating point absolute value.
1872 ;;
1873 ;; Similarly for negation of a FP value.
1874 ;;
1875
1876 (define_expand "absdf2"
1877 [(set (match_operand:DF 0 "register_operand" "")
1878 (abs:DF (match_operand:DF 1 "register_operand" "")))]
1879 ""
1880 "
1881 {
1882 rtx target, result, insns;
1883
1884 start_sequence ();
1885 target = operand_subword (operands[0], 1, 1, DFmode);
1886 result = expand_binop (SImode, and_optab,
1887 operand_subword_force (operands[1], 1, DFmode),
1888 GEN_INT(0x7fffffff), target, 0, OPTAB_WIDEN);
1889
1890 if (result == 0)
1891 abort ();
1892
1893 if (result != target)
1894 emit_move_insn (result, target);
1895
1896 emit_move_insn (operand_subword (operands[0], 0, 1, DFmode),
1897 operand_subword_force (operands[1], 0, DFmode));
1898
1899 insns = get_insns ();
1900 end_sequence ();
1901
1902 emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
1903 DONE;
1904 }")
1905
1906 (define_expand "abssf2"
1907 [(set (match_operand:SF 0 "register_operand" "")
1908 (abs:SF (match_operand:SF 1 "register_operand" "")))]
1909 ""
1910 "
1911 {
1912 rtx result;
1913 rtx target;
1914
1915 target = operand_subword_force (operands[0], 0, SFmode);
1916 result = expand_binop (SImode, and_optab,
1917 operand_subword_force (operands[1], 0, SFmode),
1918 GEN_INT(0x7fffffff), target, 0, OPTAB_WIDEN);
1919 if (result == 0)
1920 abort ();
1921
1922 if (result != target)
1923 emit_move_insn (result, target);
1924
1925 /* Make a place for REG_EQUAL. */
1926 emit_move_insn (operands[0], operands[0]);
1927 DONE;
1928 }")
1929
1930
1931 (define_expand "negdf2"
1932 [(set (match_operand:DF 0 "register_operand" "")
1933 (neg:DF (match_operand:DF 1 "register_operand" "")))]
1934 ""
1935 "
1936 {
1937 rtx target, result, insns;
1938
1939 start_sequence ();
1940 target = operand_subword (operands[0], 1, 1, DFmode);
1941 result = expand_binop (SImode, xor_optab,
1942 operand_subword_force (operands[1], 1, DFmode),
1943 GEN_INT(0x80000000), target, 0, OPTAB_WIDEN);
1944
1945 if (result == 0)
1946 abort ();
1947
1948 if (result != target)
1949 emit_move_insn (result, target);
1950
1951 emit_move_insn (operand_subword (operands[0], 0, 1, DFmode),
1952 operand_subword_force (operands[1], 0, DFmode));
1953
1954 insns = get_insns ();
1955 end_sequence ();
1956
1957 emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
1958 DONE;
1959 }")
1960
1961 (define_expand "negsf2"
1962 [(set (match_operand:SF 0 "register_operand" "")
1963 (neg:SF (match_operand:SF 1 "register_operand" "")))]
1964 ""
1965 "
1966 {
1967 rtx result;
1968 rtx target;
1969
1970 target = operand_subword_force (operands[0], 0, SFmode);
1971 result = expand_binop (SImode, xor_optab,
1972 operand_subword_force (operands[1], 0, SFmode),
1973 GEN_INT(0x80000000), target, 0, OPTAB_WIDEN);
1974 if (result == 0)
1975 abort ();
1976
1977 if (result != target)
1978 emit_move_insn (result, target);
1979
1980 /* Make a place for REG_EQUAL. */
1981 emit_move_insn (operands[0], operands[0]);
1982 DONE;
1983 }")
1984
1985
1986 ;; ----------------------------------------------------------------------
1987 ;; PROLOGUE/EPILOGUE
1988 ;; ----------------------------------------------------------------------
1989 (define_expand "prologue"
1990 [(const_int 0)]
1991 ""
1992 "expand_prologue (); DONE;")
1993
1994 (define_expand "epilogue"
1995 [(return)]
1996 ""
1997 "
1998 {
1999 expand_epilogue ();
2000 DONE;
2001 }")
2002
2003 (define_insn "return_internal"
2004 [(const_int 2)
2005 (return)]
2006 ""
2007 "rets"
2008 [(set_attr "cc" "clobber")])
2009
2010 ;; This insn restores the callee saved registers and does a return, it
2011 ;; can also deallocate stack space.
2012 (define_insn "return_internal_regs"
2013 [(const_int 0)
2014 (match_operand:SI 0 "const_int_operand" "i")
2015 (return)]
2016 ""
2017 "*
2018 {
2019 int need_comma;
2020
2021 need_comma = 0;
2022 fputs (\"\\tret [\", asm_out_file);
2023 if (regs_ever_live[2])
2024 {
2025 fputs (\"d2\", asm_out_file);
2026 need_comma = 1;
2027 }
2028 if (regs_ever_live[3])
2029 {
2030 if (need_comma)
2031 fputc (',', asm_out_file);
2032 fputs (\"d3\", asm_out_file);
2033 need_comma = 1;
2034 }
2035 if (regs_ever_live[6])
2036 {
2037 if (need_comma)
2038 fputc (',', asm_out_file);
2039 fputs (\"a2\", asm_out_file);
2040 need_comma = 1;
2041 }
2042 if (regs_ever_live[7])
2043 {
2044 if (need_comma)
2045 fputc (',', asm_out_file);
2046 fputs (\"a3\", asm_out_file);
2047 need_comma = 1;
2048 }
2049 if (regs_ever_live[14] || regs_ever_live[15]
2050 || regs_ever_live[16] || regs_ever_live[17])
2051 {
2052 if (need_comma)
2053 fputc (',', asm_out_file);
2054 fputs (\"exreg1\", asm_out_file);
2055 need_comma = 1;
2056 }
2057 fprintf (asm_out_file, \"],%d\\n\", INTVAL (operands[0]));
2058 return \"\";
2059 }"
2060 [(set_attr "cc" "clobber")])
2061
2062 (define_insn "store_movm"
2063 [(const_int 1)]
2064 ""
2065 "*
2066 {
2067 int need_comma;
2068
2069 need_comma = 0;
2070 fputs (\"\\tmovm [\", asm_out_file);
2071 if (regs_ever_live[2])
2072 {
2073 fputs (\"d2\", asm_out_file);
2074 need_comma = 1;
2075 }
2076 if (regs_ever_live[3])
2077 {
2078 if (need_comma)
2079 fputc (',', asm_out_file);
2080 fputs (\"d3\", asm_out_file);
2081 need_comma = 1;
2082 }
2083 if (regs_ever_live[6])
2084 {
2085 if (need_comma)
2086 fputc (',', asm_out_file);
2087 fputs (\"a2\", asm_out_file);
2088 need_comma = 1;
2089 }
2090 if (regs_ever_live[7])
2091 {
2092 if (need_comma)
2093 fputc (',', asm_out_file);
2094 fputs (\"a3\", asm_out_file);
2095 need_comma = 1;
2096 }
2097 if (regs_ever_live[14] || regs_ever_live[15]
2098 || regs_ever_live[16] || regs_ever_live[17])
2099 {
2100 if (need_comma)
2101 fputc (',', asm_out_file);
2102 fputs (\"exreg1\", asm_out_file);
2103 need_comma = 1;
2104 }
2105 fputs (\"],(sp)\\n\", asm_out_file);
2106 return \"\";
2107 }"
2108 [(set_attr "cc" "clobber")])
2109
2110 (define_insn "return"
2111 [(return)]
2112 "can_use_return_insn ()"
2113 "*
2114 {
2115 rtx next = next_active_insn (insn);
2116
2117 if (next
2118 && GET_CODE (next) == JUMP_INSN
2119 && GET_CODE (PATTERN (next)) == RETURN)
2120 return \"\";
2121 else
2122 return \"rets\";
2123 }"
2124 [(set_attr "cc" "clobber")])
2125
2126 ;; Try to combine consecutive updates of the stack pointer (or any
2127 ;; other register for that matter).
2128 (define_peephole
2129 [(set (match_operand:SI 0 "register_operand" "=dxay")
2130 (plus:SI (match_dup 0)
2131 (match_operand 1 "const_int_operand" "")))
2132 (set (match_dup 0)
2133 (plus:SI (match_dup 0)
2134 (match_operand 2 "const_int_operand" "")))]
2135 ""
2136 "*
2137 {
2138 operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]));
2139 return \"add %1,%0\";
2140 }"
2141 [(set_attr "cc" "clobber")])
2142
2143 ;;
2144 ;; We had patterns to check eq/ne, but the they don't work because
2145 ;; 0x80000000 + 0x80000000 = 0x0 with a carry out.
2146 ;;
2147 ;; The Z flag and C flag would be set, and we have no way to
2148 ;; check for the Z flag set and C flag clear.
2149 ;;
2150 ;; This will work on the mn10200 because we can check the ZX flag
2151 ;; if the comparison is in HImode.
2152 (define_peephole
2153 [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2154 (set (pc) (if_then_else (ge (cc0) (const_int 0))
2155 (match_operand 1 "" "")
2156 (pc)))]
2157 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2158 "add %0,%0\;bcc %1"
2159 [(set_attr "cc" "clobber")])
2160
2161 (define_peephole
2162 [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2163 (set (pc) (if_then_else (lt (cc0) (const_int 0))
2164 (match_operand 1 "" "")
2165 (pc)))]
2166 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2167 "add %0,%0\;bcs %1"
2168 [(set_attr "cc" "clobber")])
2169
2170 (define_peephole
2171 [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2172 (set (pc) (if_then_else (ge (cc0) (const_int 0))
2173 (pc)
2174 (match_operand 1 "" "")))]
2175 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2176 "add %0,%0\;bcs %1"
2177 [(set_attr "cc" "clobber")])
2178
2179 (define_peephole
2180 [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2181 (set (pc) (if_then_else (lt (cc0) (const_int 0))
2182 (pc)
2183 (match_operand 1 "" "")))]
2184 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2185 "add %0,%0\;bcc %1"
2186 [(set_attr "cc" "clobber")])
2187