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).
5 ;; This file is part of GNU CC.
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)
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.
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.
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
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"))
40 ;; ----------------------------------------------------------------------
42 ;; ----------------------------------------------------------------------
46 (define_expand "movqi"
47 [(set (match_operand:QI 0 "general_operand" "")
48 (match_operand:QI 1 "general_operand" ""))]
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);
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"))]
62 && (register_operand (operands[0], QImode)
63 || register_operand (operands[1], QImode))"
66 switch (which_alternative)
78 if (GET_CODE (operands[1]) == CONST_DOUBLE)
81 xoperands[0] = operands[0];
82 xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
83 output_asm_insn (\"mov %1,%0\", xoperands);
87 if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
88 && GET_CODE (operands[1]) == CONST_INT)
90 HOST_WIDE_INT val = INTVAL (operands[1]);
92 if (((val & 0x80) && ! (val & 0xffffff00))
93 || ((val & 0x800000) && ! (val & 0xff000000)))
94 return \"movu %1,%0\";
99 return \"movbu %1,%0\";
104 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
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)"
113 switch (which_alternative)
125 if (GET_CODE (operands[1]) == CONST_DOUBLE)
128 xoperands[0] = operands[0];
129 xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
130 output_asm_insn (\"mov %1,%0\", xoperands);
134 return \"mov %1,%0\";
137 return \"movbu %1,%0\";
142 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
146 (define_expand "movhi"
147 [(set (match_operand:HI 0 "general_operand" "")
148 (match_operand:HI 1 "general_operand" ""))]
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);
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"))]
162 && (register_operand (operands[0], HImode)
163 || register_operand (operands[1], HImode))"
166 switch (which_alternative)
178 if (GET_CODE (operands[1]) == CONST_DOUBLE)
181 xoperands[0] = operands[0];
182 xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
183 output_asm_insn (\"mov %1,%0\", xoperands);
187 if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
188 && GET_CODE (operands[1]) == CONST_INT)
190 HOST_WIDE_INT val = INTVAL (operands[1]);
192 if (((val & 0x80) && ! (val & 0xffffff00))
193 || ((val & 0x800000) && ! (val & 0xff000000)))
194 return \"movu %1,%0\";
196 return \"mov %1,%0\";
199 return \"movhu %1,%0\";
204 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
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)"
213 switch (which_alternative)
225 if (GET_CODE (operands[1]) == CONST_DOUBLE)
228 xoperands[0] = operands[0];
229 xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
230 output_asm_insn (\"mov %1,%0\", xoperands);
233 return \"mov %1,%0\";
236 return \"movhu %1,%0\";
241 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
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"))]
255 if (XEXP (operands[1], 0) == stack_pointer_rtx)
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],
262 (GET_MODE (XEXP (operands[1], 1)),
263 SUBREG_REG (XEXP (operands[1], 1))));
265 emit_move_insn (operands[2], XEXP (operands[1], 1));
266 emit_move_insn (operands[0], XEXP (operands[1], 0));
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],
275 (GET_MODE (XEXP (operands[1], 0)),
276 SUBREG_REG (XEXP (operands[1], 0))));
278 emit_move_insn (operands[2], XEXP (operands[1], 0));
279 emit_move_insn (operands[0], XEXP (operands[1], 1));
281 emit_insn (gen_addsi3 (operands[0], operands[0], operands[2]));
285 (define_expand "movsi"
286 [(set (match_operand:SI 0 "general_operand" "")
287 (match_operand:SI 1 "general_operand" ""))]
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);
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)"
306 switch (which_alternative)
324 if (GET_CODE (operands[1]) == CONST_DOUBLE)
327 xoperands[0] = operands[0];
328 xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
329 output_asm_insn (\"mov %1,%0\", xoperands);
333 if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
334 && GET_CODE (operands[1]) == CONST_INT)
336 HOST_WIDE_INT val = INTVAL (operands[1]);
338 if (((val & 0x80) && ! (val & 0xffffff00))
339 || ((val & 0x800000) && ! (val & 0xff000000)))
340 return \"movu %1,%0\";
342 return \"mov %1,%0\";
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")])
349 (define_expand "movsf"
350 [(set (match_operand:SF 0 "general_operand" "")
351 (match_operand:SF 1 "general_operand" ""))]
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);
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)"
368 switch (which_alternative)
378 if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
379 && GET_CODE (operands[1]) == CONST_INT)
381 HOST_WIDE_INT val = INTVAL (operands[1]);
383 if (((val & 0x80) && ! (val & 0xffffff00))
384 || ((val & 0x800000) && ! (val & 0xff000000)))
385 return \"movu %1,%0\";
387 return \"mov %1,%0\";
392 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit")])
394 (define_expand "movdi"
395 [(set (match_operand:DI 0 "general_operand" "")
396 (match_operand:DI 1 "general_operand" ""))]
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);
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)"
418 switch (which_alternative)
425 return \"clr %L0\;clr %H0\";
428 if (rtx_equal_p (operands[0], operands[1]))
429 return \"sub %L1,%L0\;mov %L0,%H0\";
431 return \"mov %1,%L0\;mov %L0,%H0\";
440 if (GET_CODE (operands[1]) == CONST_INT)
442 val[0] = INTVAL (operands[1]);
443 val[1] = val[0] < 0 ? -1 : 0;
445 if (GET_CODE (operands[1]) == CONST_DOUBLE)
447 if (GET_MODE (operands[1]) == DFmode)
449 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
450 REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
452 else if (GET_MODE (operands[1]) == VOIDmode
453 || GET_MODE (operands[1]) == DImode)
455 val[0] = CONST_DOUBLE_LOW (operands[1]);
456 val[1] = CONST_DOUBLE_HIGH (operands[1]);
460 if (GET_CODE (operands[1]) == MEM
461 && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
463 rtx temp = operands[0];
465 while (GET_CODE (temp) == SUBREG)
466 temp = SUBREG_REG (temp);
468 if (GET_CODE (temp) != REG)
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\";
475 return \"mov %L1,%L0\;mov %H1,%H0\";
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)
484 xoperands[0] = operands[0];
485 xoperands[1] = XEXP (operands[1], 0);
487 output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\",
493 if ((GET_CODE (operands[1]) == CONST_INT
494 || GET_CODE (operands[1]) == CONST_DOUBLE)
497 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
498 output_asm_insn (\"clr %L0\", operands);
500 output_asm_insn (\"mov %L1,%L0\", operands);
502 else if ((REGNO_REG_CLASS (true_regnum (operands[0]))
504 && (((val[0] & 0x80) && ! (val[0] & 0xffffff00))
505 || ((val[0] & 0x800000) && ! (val[0] & 0xff000000))))
506 output_asm_insn (\"movu %1,%0\", operands);
508 output_asm_insn (\"mov %L1,%L0\", operands);
510 if ((GET_CODE (operands[1]) == CONST_INT
511 || GET_CODE (operands[1]) == CONST_DOUBLE)
514 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
515 output_asm_insn (\"clr %H0\", operands);
517 output_asm_insn (\"mov %H1,%H0\", operands);
519 else if ((GET_CODE (operands[1]) == CONST_INT
520 || GET_CODE (operands[1]) == CONST_DOUBLE)
522 output_asm_insn (\"mov %L0,%H0\", operands);
523 else if ((REGNO_REG_CLASS (true_regnum (operands[0]))
525 && (((val[1] & 0x80) && ! (val[1] & 0xffffff00))
526 || ((val[1] & 0x800000) && ! (val[1] & 0xff000000))))
527 output_asm_insn (\"movu %1,%0\", operands);
529 output_asm_insn (\"mov %H1,%H0\", operands);
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")])
538 (define_expand "movdf"
539 [(set (match_operand:DF 0 "general_operand" "")
540 (match_operand:DF 1 "general_operand" ""))]
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);
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)"
562 switch (which_alternative)
569 return \"clr %L0\;clr %H0\";
572 if (rtx_equal_p (operands[0], operands[1]))
573 return \"sub %L1,%L0\;mov %L0,%H0\";
575 return \"mov %1,%L0\;mov %L0,%H0\";
584 if (GET_CODE (operands[1]) == CONST_INT)
586 val[0] = INTVAL (operands[1]);
587 val[1] = val[0] < 0 ? -1 : 0;
589 if (GET_CODE (operands[1]) == CONST_DOUBLE)
591 if (GET_MODE (operands[1]) == DFmode)
593 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
594 REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
596 else if (GET_MODE (operands[1]) == VOIDmode
597 || GET_MODE (operands[1]) == DImode)
599 val[0] = CONST_DOUBLE_LOW (operands[1]);
600 val[1] = CONST_DOUBLE_HIGH (operands[1]);
604 if (GET_CODE (operands[1]) == MEM
605 && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
607 rtx temp = operands[0];
609 while (GET_CODE (temp) == SUBREG)
610 temp = SUBREG_REG (temp);
612 if (GET_CODE (temp) != REG)
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\";
619 return \"mov %L1,%L0\;mov %H1,%H0\";
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)
628 xoperands[0] = operands[0];
629 xoperands[1] = XEXP (operands[1], 0);
631 output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\",
637 if ((GET_CODE (operands[1]) == CONST_INT
638 || GET_CODE (operands[1]) == CONST_DOUBLE)
641 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
642 output_asm_insn (\"clr %L0\", operands);
644 output_asm_insn (\"mov %L1,%L0\", operands);
646 else if ((REGNO_REG_CLASS (true_regnum (operands[0]))
648 && (((val[0] & 0x80) && ! (val[0] & 0xffffff00))
649 || ((val[0] & 0x800000) && ! (val[0] & 0xff000000))))
650 output_asm_insn (\"movu %1,%0\", operands);
652 output_asm_insn (\"mov %L1,%L0\", operands);
654 if ((GET_CODE (operands[1]) == CONST_INT
655 || GET_CODE (operands[1]) == CONST_DOUBLE)
658 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
659 output_asm_insn (\"clr %H0\", operands);
661 output_asm_insn (\"mov %H1,%H0\", operands);
663 else if ((GET_CODE (operands[1]) == CONST_INT
664 || GET_CODE (operands[1]) == CONST_DOUBLE)
666 output_asm_insn (\"mov %L0,%H0\", operands);
667 else if ((REGNO_REG_CLASS (true_regnum (operands[0]))
669 && (((val[1] & 0x80) && ! (val[1] & 0xffffff00))
670 || ((val[1] & 0x800000) && ! (val[1] & 0xff000000))))
671 output_asm_insn (\"movu %1,%0\", operands);
673 output_asm_insn (\"mov %H1,%H0\", operands);
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")])
684 ;; ----------------------------------------------------------------------
686 ;; ----------------------------------------------------------------------
688 ;; Go ahead and define tstsi so we can eliminate redundant tst insns
689 ;; when we start trying to optimize this port.
691 [(set (cc0) (match_operand:SI 0 "register_operand" "dax"))]
693 "* return output_tst (operands[0], insn);"
694 [(set_attr "cc" "set_znv")])
697 [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "dx,!a")))]
699 "* return output_tst (operands[0], insn);"
700 [(set_attr "cc" "set_znv")])
703 [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "dx")))]
705 "* return output_tst (operands[0], insn);"
706 [(set_attr "cc" "set_znv")])
709 [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "dx,!a")))]
711 "* return output_tst (operands[0], insn);"
712 [(set_attr "cc" "set_znv")])
715 [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "dx")))]
717 "* return output_tst (operands[0], insn);"
718 [(set_attr "cc" "set_znv")])
722 (compare (match_operand:SI 0 "register_operand" "!*d*a*x,dax")
723 (match_operand:SI 1 "nonmemory_operand" "!*0,daxi")))]
728 [(set_attr "cc" "invert,compare")])
730 ;; ----------------------------------------------------------------------
732 ;; ----------------------------------------------------------------------
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" "")))]
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)
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);
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")))]
761 switch (which_alternative)
770 return \"add %2,%0\";
773 enum reg_class src1_class, src2_class, dst_class;
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]));
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\";
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)
792 /* We have to copy one of the sources into the destination, then
793 add the other source to the destination.
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\";
805 /* At least one register is an extended register. */
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\";
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
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\";
830 [(set_attr "cc" "set_zn,none_0hit,none_0hit,set_zn,none_0hit,set_zn")])
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")))]
839 switch (which_alternative)
848 return \"add %2,%0\";
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\";
857 /* We have to copy one of the sources into the destination, then add
858 the other source to the destination.
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\";
872 [(set_attr "cc" "set_zn,none_0hit,none_0hit,set_zn,none_0hit,set_zn")])
874 ;; ----------------------------------------------------------------------
875 ;; SUBTRACT INSTRUCTIONS
876 ;; ----------------------------------------------------------------------
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" "")))]
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")))]
892 if (true_regnum (operands[0]) == true_regnum (operands[1]))
893 return \"sub %2,%0\";
896 enum reg_class src1_class, src2_class, dst_class;
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]));
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\";
913 [(set_attr "cc" "set_zn")])
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")))]
921 [(set_attr "cc" "set_zn")])
923 (define_expand "negsi2"
924 [(set (match_operand:SI 0 "register_operand" "")
925 (neg:SI (match_operand:SI 1 "register_operand" "")))]
929 rtx target = gen_reg_rtx (SImode);
931 emit_move_insn (target, GEN_INT (0));
932 emit_insn (gen_subsi3 (target, target, operands[1]));
933 emit_move_insn (operands[0], target);
937 ;; ----------------------------------------------------------------------
938 ;; MULTIPLY INSTRUCTIONS
939 ;; ----------------------------------------------------------------------
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"))))]
947 [(set_attr "cc" "set_zn")])
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"))))]
955 [(set_attr "cc" "set_zn")])
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" "")))]
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")))]
972 return \"nop\;nop\;mul %2,%0\";
974 return \"mul %2,%0\";
976 [(set_attr "cc" "set_zn")])
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")))]
986 return \"nop\;nop\;mul %2,%0\";
988 return \"mul %2,%0\";
990 [(set_attr "cc" "set_zn")])
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)))]
1001 output_asm_insn (\"sub %3,%3\;mov %3,mdr\", operands);
1003 if (find_reg_note (insn, REG_UNUSED, operands[3]))
1004 return \"divu %2,%0\";
1006 return \"divu %2,%0\;mov mdr,%3\";
1008 [(set_attr "cc" "set_zn")])
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)))]
1019 if (find_reg_note (insn, REG_UNUSED, operands[3]))
1020 return \"ext %0\;div %2,%0\";
1022 return \"ext %0\;div %2,%0\;mov mdr,%3\";
1024 [(set_attr "cc" "set_zn")])
1027 ;; ----------------------------------------------------------------------
1029 ;; ----------------------------------------------------------------------
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" "")))]
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")))]
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\";
1081 [(set_attr "cc" "none_0hit,set_znv,set_znv")])
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")))]
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\";
1112 [(set_attr "cc" "none_0hit,set_znv")])
1114 ;; ----------------------------------------------------------------------
1116 ;; ----------------------------------------------------------------------
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" "")))]
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")))]
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\";
1148 [(set_attr "cc" "set_znv")])
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")))]
1156 [(set_attr "cc" "set_znv")])
1158 ;; ----------------------------------------------------------------------
1160 ;; ----------------------------------------------------------------------
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" "")))]
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")))]
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\";
1192 [(set_attr "cc" "set_znv")])
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")))]
1200 [(set_attr "cc" "set_znv")])
1202 ;; ----------------------------------------------------------------------
1204 ;; ----------------------------------------------------------------------
1206 (define_expand "one_cmplsi2"
1207 [(set (match_operand:SI 0 "register_operand" "")
1208 (not:SI (match_operand:SI 1 "register_operand" "")))]
1213 [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1214 (not:SI (match_operand:SI 1 "register_operand" "0,0")))]
1217 [(set_attr "cc" "set_znv")])
1220 [(set (match_operand:SI 0 "register_operand" "=dx")
1221 (not:SI (match_operand:SI 1 "register_operand" "0")))]
1224 [(set_attr "cc" "set_znv")])
1226 ;; -----------------------------------------------------------------
1228 ;; -----------------------------------------------------------------
1231 ;; These set/clear memory in byte sized chunks.
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.
1237 [(set (match_operand:QI 0 "general_operand" "=R,d") (const_int 0))]
1242 [(set_attr "cc" "clobber")])
1245 [(set (match_operand:QI 0 "general_operand" "=R,d") (const_int -1))]
1250 [(set_attr "cc" "clobber,none_0hit")])
1253 [(set (match_operand:QI 0 "general_operand" "+R,d")
1255 (and:SI (subreg:SI (match_dup 0) 0)
1256 (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
1261 [(set_attr "cc" "clobber,set_znv")])
1264 [(set (match_operand:QI 0 "general_operand" "+R,d")
1266 (ior:SI (subreg:SI (match_dup 0) 0)
1267 (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
1272 [(set_attr "cc" "clobber,set_znv")])
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" "")))]
1282 int len = INTVAL (operands[1]);
1283 int bit = INTVAL (operands[2]);
1294 xoperands[0] = operands[0];
1295 xoperands[1] = GEN_INT (mask);
1296 output_asm_insn (\"btst %1,%0\", xoperands);
1299 [(set_attr "cc" "clobber")])
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]))"
1309 int len = INTVAL (operands[1]);
1310 int bit = INTVAL (operands[2]);
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]))
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;
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);
1341 output_asm_insn (\"btst %1,%A0\", xoperands);
1344 [(set_attr "cc" "clobber")])
1347 [(set (cc0) (and:SI (match_operand:SI 0 "register_operand" "dx")
1348 (match_operand:SI 1 "const_int_operand" "")))]
1351 [(set_attr "cc" "clobber")])
1356 (subreg:SI (match_operand:QI 0 "general_operand" "R,dx") 0)
1357 (match_operand:SI 1 "const_8bit_operand" "")))]
1362 [(set_attr "cc" "clobber")])
1365 ;; ----------------------------------------------------------------------
1366 ;; JUMP INSTRUCTIONS
1367 ;; ----------------------------------------------------------------------
1369 ;; Conditional jump instructions
1371 (define_expand "ble"
1373 (if_then_else (le (cc0)
1375 (label_ref (match_operand 0 "" ""))
1380 (define_expand "bleu"
1382 (if_then_else (leu (cc0)
1384 (label_ref (match_operand 0 "" ""))
1389 (define_expand "bge"
1391 (if_then_else (ge (cc0)
1393 (label_ref (match_operand 0 "" ""))
1398 (define_expand "bgeu"
1400 (if_then_else (geu (cc0)
1402 (label_ref (match_operand 0 "" ""))
1407 (define_expand "blt"
1409 (if_then_else (lt (cc0)
1411 (label_ref (match_operand 0 "" ""))
1416 (define_expand "bltu"
1418 (if_then_else (ltu (cc0)
1420 (label_ref (match_operand 0 "" ""))
1425 (define_expand "bgt"
1427 (if_then_else (gt (cc0)
1429 (label_ref (match_operand 0 "" ""))
1434 (define_expand "bgtu"
1436 (if_then_else (gtu (cc0)
1438 (label_ref (match_operand 0 "" ""))
1443 (define_expand "beq"
1445 (if_then_else (eq (cc0)
1447 (label_ref (match_operand 0 "" ""))
1452 (define_expand "bne"
1454 (if_then_else (ne (cc0)
1456 (label_ref (match_operand 0 "" ""))
1463 (if_then_else (match_operator 1 "comparison_operator"
1464 [(cc0) (const_int 0)])
1465 (label_ref (match_operand 0 "" ""))
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))
1478 [(set_attr "cc" "none")])
1482 (if_then_else (match_operator 1 "comparison_operator"
1483 [(cc0) (const_int 0)])
1485 (label_ref (match_operand 0 "" ""))))]
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))
1497 [(set_attr "cc" "none")])
1499 ;; Unconditional and other jump instructions.
1503 (label_ref (match_operand 0 "" "")))]
1506 [(set_attr "cc" "none")])
1508 (define_insn "indirect_jump"
1509 [(set (pc) (match_operand:SI 0 "register_operand" "a"))]
1512 [(set_attr "cc" "none")])
1514 (define_insn "tablejump"
1515 [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1516 (use (label_ref (match_operand 1 "" "")))]
1519 [(set_attr "cc" "none")])
1521 ;; Call subroutine with no return value.
1523 (define_expand "call"
1524 [(call (match_operand:QI 0 "general_operand" "")
1525 (match_operand:SI 1 "general_operand" ""))]
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]));
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"))]
1541 if (REG_P (operands[0]))
1542 return \"calls %C0\";
1544 return \"call %C0,[],0\";
1546 [(set_attr "cc" "clobber")])
1548 ;; Call subroutine, returning value in operand 0
1549 ;; (which must be a hard register).
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" "")))]
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),
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")))]
1573 if (REG_P (operands[1]))
1574 return \"calls %C1\";
1576 return \"call %C1,[],0\";
1578 [(set_attr "cc" "clobber")])
1580 (define_expand "untyped_call"
1581 [(parallel [(call (match_operand 0 "" "")
1583 (match_operand 1 "" "")
1584 (match_operand 2 "" "")])]
1590 emit_call_insn (gen_call (operands[0], const0_rtx));
1592 for (i = 0; i < XVECLEN (operands[2], 0); i++)
1594 rtx set = XVECEXP (operands[2], 0, i);
1595 emit_move_insn (SET_DEST (set), SET_SRC (set));
1604 [(set_attr "cc" "none")])
1606 ;; ----------------------------------------------------------------------
1607 ;; EXTEND INSTRUCTIONS
1608 ;; ----------------------------------------------------------------------
1610 (define_expand "zero_extendqisi2"
1611 [(set (match_operand:SI 0 "general_operand" "")
1613 (match_operand:QI 1 "general_operand" "")))]
1618 [(set (match_operand:SI 0 "general_operand" "=dx,dx,dx,!dax,!dax,!dax")
1620 (match_operand:QI 1 "general_operand" "0,dax,m,0,dax,m")))]
1629 [(set_attr "cc" "none_0hit")])
1632 [(set (match_operand:SI 0 "general_operand" "=dx,dx,dx")
1634 (match_operand:QI 1 "general_operand" "0,d,m")))]
1640 [(set_attr "cc" "none_0hit")])
1642 (define_expand "zero_extendhisi2"
1643 [(set (match_operand:SI 0 "general_operand" "")
1645 (match_operand:HI 1 "general_operand" "")))]
1650 [(set (match_operand:SI 0 "general_operand" "=dx,dx,dx,!dax,!dax,!dax")
1652 (match_operand:HI 1 "general_operand" "0,dax,m,0,dax,m")))]
1661 [(set_attr "cc" "none_0hit")])
1664 [(set (match_operand:SI 0 "general_operand" "=dx,dx,dx")
1666 (match_operand:HI 1 "general_operand" "0,dx,m")))]
1672 [(set_attr "cc" "none_0hit")])
1674 ;;- sign extension instructions
1676 (define_expand "extendqisi2"
1677 [(set (match_operand:SI 0 "general_operand" "")
1679 (match_operand:QI 1 "general_operand" "")))]
1684 [(set (match_operand:SI 0 "general_operand" "=dx,dx,!dax,!dax")
1686 (match_operand:QI 1 "general_operand" "0,dx,0,dax")))]
1693 [(set_attr "cc" "none_0hit")])
1696 [(set (match_operand:SI 0 "general_operand" "=dx,dx")
1698 (match_operand:QI 1 "general_operand" "0,dx")))]
1703 [(set_attr "cc" "none_0hit")])
1705 (define_expand "extendhisi2"
1706 [(set (match_operand:SI 0 "general_operand" "")
1708 (match_operand:HI 1 "general_operand" "")))]
1713 [(set (match_operand:SI 0 "general_operand" "=dx,dx,!dax,!dax")
1715 (match_operand:HI 1 "general_operand" "0,dax,0,dax")))]
1722 [(set_attr "cc" "none_0hit")])
1725 [(set (match_operand:SI 0 "general_operand" "=dx,dx")
1727 (match_operand:HI 1 "general_operand" "0,dx")))]
1732 [(set_attr "cc" "none_0hit")])
1734 ;; ----------------------------------------------------------------------
1736 ;; ----------------------------------------------------------------------
1738 (define_expand "ashlsi3"
1739 [(set (match_operand:SI 0 "register_operand" "")
1741 (match_operand:SI 1 "register_operand" "")
1742 (match_operand:QI 2 "nonmemory_operand" "")))]
1747 [(set (match_operand:SI 0 "register_operand" "=dax,dx,!dax")
1749 (match_operand:SI 1 "register_operand" "0,0,dax")
1750 (match_operand:QI 2 "nonmemory_operand" "J,dxi,dax")))]
1754 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 1)
1755 return \"add %0,%0\";
1757 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 2)
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\";
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\";
1768 if (true_regnum (operands[1]) == true_regnum (operands[0]))
1769 return \"asl %S2,%0\";
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\";
1777 [(set_attr "cc" "set_zn")])
1780 [(set (match_operand:SI 0 "register_operand" "=dax,dx,dx,dx,dx")
1782 (match_operand:SI 1 "register_operand" "0,0,0,0,0")
1783 (match_operand:QI 2 "nonmemory_operand" "J,K,M,L,dxi")))]
1791 [(set_attr "cc" "set_zn")])
1793 (define_expand "lshrsi3"
1794 [(set (match_operand:SI 0 "register_operand" "")
1796 (match_operand:SI 1 "register_operand" "")
1797 (match_operand:QI 2 "nonmemory_operand" "")))]
1802 [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1804 (match_operand:SI 1 "register_operand" "0,dax")
1805 (match_operand:QI 2 "nonmemory_operand" "dxi,dax")))]
1809 if (true_regnum (operands[1]) == true_regnum (operands[0]))
1810 return \"lsr %S2,%0\";
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\";
1818 [(set_attr "cc" "set_zn")])
1821 [(set (match_operand:SI 0 "register_operand" "=dx")
1823 (match_operand:SI 1 "register_operand" "0")
1824 (match_operand:QI 2 "nonmemory_operand" "dxi")))]
1827 [(set_attr "cc" "set_zn")])
1829 (define_expand "ashrsi3"
1830 [(set (match_operand:SI 0 "register_operand" "")
1832 (match_operand:SI 1 "register_operand" "")
1833 (match_operand:QI 2 "nonmemory_operand" "")))]
1838 [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1840 (match_operand:SI 1 "register_operand" "0,dax")
1841 (match_operand:QI 2 "nonmemory_operand" "dxi,dax")))]
1845 if (true_regnum (operands[1]) == true_regnum (operands[0]))
1846 return \"asr %S2,%0\";
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\";
1854 [(set_attr "cc" "set_zn")])
1857 [(set (match_operand:SI 0 "register_operand" "=dx")
1859 (match_operand:SI 1 "register_operand" "0")
1860 (match_operand:QI 2 "nonmemory_operand" "dxi")))]
1863 [(set_attr "cc" "set_zn")])
1865 ;; ----------------------------------------------------------------------
1867 ;; ----------------------------------------------------------------------
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.
1873 ;; Similarly for negation of a FP value.
1876 (define_expand "absdf2"
1877 [(set (match_operand:DF 0 "register_operand" "")
1878 (abs:DF (match_operand:DF 1 "register_operand" "")))]
1882 rtx target, result, insns;
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);
1893 if (result != target)
1894 emit_move_insn (result, target);
1896 emit_move_insn (operand_subword (operands[0], 0, 1, DFmode),
1897 operand_subword_force (operands[1], 0, DFmode));
1899 insns = get_insns ();
1902 emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
1906 (define_expand "abssf2"
1907 [(set (match_operand:SF 0 "register_operand" "")
1908 (abs:SF (match_operand:SF 1 "register_operand" "")))]
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);
1922 if (result != target)
1923 emit_move_insn (result, target);
1925 /* Make a place for REG_EQUAL. */
1926 emit_move_insn (operands[0], operands[0]);
1931 (define_expand "negdf2"
1932 [(set (match_operand:DF 0 "register_operand" "")
1933 (neg:DF (match_operand:DF 1 "register_operand" "")))]
1937 rtx target, result, insns;
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);
1948 if (result != target)
1949 emit_move_insn (result, target);
1951 emit_move_insn (operand_subword (operands[0], 0, 1, DFmode),
1952 operand_subword_force (operands[1], 0, DFmode));
1954 insns = get_insns ();
1957 emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
1961 (define_expand "negsf2"
1962 [(set (match_operand:SF 0 "register_operand" "")
1963 (neg:SF (match_operand:SF 1 "register_operand" "")))]
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);
1977 if (result != target)
1978 emit_move_insn (result, target);
1980 /* Make a place for REG_EQUAL. */
1981 emit_move_insn (operands[0], operands[0]);
1986 ;; ----------------------------------------------------------------------
1987 ;; PROLOGUE/EPILOGUE
1988 ;; ----------------------------------------------------------------------
1989 (define_expand "prologue"
1992 "expand_prologue (); DONE;")
1994 (define_expand "epilogue"
2003 (define_insn "return_internal"
2008 [(set_attr "cc" "clobber")])
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"
2014 (match_operand:SI 0 "const_int_operand" "i")
2022 fputs (\"\\tret [\", asm_out_file);
2023 if (regs_ever_live[2])
2025 fputs (\"d2\", asm_out_file);
2028 if (regs_ever_live[3])
2031 fputc (',', asm_out_file);
2032 fputs (\"d3\", asm_out_file);
2035 if (regs_ever_live[6])
2038 fputc (',', asm_out_file);
2039 fputs (\"a2\", asm_out_file);
2042 if (regs_ever_live[7])
2045 fputc (',', asm_out_file);
2046 fputs (\"a3\", asm_out_file);
2049 if (regs_ever_live[14] || regs_ever_live[15]
2050 || regs_ever_live[16] || regs_ever_live[17])
2053 fputc (',', asm_out_file);
2054 fputs (\"exreg1\", asm_out_file);
2057 fprintf (asm_out_file, \"],%d\\n\", INTVAL (operands[0]));
2060 [(set_attr "cc" "clobber")])
2062 (define_insn "store_movm"
2070 fputs (\"\\tmovm [\", asm_out_file);
2071 if (regs_ever_live[2])
2073 fputs (\"d2\", asm_out_file);
2076 if (regs_ever_live[3])
2079 fputc (',', asm_out_file);
2080 fputs (\"d3\", asm_out_file);
2083 if (regs_ever_live[6])
2086 fputc (',', asm_out_file);
2087 fputs (\"a2\", asm_out_file);
2090 if (regs_ever_live[7])
2093 fputc (',', asm_out_file);
2094 fputs (\"a3\", asm_out_file);
2097 if (regs_ever_live[14] || regs_ever_live[15]
2098 || regs_ever_live[16] || regs_ever_live[17])
2101 fputc (',', asm_out_file);
2102 fputs (\"exreg1\", asm_out_file);
2105 fputs (\"],(sp)\\n\", asm_out_file);
2108 [(set_attr "cc" "clobber")])
2110 (define_insn "return"
2112 "can_use_return_insn ()"
2115 rtx next = next_active_insn (insn);
2118 && GET_CODE (next) == JUMP_INSN
2119 && GET_CODE (PATTERN (next)) == RETURN)
2124 [(set_attr "cc" "clobber")])
2126 ;; Try to combine consecutive updates of the stack pointer (or any
2127 ;; other register for that matter).
2129 [(set (match_operand:SI 0 "register_operand" "=dxay")
2130 (plus:SI (match_dup 0)
2131 (match_operand 1 "const_int_operand" "")))
2133 (plus:SI (match_dup 0)
2134 (match_operand 2 "const_int_operand" "")))]
2138 operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]));
2139 return \"add %1,%0\";
2141 [(set_attr "cc" "clobber")])
2144 ;; We had patterns to check eq/ne, but the they don't work because
2145 ;; 0x80000000 + 0x80000000 = 0x0 with a carry out.
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.
2150 ;; This will work on the mn10200 because we can check the ZX flag
2151 ;; if the comparison is in HImode.
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 "" "")
2157 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2159 [(set_attr "cc" "clobber")])
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 "" "")
2166 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2168 [(set_attr "cc" "clobber")])
2171 [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2172 (set (pc) (if_then_else (ge (cc0) (const_int 0))
2174 (match_operand 1 "" "")))]
2175 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2177 [(set_attr "cc" "clobber")])
2180 [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2181 (set (pc) (if_then_else (lt (cc0) (const_int 0))
2183 (match_operand 1 "" "")))]
2184 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2186 [(set_attr "cc" "clobber")])