1 ;; GCC machine description for Matsushita MN10300
2 ;; Copyright (C) 1996, 1997, 1998 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" "=d,*a,d,*a,d,*a,d,*a,d,m")
60 (match_operand:QI 1 "general_operand" "0,0,I,I,a,d,di,ia,m,d"))]
61 "register_operand (operands[0], QImode)
62 || register_operand (operands[1], QImode)"
65 switch (which_alternative)
77 xoperands[0] = operands[0];
78 xoperands[1] = zero_areg;
79 if (rtx_equal_p (xoperands[0], xoperands[1]))
80 output_asm_insn (\"sub %1,%0\", xoperands);
82 output_asm_insn (\"mov %1,%0\", xoperands);
94 return \"movbu %1,%0\";
97 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
101 (define_expand "movhi"
102 [(set (match_operand:HI 0 "general_operand" "")
103 (match_operand:HI 1 "general_operand" ""))]
107 /* One of the ops has to be in a register */
108 if (!register_operand (operand1, HImode)
109 && !register_operand (operand0, HImode))
110 operands[1] = copy_to_mode_reg (HImode, operand1);
114 [(set (match_operand:HI 0 "general_operand" "=d,*a,d,*a,d,*a,d,*a,d,m")
115 (match_operand:HI 1 "general_operand" "0,0,I,I,a,d,di,ia,m,d"))]
116 "register_operand (operands[0], HImode)
117 || register_operand (operands[1], HImode)"
120 switch (which_alternative)
132 xoperands[0] = operands[0];
133 xoperands[1] = zero_areg;
134 if (rtx_equal_p (xoperands[0], xoperands[1]))
135 output_asm_insn (\"sub %1,%0\", xoperands);
137 output_asm_insn (\"mov %1,%0\", xoperands);
146 return \"mov %1,%0\";
149 return \"movhu %1,%0\";
152 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
156 ;; We use this to handle addition of two values when one operand is the
157 ;; stack pointer and the other is a memory reference of some kind. Reload
158 ;; does not handle them correctly without this expander.
159 (define_expand "reload_insi"
160 [(set (match_operand:SI 0 "register_operand" "=a")
161 (match_operand:SI 1 "impossible_plus_operand" ""))
162 (clobber (match_operand:SI 2 "register_operand" "=&r"))]
166 if (XEXP (operands[1], 0) == stack_pointer_rtx)
168 emit_move_insn (operands[0], XEXP (operands[1], 0));
169 if (GET_CODE (XEXP (operands[1], 1)) == SUBREG
170 && (GET_MODE_SIZE (GET_MODE (XEXP (operands[1], 1)))
171 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (operands[1], 1))))))
172 emit_move_insn (operands[2],
174 (GET_MODE (XEXP (operands[1], 1)),
175 SUBREG_REG (XEXP (operands[1], 1))));
177 emit_move_insn (operands[2], XEXP (operands[1], 1));
181 emit_move_insn (operands[0], XEXP (operands[1], 1));
182 if (GET_CODE (XEXP (operands[1], 0)) == SUBREG
183 && (GET_MODE_SIZE (GET_MODE (XEXP (operands[1], 0)))
184 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (operands[1], 0))))))
185 emit_move_insn (operands[2],
187 (GET_MODE (XEXP (operands[1], 0)),
188 SUBREG_REG (XEXP (operands[1], 0))));
190 emit_move_insn (operands[2], XEXP (operands[1], 0));
192 emit_insn (gen_addsi3 (operands[0], operands[0], operands[2]));
196 (define_expand "movsi"
197 [(set (match_operand:SI 0 "general_operand" "")
198 (match_operand:SI 1 "general_operand" ""))]
202 /* One of the ops has to be in a register */
203 if (!register_operand (operand1, SImode)
204 && !register_operand (operand0, SImode))
205 operands[1] = copy_to_mode_reg (SImode, operand1);
209 [(set (match_operand:SI 0 "general_operand"
210 "=d,a,d,a,dm,dm,am,am,d,d,a,a,aR,x")
211 (match_operand:SI 1 "general_operand"
212 "0,0,I,I,d,a,d,a,dim,aim,dim,aim,x,aR"))]
213 "register_operand (operands[0], SImode)
214 || register_operand (operands[1], SImode)"
217 switch (which_alternative)
229 xoperands[0] = operands[0];
230 xoperands[1] = zero_areg;
231 if (rtx_equal_p (xoperands[0], xoperands[1]))
232 output_asm_insn (\"sub %1,%0\", xoperands);
234 output_asm_insn (\"mov %1,%0\", xoperands);
249 return \"mov %1,%0\";
252 [(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")])
254 (define_expand "movsf"
255 [(set (match_operand:SF 0 "general_operand" "")
256 (match_operand:SF 1 "general_operand" ""))]
260 /* One of the ops has to be in a register */
261 if (!register_operand (operand1, SFmode)
262 && !register_operand (operand0, SFmode))
263 operands[1] = copy_to_mode_reg (SFmode, operand1);
267 [(set (match_operand:SF 0 "general_operand" "=d,a,d,a,dam,da")
268 (match_operand:SF 1 "general_operand" "0,0,G,G,da,daim"))]
269 "register_operand (operands[0], SFmode)
270 || register_operand (operands[1], SFmode)"
273 switch (which_alternative)
285 xoperands[0] = operands[0];
286 xoperands[1] = zero_areg;
287 if (rtx_equal_p (xoperands[0], xoperands[1]))
288 output_asm_insn (\"sub %1,%0\", xoperands);
290 output_asm_insn (\"mov %1,%0\", xoperands);
297 return \"mov %1,%0\";
300 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit")])
302 (define_expand "movdi"
303 [(set (match_operand:DI 0 "general_operand" "")
304 (match_operand:DI 1 "general_operand" ""))]
308 /* One of the ops has to be in a register */
309 if (!register_operand (operand1, DImode)
310 && !register_operand (operand0, DImode))
311 operands[1] = copy_to_mode_reg (DImode, operand1);
315 [(set (match_operand:DI 0 "general_operand"
316 "=d,a,d,a,dm,dm,am,am,d,d,a,a")
317 (match_operand:DI 1 "general_operand"
318 "0,0,I,I,d,a,d,a,dim,aim,dim,aim"))]
319 "register_operand (operands[0], DImode)
320 || register_operand (operands[1], DImode)"
326 switch (which_alternative)
333 return \"clr %L0\;clr %H0\";
339 xoperands[0] = operands[0];
340 xoperands[1] = zero_areg ? zero_areg : operands[1];
341 if (rtx_equal_p (xoperands[0], xoperands[1]))
342 output_asm_insn (\"sub %L1,%L0\;mov %L0,%H0\", xoperands);
344 output_asm_insn (\"mov %1,%L0\;mov %L0,%H0\", xoperands);
355 if (GET_CODE (operands[1]) == CONST_INT)
357 val[0] = INTVAL (operands[1]);
358 val[1] = val[0] < 0 ? -1 : 0;
360 if (GET_CODE (operands[1]) == CONST_DOUBLE)
362 if (GET_MODE (operands[1]) == DFmode)
364 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
365 REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
367 else if (GET_MODE (operands[1]) == VOIDmode
368 || GET_MODE (operands[1]) == DImode)
370 val[0] = CONST_DOUBLE_LOW (operands[1]);
371 val[1] = CONST_DOUBLE_HIGH (operands[1]);
375 if (GET_CODE (operands[1]) == MEM
376 && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
378 rtx temp = operands[0];
380 while (GET_CODE (temp) == SUBREG)
381 temp = SUBREG_REG (temp);
383 if (GET_CODE (temp) != REG)
386 if (reg_overlap_mentioned_p (gen_rtx_REG (SImode, REGNO (temp)),
387 XEXP (operands[1], 0)))
388 return \"mov %H1,%H0\;mov %L1,%L0\";
390 return \"mov %L1,%L0\;mov %H1,%H0\";
393 else if (GET_CODE (operands[1]) == MEM
394 && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
395 && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
399 xoperands[0] = operands[0];
400 xoperands[1] = XEXP (operands[1], 0);
402 output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\",
408 if ((GET_CODE (operands[1]) == CONST_INT
409 || GET_CODE (operands[1]) == CONST_DOUBLE)
412 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
413 output_asm_insn (\"clr %L0\", operands);
418 xoperands[0] = operands[0];
419 xoperands[1] = zero_areg;
420 if (rtx_equal_p (xoperands[0], xoperands[1]))
421 output_asm_insn (\"sub %L0,%L0\", xoperands);
423 output_asm_insn (\"mov %1,%L0\", xoperands);
426 output_asm_insn (\"mov %L1,%L0\", operands);
429 output_asm_insn (\"mov %L1,%L0\", operands);
431 if ((GET_CODE (operands[1]) == CONST_INT
432 || GET_CODE (operands[1]) == CONST_DOUBLE)
435 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
436 output_asm_insn (\"clr %H0\", operands);
441 xoperands[0] = operands[0];
442 xoperands[1] = zero_areg;
443 if (rtx_equal_p (xoperands[0], xoperands[1]))
444 output_asm_insn (\"sub %H0,%H0\", xoperands);
446 output_asm_insn (\"mov %1,%H0\", xoperands);
449 output_asm_insn (\"mov %H1,%H0\", operands);
451 else if ((GET_CODE (operands[1]) == CONST_INT
452 || GET_CODE (operands[1]) == CONST_DOUBLE)
454 output_asm_insn (\"mov %L0,%H0\", operands);
456 output_asm_insn (\"mov %H1,%H0\", operands);
461 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
463 (define_expand "movdf"
464 [(set (match_operand:DF 0 "general_operand" "")
465 (match_operand:DF 1 "general_operand" ""))]
469 /* One of the ops has to be in a register */
470 if (!register_operand (operand1, DFmode)
471 && !register_operand (operand0, DFmode))
472 operands[1] = copy_to_mode_reg (DFmode, operand1);
476 [(set (match_operand:DF 0 "general_operand"
477 "=d,a,d,a,dm,dm,am,am,d,d,a,a")
478 (match_operand:DF 1 "general_operand"
479 "0,0,G,G,d,a,d,a,dim,aim,dim,aim"))]
480 "register_operand (operands[0], DFmode)
481 || register_operand (operands[1], DFmode)"
487 switch (which_alternative)
494 return \"clr %L0\;clr %H0\";
500 xoperands[0] = operands[0];
501 xoperands[1] = zero_areg ? zero_areg : operands[1];
502 if (rtx_equal_p (xoperands[0], xoperands[1]))
503 output_asm_insn (\"sub %L1,%L0\;mov %L0,%H0\", xoperands);
505 output_asm_insn (\"mov %1,%L0\;mov %L0,%H0\", xoperands);
516 if (GET_CODE (operands[1]) == CONST_INT)
518 val[0] = INTVAL (operands[1]);
519 val[1] = val[0] < 0 ? -1 : 0;
521 if (GET_CODE (operands[1]) == CONST_DOUBLE)
523 if (GET_MODE (operands[1]) == DFmode)
525 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
526 REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
528 else if (GET_MODE (operands[1]) == VOIDmode
529 || GET_MODE (operands[1]) == DImode)
531 val[0] = CONST_DOUBLE_LOW (operands[1]);
532 val[1] = CONST_DOUBLE_HIGH (operands[1]);
536 if (GET_CODE (operands[1]) == MEM
537 && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
539 rtx temp = operands[0];
541 while (GET_CODE (temp) == SUBREG)
542 temp = SUBREG_REG (temp);
544 if (GET_CODE (temp) != REG)
547 if (reg_overlap_mentioned_p (gen_rtx_REG (SImode, REGNO (temp)),
548 XEXP (operands[1], 0)))
549 return \"mov %H1,%H0\;mov %L1,%L0\";
551 return \"mov %L1,%L0\;mov %H1,%H0\";
554 else if (GET_CODE (operands[1]) == MEM
555 && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
556 && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
560 xoperands[0] = operands[0];
561 xoperands[1] = XEXP (operands[1], 0);
563 output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\",
569 if ((GET_CODE (operands[1]) == CONST_INT
570 || GET_CODE (operands[1]) == CONST_DOUBLE)
573 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
574 output_asm_insn (\"clr %L0\", operands);
579 xoperands[0] = operands[0];
580 xoperands[1] = zero_areg;
581 if (rtx_equal_p (xoperands[0], xoperands[1]))
582 output_asm_insn (\"sub %L0,%L0\", xoperands);
584 output_asm_insn (\"mov %1,%L0\", xoperands);
587 output_asm_insn (\"mov %L1,%L0\", operands);
590 output_asm_insn (\"mov %L1,%L0\", operands);
592 if ((GET_CODE (operands[1]) == CONST_INT
593 || GET_CODE (operands[1]) == CONST_DOUBLE)
596 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
597 output_asm_insn (\"clr %H0\", operands);
602 xoperands[0] = operands[0];
603 xoperands[1] = zero_areg;
604 if (rtx_equal_p (xoperands[0], xoperands[1]))
605 output_asm_insn (\"sub %H0,%H0\", xoperands);
607 output_asm_insn (\"mov %1,%H0\", xoperands);
610 output_asm_insn (\"mov %H1,%H0\", operands);
612 else if ((GET_CODE (operands[1]) == CONST_INT
613 || GET_CODE (operands[1]) == CONST_DOUBLE)
615 output_asm_insn (\"mov %L0,%H0\", operands);
617 output_asm_insn (\"mov %H1,%H0\", operands);
622 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
626 ;; ----------------------------------------------------------------------
628 ;; ----------------------------------------------------------------------
630 ;; Go ahead and define tstsi so we can eliminate redundant tst insns
631 ;; when we start trying to optimize this port.
633 [(set (cc0) (match_operand:SI 0 "register_operand" "da"))]
635 "* return output_tst (operands[0], insn);"
636 [(set_attr "cc" "set_znv")])
639 [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "d")))]
641 "* return output_tst (operands[0], insn);"
642 [(set_attr "cc" "set_znv")])
645 [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "d")))]
647 "* return output_tst (operands[0], insn);"
648 [(set_attr "cc" "set_znv")])
653 (compare (match_operand:SI 0 "register_operand" "!*d*a,da")
654 (match_operand:SI 1 "nonmemory_operand" "!*0,dai")))]
659 [(set_attr "cc" "invert,compare")])
661 ;; ----------------------------------------------------------------------
663 ;; ----------------------------------------------------------------------
665 (define_expand "addsi3"
666 [(set (match_operand:SI 0 "register_operand" "")
667 (plus:SI (match_operand:SI 1 "register_operand" "")
668 (match_operand:SI 2 "nonmemory_operand" "")))]
672 /* We can't add a variable amount directly to the stack pointer;
673 so do so via a temporary register. */
674 if (operands[0] == stack_pointer_rtx
675 && GET_CODE (operands[1]) != CONST_INT
676 && GET_CODE (operands[2]) != CONST_INT)
678 rtx temp = gen_reg_rtx (SImode);
679 emit_move_insn (temp, gen_rtx_PLUS (SImode, operands[1], operands[2]));
680 emit_move_insn (operands[0], temp);
686 [(set (match_operand:SI 0 "register_operand" "=d,a,a,da,x,&!da")
687 (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,da")
688 (match_operand:SI 2 "nonmemory_operand" "J,J,L,dai,i,da")))]
696 mov %2,%0\;add %1,%0"
697 [(set_attr "cc" "set_zn,none_0hit,none_0hit,set_zn,none_0hit,set_zn")])
699 ;; ----------------------------------------------------------------------
700 ;; SUBTRACT INSTRUCTIONS
701 ;; ----------------------------------------------------------------------
703 (define_insn "subsi3"
704 [(set (match_operand:SI 0 "register_operand" "=da")
705 (minus:SI (match_operand:SI 1 "register_operand" "0")
706 (match_operand:SI 2 "nonmemory_operand" "dai")))]
709 [(set_attr "cc" "set_zn")])
711 (define_expand "negsi2"
712 [(set (match_operand:SI 0 "register_operand" "")
713 (neg:SI (match_operand:SI 1 "register_operand" "")))]
717 rtx target = gen_reg_rtx (SImode);
719 emit_move_insn (target, GEN_INT (0));
720 emit_insn (gen_subsi3 (target, target, operands[1]));
721 emit_move_insn (operands[0], target);
725 ;; ----------------------------------------------------------------------
726 ;; MULTIPLY INSTRUCTIONS
727 ;; ----------------------------------------------------------------------
729 (define_insn "mulsi3"
730 [(set (match_operand:SI 0 "register_operand" "=d")
731 (mult:SI (match_operand:SI 1 "register_operand" "%0")
732 (match_operand:SI 2 "register_operand" "d")))]
737 return \"nop\;nop\;mul %2,%0\";
739 return \"mul %2,%0\";
741 [(set_attr "cc" "set_zn")])
743 (define_insn "udivmodsi4"
744 [(set (match_operand:SI 0 "general_operand" "=d")
745 (udiv:SI (match_operand:SI 1 "general_operand" "0")
746 (match_operand:SI 2 "general_operand" "d")))
747 (set (match_operand:SI 3 "general_operand" "=&d")
748 (umod:SI (match_dup 1) (match_dup 2)))]
753 output_asm_insn (\"mov %0,mdr\", &zero_dreg);
755 output_asm_insn (\"sub %3,%3\;mov %3,mdr\", operands);
757 if (find_reg_note (insn, REG_UNUSED, operands[3]))
758 return \"divu %2,%0\";
760 return \"divu %2,%0\;mov mdr,%3\";
762 [(set_attr "cc" "set_zn")])
764 (define_insn "divmodsi4"
765 [(set (match_operand:SI 0 "general_operand" "=d")
766 (div:SI (match_operand:SI 1 "general_operand" "0")
767 (match_operand:SI 2 "general_operand" "d")))
768 (set (match_operand:SI 3 "general_operand" "=d")
769 (mod:SI (match_dup 1) (match_dup 2)))]
773 if (find_reg_note (insn, REG_UNUSED, operands[3]))
774 return \"ext %0\;div %2,%0\";
776 return \"ext %0\;div %2,%0\;mov mdr,%3\";
778 [(set_attr "cc" "set_zn")])
781 ;; ----------------------------------------------------------------------
783 ;; ----------------------------------------------------------------------
785 (define_insn "andsi3"
786 [(set (match_operand:SI 0 "register_operand" "=d,d")
787 (and:SI (match_operand:SI 1 "register_operand" "%0,0")
788 (match_operand:SI 2 "nonmemory_operand" "N,di")))]
792 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff)
794 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xffff)
796 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x7fffffff)
797 return \"add %0,%0\;lsr 1,%0\";
798 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x3fffffff)
799 return \"asl2 %0\;lsr 2,%0\";
800 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x1fffffff)
801 return \"add %0,%0\;asl2 %0\;lsr 3,%0\";
802 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x0fffffff)
803 return \"asl2 %0,%0\;asl2 %0\;lsr 4,%0\";
804 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffe)
805 return \"lsr 1,%0\;add %0,%0\";
806 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffc)
807 return \"lsr 2,%0\;asl2 %0\";
808 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff8)
809 return \"lsr 3,%0\;add %0,%0\;asl2 %0\";
810 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff0)
811 return \"lsr 4,%0\;asl2 %0\;asl2 %0\";
812 return \"and %2,%0\";
814 [(set_attr "cc" "none_0hit,set_znv")])
816 ;; ----------------------------------------------------------------------
818 ;; ----------------------------------------------------------------------
820 (define_insn "iorsi3"
821 [(set (match_operand:SI 0 "register_operand" "=d")
822 (ior:SI (match_operand:SI 1 "register_operand" "%0")
823 (match_operand:SI 2 "nonmemory_operand" "di")))]
826 [(set_attr "cc" "set_znv")])
828 ;; ----------------------------------------------------------------------
830 ;; ----------------------------------------------------------------------
832 (define_insn "xorsi3"
833 [(set (match_operand:SI 0 "register_operand" "=d")
834 (xor:SI (match_operand:SI 1 "register_operand" "%0")
835 (match_operand:SI 2 "nonmemory_operand" "di")))]
838 [(set_attr "cc" "set_znv")])
840 ;; ----------------------------------------------------------------------
842 ;; ----------------------------------------------------------------------
844 (define_insn "one_cmplsi2"
845 [(set (match_operand:SI 0 "register_operand" "=d")
846 (not:SI (match_operand:SI 1 "register_operand" "0")))]
849 [(set_attr "cc" "set_znv")])
851 ;; -----------------------------------------------------------------
853 ;; -----------------------------------------------------------------
856 ;; These set/clear memory in byte sized chunks.
858 ;; They are no smaller/faster than loading the value into a register
859 ;; and storing the register, but they don't need a scratch register
860 ;; which may allow for better code generation.
862 [(set (match_operand:QI 0 "general_operand" "=R,d") (const_int 0))]
867 [(set_attr "cc" "clobber")])
870 [(set (match_operand:QI 0 "general_operand" "=R,d") (const_int -1))]
875 [(set_attr "cc" "clobber,none_0hit")])
878 [(set (match_operand:QI 0 "general_operand" "=R,d")
880 (and:SI (subreg:SI (match_dup 0) 0)
881 (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
886 [(set_attr "cc" "clobber,set_znv")])
889 [(set (match_operand:QI 0 "general_operand" "=R,d")
891 (ior:SI (subreg:SI (match_dup 0) 0)
892 (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
897 [(set_attr "cc" "clobber,set_znv")])
901 (zero_extract:SI (match_operand:SI 0 "register_operand" "d")
902 (match_operand 1 "const_int_operand" "")
903 (match_operand 2 "const_int_operand" "")))]
907 int len = INTVAL (operands[1]);
908 int bit = INTVAL (operands[2]);
919 xoperands[0] = operands[0];
920 xoperands[1] = GEN_INT (mask);
921 output_asm_insn (\"btst %1,%0\", xoperands);
924 [(set_attr "cc" "set_znv")])
928 (zero_extract:SI (match_operand:QI 0 "general_operand" "R,d")
929 (match_operand 1 "const_int_operand" "")
930 (match_operand 2 "const_int_operand" "")))]
931 "INTVAL (operands[1]) <= 8 && INTVAL (operands[2]) <= 7"
934 int len = INTVAL (operands[1]);
935 int bit = INTVAL (operands[2]);
946 xoperands[0] = operands[0];
947 xoperands[1] = GEN_INT (mask);
948 if (GET_CODE (operands[0]) == REG)
949 output_asm_insn (\"btst %1,%0\", xoperands);
951 output_asm_insn (\"btst %1,%A0\", xoperands);
954 [(set_attr "cc" "set_znv")])
957 [(set (cc0) (and:SI (match_operand:SI 0 "register_operand" "d")
958 (match_operand:SI 1 "const_int_operand" "")))]
961 [(set_attr "cc" "set_znv")])
966 (subreg:SI (match_operand:QI 0 "general_operand" "R,d") 0)
967 (match_operand:SI 1 "const_int_operand" "")))]
972 [(set_attr "cc" "set_znv")])
975 ;; ----------------------------------------------------------------------
977 ;; ----------------------------------------------------------------------
979 ;; Conditional jump instructions
983 (if_then_else (le (cc0)
985 (label_ref (match_operand 0 "" ""))
990 (define_expand "bleu"
992 (if_then_else (leu (cc0)
994 (label_ref (match_operand 0 "" ""))
1001 (if_then_else (ge (cc0)
1003 (label_ref (match_operand 0 "" ""))
1008 (define_expand "bgeu"
1010 (if_then_else (geu (cc0)
1012 (label_ref (match_operand 0 "" ""))
1017 (define_expand "blt"
1019 (if_then_else (lt (cc0)
1021 (label_ref (match_operand 0 "" ""))
1026 (define_expand "bltu"
1028 (if_then_else (ltu (cc0)
1030 (label_ref (match_operand 0 "" ""))
1035 (define_expand "bgt"
1037 (if_then_else (gt (cc0)
1039 (label_ref (match_operand 0 "" ""))
1044 (define_expand "bgtu"
1046 (if_then_else (gtu (cc0)
1048 (label_ref (match_operand 0 "" ""))
1053 (define_expand "beq"
1055 (if_then_else (eq (cc0)
1057 (label_ref (match_operand 0 "" ""))
1062 (define_expand "bne"
1064 (if_then_else (ne (cc0)
1066 (label_ref (match_operand 0 "" ""))
1073 (if_then_else (match_operator 1 "comparison_operator"
1074 [(cc0) (const_int 0)])
1075 (label_ref (match_operand 0 "" ""))
1080 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1081 && (GET_CODE (operands[1]) == GT
1082 || GET_CODE (operands[1]) == GE
1083 || GET_CODE (operands[1]) == LE
1084 || GET_CODE (operands[1]) == LT))
1088 [(set_attr "cc" "none")])
1092 (if_then_else (match_operator 1 "comparison_operator"
1093 [(cc0) (const_int 0)])
1095 (label_ref (match_operand 0 "" ""))))]
1099 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1100 && (GET_CODE (operands[1]) == GT
1101 || GET_CODE (operands[1]) == GE
1102 || GET_CODE (operands[1]) == LE
1103 || GET_CODE (operands[1]) == LT))
1107 [(set_attr "cc" "none")])
1109 ;; Unconditional and other jump instructions.
1113 (label_ref (match_operand 0 "" "")))]
1116 [(set_attr "cc" "none")])
1118 (define_insn "indirect_jump"
1119 [(set (pc) (match_operand:SI 0 "register_operand" "a"))]
1122 [(set_attr "cc" "none")])
1124 (define_insn "tablejump"
1125 [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1126 (use (label_ref (match_operand 1 "" "")))]
1129 [(set_attr "cc" "none")])
1131 ;; Call subroutine with no return value.
1133 (define_expand "call"
1134 [(call (match_operand:QI 0 "general_operand" "")
1135 (match_operand:SI 1 "general_operand" ""))]
1139 if (! call_address_operand (XEXP (operands[0], 0)))
1140 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
1141 emit_call_insn (gen_call_internal (XEXP (operands[0], 0), operands[1]));
1145 (define_insn "call_internal"
1146 [(call (mem:QI (match_operand:SI 0 "call_address_operand" "aS"))
1147 (match_operand:SI 1 "general_operand" "g"))]
1151 if (REG_P (operands[0]))
1152 return \"calls %C0\";
1154 return \"call %C0,[],0\";
1156 [(set_attr "cc" "clobber")])
1158 ;; Call subroutine, returning value in operand 0
1159 ;; (which must be a hard register).
1161 (define_expand "call_value"
1162 [(set (match_operand 0 "" "")
1163 (call (match_operand:QI 1 "general_operand" "")
1164 (match_operand:SI 2 "general_operand" "")))]
1168 if (! call_address_operand (XEXP (operands[1], 0)))
1169 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
1170 emit_call_insn (gen_call_value_internal (operands[0],
1171 XEXP (operands[1], 0),
1176 (define_insn "call_value_internal"
1177 [(set (match_operand 0 "" "=da")
1178 (call (mem:QI (match_operand:SI 1 "call_address_operand" "aS"))
1179 (match_operand:SI 2 "general_operand" "g")))]
1183 if (REG_P (operands[1]))
1184 return \"calls %C1\";
1186 return \"call %C1,[],0\";
1188 [(set_attr "cc" "clobber")])
1190 (define_expand "untyped_call"
1191 [(parallel [(call (match_operand 0 "" "")
1193 (match_operand 1 "" "")
1194 (match_operand 2 "" "")])]
1200 emit_call_insn (gen_call (operands[0], const0_rtx));
1202 for (i = 0; i < XVECLEN (operands[2], 0); i++)
1204 rtx set = XVECEXP (operands[2], 0, i);
1205 emit_move_insn (SET_DEST (set), SET_SRC (set));
1214 [(set_attr "cc" "none")])
1216 ;; ----------------------------------------------------------------------
1217 ;; EXTEND INSTRUCTIONS
1218 ;; ----------------------------------------------------------------------
1220 (define_insn "zero_extendqisi2"
1221 [(set (match_operand:SI 0 "general_operand" "=d,d,d")
1223 (match_operand:QI 1 "general_operand" "0,d,m")))]
1229 [(set_attr "cc" "none_0hit")])
1231 (define_insn "zero_extendhisi2"
1232 [(set (match_operand:SI 0 "general_operand" "=d,d,d")
1234 (match_operand:HI 1 "general_operand" "0,d,m")))]
1240 [(set_attr "cc" "none_0hit")])
1242 ;;- sign extension instructions
1244 (define_insn "extendqisi2"
1245 [(set (match_operand:SI 0 "general_operand" "=d,d")
1247 (match_operand:QI 1 "general_operand" "0,d")))]
1252 [(set_attr "cc" "none_0hit")])
1254 (define_insn "extendhisi2"
1255 [(set (match_operand:SI 0 "general_operand" "=d,d")
1257 (match_operand:HI 1 "general_operand" "0,d")))]
1262 [(set_attr "cc" "none_0hit")])
1264 ;; ----------------------------------------------------------------------
1266 ;; ----------------------------------------------------------------------
1268 (define_insn "ashlsi3"
1269 [(set (match_operand:SI 0 "register_operand" "=da,d,d,d,d")
1271 (match_operand:SI 1 "register_operand" "0,0,0,0,0")
1272 (match_operand:QI 2 "nonmemory_operand" "J,K,M,L,di")))]
1280 [(set_attr "cc" "set_zn")])
1282 (define_insn "lshrsi3"
1283 [(set (match_operand:SI 0 "register_operand" "=d")
1285 (match_operand:SI 1 "register_operand" "0")
1286 (match_operand:QI 2 "nonmemory_operand" "di")))]
1289 [(set_attr "cc" "set_zn")])
1291 (define_insn "ashrsi3"
1292 [(set (match_operand:SI 0 "register_operand" "=d")
1294 (match_operand:SI 1 "register_operand" "0")
1295 (match_operand:QI 2 "nonmemory_operand" "di")))]
1298 [(set_attr "cc" "set_zn")])
1300 ;; ----------------------------------------------------------------------
1301 ;; PROLOGUE/EPILOGUE
1302 ;; ----------------------------------------------------------------------
1303 (define_expand "prologue"
1306 "expand_prologue (); DONE;")
1308 (define_expand "epilogue"
1317 (define_insn "return_internal"
1321 [(set_attr "cc" "clobber")])
1323 ;; This insn restores the callee saved registers and does a return, it
1324 ;; can also deallocate stack space.
1325 (define_insn "return_internal_regs"
1327 (match_operand:SI 0 "const_int_operand" "i")
1330 "ret [d2,d3,a2,a3],%0"
1331 [(set_attr "cc" "clobber")])
1333 (define_insn "store_movm"
1336 "movm [d2,d3,a2,a3],(sp)"
1337 [(set_attr "cc" "clobber")])
1339 (define_insn "return"
1341 "can_use_return_insn ()"
1344 rtx next = next_active_insn (insn);
1347 && GET_CODE (next) == JUMP_INSN
1348 && GET_CODE (PATTERN (next)) == RETURN)
1353 [(set_attr "cc" "clobber")])
1355 ;; Try to combine consecutive updates of the stack pointer (or any
1356 ;; other register for that matter).
1358 [(set (match_operand:SI 0 "register_operand" "=dax")
1359 (plus:SI (match_dup 0)
1360 (match_operand 1 "const_int_operand" "")))
1362 (plus:SI (match_dup 0)
1363 (match_operand 2 "const_int_operand" "")))]
1367 operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]));
1368 return \"add %1,%0\";
1370 [(set_attr "cc" "clobber")])
1373 ;; We had patterns to check eq/ne, but the they don't work because
1374 ;; 0x80000000 + 0x80000000 = 0x0 with a carry out.
1376 ;; The Z flag and C flag would be set, and we have no way to
1377 ;; check for the Z flag set and C flag clear.
1379 ;; This will work on the mn10200 because we can check the ZX flag
1380 ;; if the comparison is in HImode.
1382 [(set (cc0) (match_operand:SI 0 "register_operand" "d"))
1383 (set (pc) (if_then_else (ge (cc0) (const_int 0))
1384 (match_operand 1 "" "")
1386 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1388 [(set_attr "cc" "clobber")])
1391 [(set (cc0) (match_operand:SI 0 "register_operand" "d"))
1392 (set (pc) (if_then_else (lt (cc0) (const_int 0))
1393 (match_operand 1 "" "")
1395 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1397 [(set_attr "cc" "clobber")])
1400 [(set (cc0) (match_operand:SI 0 "register_operand" "d"))
1401 (set (pc) (if_then_else (ge (cc0) (const_int 0))
1403 (match_operand 1 "" "")))]
1404 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1406 [(set_attr "cc" "clobber")])
1409 [(set (cc0) (match_operand:SI 0 "register_operand" "d"))
1410 (set (pc) (if_then_else (lt (cc0) (const_int 0))
1412 (match_operand 1 "" "")))]
1413 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1415 [(set_attr "cc" "clobber")])