1 ; GCC machine description for Matsushita MN10300
2 ;; Copyright (C) 1996, 1997 Free Software Foundation, Inc.
4 ;; Contributed by Jeff Law (law@cygnus.com).
6 ;; This file is part of GNU CC.
8 ;; GNU CC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; GNU CC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GNU CC; see the file COPYING. If not, write to
20 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
21 ;; Boston, MA 02111-1307, USA.
23 ;; The original PO technology requires these to be ordered by speed,
24 ;; so that assigner will pick the fastest.
26 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;; Condition code settings.
29 ;; none - insn does not affect cc
30 ;; none_0hit - insn does not affect cc but it does modify operand 0
31 ;; This attribute is used to keep track of when operand 0 changes.
32 ;; See the description of NOTICE_UPDATE_CC for more info.
33 ;; set_znv - insn sets z,n,v to useable values; c is unusable.
34 ;; set_zn - insn sets z,n to useable values; v,c are unuseable.
35 ;; compare - compare instruction
36 ;; invert -- like compare, but flags are inverted.
37 ;; clobber - value of cc is unknown
38 (define_attr "cc" "none,none_0hit,set_znv,set_zn,compare,clobber,invert"
39 (const_string "clobber"))
41 ;; ----------------------------------------------------------------------
43 ;; ----------------------------------------------------------------------
47 (define_expand "movqi"
48 [(set (match_operand:QI 0 "general_operand" "")
49 (match_operand:QI 1 "general_operand" ""))]
53 /* One of the ops has to be in a register */
54 if (!register_operand (operand0, QImode)
55 && !register_operand (operand1, QImode))
56 operands[1] = copy_to_mode_reg (QImode, operand1);
60 [(set (match_operand:QI 0 "general_operand" "=d,a,d,a,d,a,d,a,d,m")
61 (match_operand:QI 1 "general_operand" "0,0,I,I,a,d,di,ia,m,d"))]
62 "register_operand (operands[0], QImode)
63 || register_operand (operands[1], QImode)"
66 switch (which_alternative)
78 xoperands[0] = operands[0];
79 xoperands[1] = zero_areg;
80 if (rtx_equal_p (xoperands[0], xoperands[1]))
81 output_asm_insn (\"sub %1,%0\", xoperands);
83 output_asm_insn (\"mov %1,%0\", xoperands);
95 return \"movbu %1,%0\";
98 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
102 (define_expand "movhi"
103 [(set (match_operand:HI 0 "general_operand" "")
104 (match_operand:HI 1 "general_operand" ""))]
108 /* One of the ops has to be in a register */
109 if (!register_operand (operand1, HImode)
110 && !register_operand (operand0, HImode))
111 operands[1] = copy_to_mode_reg (HImode, operand1);
115 [(set (match_operand:HI 0 "general_operand" "=d,a,d,a,d,a,d,a,d,m")
116 (match_operand:HI 1 "general_operand" "0,0,I,I,a,d,di,ia,m,d"))]
117 "register_operand (operands[0], HImode)
118 || register_operand (operands[1], HImode)"
121 switch (which_alternative)
133 xoperands[0] = operands[0];
134 xoperands[1] = zero_areg;
135 if (rtx_equal_p (xoperands[0], xoperands[1]))
136 output_asm_insn (\"sub %1,%0\", xoperands);
138 output_asm_insn (\"mov %1,%0\", xoperands);
147 return \"mov %1,%0\";
150 return \"movhu %1,%0\";
153 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
157 ;; We use this to handle addition of two values when one operand is the
158 ;; stack pointer and the other is a memory reference of some kind. Reload
159 ;; does not handle them correctly without this expander.
160 (define_expand "reload_insi"
161 [(set (match_operand:SI 0 "register_operand" "=a")
162 (match_operand:SI 1 "impossible_plus_operand" ""))
163 (clobber (match_operand:SI 2 "register_operand" "=&r"))]
167 if (XEXP (operands[1], 0) == stack_pointer_rtx)
169 emit_move_insn (operands[0], XEXP (operands[1], 0));
170 if (GET_CODE (XEXP (operands[1], 1)) == SUBREG
171 && (GET_MODE_SIZE (GET_MODE (XEXP (operands[1], 1)))
172 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (operands[1], 1))))))
173 emit_move_insn (operands[2],
174 gen_rtx (ZERO_EXTEND, 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],
186 gen_rtx (ZERO_EXTEND, GET_MODE (XEXP (operands[1], 0)),
187 SUBREG_REG (XEXP (operands[1], 0))));
189 emit_move_insn (operands[2], XEXP (operands[1], 0));
191 emit_insn (gen_addsi3 (operands[0], operands[0], operands[2]));
195 (define_expand "movsi"
196 [(set (match_operand:SI 0 "general_operand" "")
197 (match_operand:SI 1 "general_operand" ""))]
201 /* One of the ops has to be in a register */
202 if (!register_operand (operand1, SImode)
203 && !register_operand (operand0, SImode))
204 operands[1] = copy_to_mode_reg (SImode, operand1);
208 [(set (match_operand:SI 0 "general_operand"
209 "=d,a,d,a,dm,dm,am,am,d,d,a,a,aR,x")
210 (match_operand:SI 1 "general_operand"
211 "0,0,I,I,d,a,d,a,dim,aim,dim,aim,x,aR"))]
212 "register_operand (operands[0], SImode)
213 || register_operand (operands[1], SImode)"
216 switch (which_alternative)
228 xoperands[0] = operands[0];
229 xoperands[1] = zero_areg;
230 if (rtx_equal_p (xoperands[0], xoperands[1]))
231 output_asm_insn (\"sub %1,%0\", xoperands);
233 output_asm_insn (\"mov %1,%0\", xoperands);
248 return \"mov %1,%0\";
251 [(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")])
253 (define_expand "movsf"
254 [(set (match_operand:SF 0 "general_operand" "")
255 (match_operand:SF 1 "general_operand" ""))]
259 /* One of the ops has to be in a register */
260 if (!register_operand (operand1, SFmode)
261 && !register_operand (operand0, SFmode))
262 operands[1] = copy_to_mode_reg (SFmode, operand1);
266 [(set (match_operand:SF 0 "general_operand" "=d,a,d,a,dam,da")
267 (match_operand:SF 1 "general_operand" "0,0,G,G,da,daim"))]
268 "register_operand (operands[0], SFmode)
269 || register_operand (operands[1], SFmode)"
272 switch (which_alternative)
284 xoperands[0] = operands[0];
285 xoperands[1] = zero_areg;
286 if (rtx_equal_p (xoperands[0], xoperands[1]))
287 output_asm_insn (\"sub %1,%0\", xoperands);
289 output_asm_insn (\"mov %1,%0\", xoperands);
296 return \"mov %1,%0\";
299 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit")])
301 (define_expand "movdi"
302 [(set (match_operand:DI 0 "general_operand" "")
303 (match_operand:DI 1 "general_operand" ""))]
307 /* One of the ops has to be in a register */
308 if (!register_operand (operand1, DImode)
309 && !register_operand (operand0, DImode))
310 operands[1] = copy_to_mode_reg (DImode, operand1);
314 [(set (match_operand:DI 0 "general_operand"
315 "=d,a,d,a,dm,dm,am,am,d,d,a,a")
316 (match_operand:DI 1 "general_operand"
317 "0,0,I,I,d,a,d,a,dim,aim,dim,aim"))]
318 "register_operand (operands[0], DImode)
319 || register_operand (operands[1], DImode)"
325 switch (which_alternative)
332 return \"clr %L0\;clr %H0\";
338 xoperands[0] = operands[0];
339 xoperands[1] = zero_areg ? zero_areg : operands[1];
340 if (rtx_equal_p (xoperands[0], xoperands[1]))
341 output_asm_insn (\"sub %L1,%L0\;mov %L0,%H0\", xoperands);
343 output_asm_insn (\"mov %1,%L0\;mov %L0,%H0\", xoperands);
354 if (GET_CODE (operands[1]) == CONST_INT)
356 val[0] = INTVAL (operands[1]);
357 val[1] = val[0] < 0 ? -1 : 0;
359 if (GET_CODE (operands[1]) == CONST_DOUBLE)
361 if (GET_MODE (operands[1]) == DFmode)
363 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
364 REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
366 else if (GET_MODE (operands[1]) == VOIDmode
367 || GET_MODE (operands[1]) == DImode)
369 val[0] = CONST_DOUBLE_LOW (operands[1]);
370 val[1] = CONST_DOUBLE_HIGH (operands[1]);
374 if (GET_CODE (operands[1]) == MEM
375 && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
377 rtx temp = operands[0];
379 while (GET_CODE (temp) == SUBREG)
380 temp = SUBREG_REG (temp);
382 if (GET_CODE (temp) != REG)
385 if (reg_overlap_mentioned_p (gen_rtx (REG, SImode, REGNO (temp)),
386 XEXP (operands[1], 0)))
387 return \"mov %H1,%H0\;mov %L1,%L0\";
389 return \"mov %L1,%L0\;mov %H1,%H0\";
392 else if (GET_CODE (operands[1]) == MEM
393 && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
394 && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
398 xoperands[0] = operands[0];
399 xoperands[1] = XEXP (operands[1], 0);
401 output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\",
407 if ((GET_CODE (operands[1]) == CONST_INT
408 || GET_CODE (operands[1]) == CONST_DOUBLE)
411 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
412 output_asm_insn (\"clr %L0\", operands);
417 xoperands[0] = operands[0];
418 xoperands[1] = zero_areg;
419 if (rtx_equal_p (xoperands[0], xoperands[1]))
420 output_asm_insn (\"sub %L0,%L0\", xoperands);
422 output_asm_insn (\"mov %1,%L0\", xoperands);
425 output_asm_insn (\"mov %L1,%L0\", operands);
428 output_asm_insn (\"mov %L1,%L0\", operands);
430 if ((GET_CODE (operands[1]) == CONST_INT
431 || GET_CODE (operands[1]) == CONST_DOUBLE)
434 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
435 output_asm_insn (\"clr %H0\", operands);
440 xoperands[0] = operands[0];
441 xoperands[1] = zero_areg;
442 if (rtx_equal_p (xoperands[0], xoperands[1]))
443 output_asm_insn (\"sub %H0,%H0\", xoperands);
445 output_asm_insn (\"mov %1,%H0\", xoperands);
448 output_asm_insn (\"mov %H1,%H0\", operands);
450 else if ((GET_CODE (operands[1]) == CONST_INT
451 || GET_CODE (operands[1]) == CONST_DOUBLE)
453 output_asm_insn (\"mov %L0,%H0\", operands);
455 output_asm_insn (\"mov %H1,%H0\", operands);
460 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
462 (define_expand "movdf"
463 [(set (match_operand:DF 0 "general_operand" "")
464 (match_operand:DF 1 "general_operand" ""))]
468 /* One of the ops has to be in a register */
469 if (!register_operand (operand1, DFmode)
470 && !register_operand (operand0, DFmode))
471 operands[1] = copy_to_mode_reg (DFmode, operand1);
475 [(set (match_operand:DF 0 "general_operand"
476 "=d,a,d,a,dm,dm,am,am,d,d,a,a")
477 (match_operand:DF 1 "general_operand"
478 "0,0,G,G,d,a,d,a,dim,aim,dim,aim"))]
479 "register_operand (operands[0], DFmode)
480 || register_operand (operands[1], DFmode)"
486 switch (which_alternative)
493 return \"clr %L0\;clr %H0\";
499 xoperands[0] = operands[0];
500 xoperands[1] = zero_areg ? zero_areg : operands[1];
501 if (rtx_equal_p (xoperands[0], xoperands[1]))
502 output_asm_insn (\"sub %L1,%L0\;mov %L0,%H0\", xoperands);
504 output_asm_insn (\"mov %1,%L0\;mov %L0,%H0\", xoperands);
515 if (GET_CODE (operands[1]) == CONST_INT)
517 val[0] = INTVAL (operands[1]);
518 val[1] = val[0] < 0 ? -1 : 0;
520 if (GET_CODE (operands[1]) == CONST_DOUBLE)
522 if (GET_MODE (operands[1]) == DFmode)
524 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
525 REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
527 else if (GET_MODE (operands[1]) == VOIDmode
528 || GET_MODE (operands[1]) == DImode)
530 val[0] = CONST_DOUBLE_LOW (operands[1]);
531 val[1] = CONST_DOUBLE_HIGH (operands[1]);
535 if (GET_CODE (operands[1]) == MEM
536 && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
538 rtx temp = operands[0];
540 while (GET_CODE (temp) == SUBREG)
541 temp = SUBREG_REG (temp);
543 if (GET_CODE (temp) != REG)
546 if (reg_overlap_mentioned_p (gen_rtx (REG, SImode, REGNO (temp)),
547 XEXP (operands[1], 0)))
548 return \"mov %H1,%H0\;mov %L1,%L0\";
550 return \"mov %L1,%L0\;mov %H1,%H0\";
553 else if (GET_CODE (operands[1]) == MEM
554 && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
555 && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
559 xoperands[0] = operands[0];
560 xoperands[1] = XEXP (operands[1], 0);
562 output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\",
568 if ((GET_CODE (operands[1]) == CONST_INT
569 || GET_CODE (operands[1]) == CONST_DOUBLE)
572 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
573 output_asm_insn (\"clr %L0\", operands);
578 xoperands[0] = operands[0];
579 xoperands[1] = zero_areg;
580 if (rtx_equal_p (xoperands[0], xoperands[1]))
581 output_asm_insn (\"sub %L0,%L0\", xoperands);
583 output_asm_insn (\"mov %1,%L0\", xoperands);
586 output_asm_insn (\"mov %L1,%L0\", operands);
589 output_asm_insn (\"mov %L1,%L0\", operands);
591 if ((GET_CODE (operands[1]) == CONST_INT
592 || GET_CODE (operands[1]) == CONST_DOUBLE)
595 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
596 output_asm_insn (\"clr %H0\", operands);
601 xoperands[0] = operands[0];
602 xoperands[1] = zero_areg;
603 if (rtx_equal_p (xoperands[0], xoperands[1]))
604 output_asm_insn (\"sub %H0,%H0\", xoperands);
606 output_asm_insn (\"mov %1,%H0\", xoperands);
609 output_asm_insn (\"mov %H1,%H0\", operands);
611 else if ((GET_CODE (operands[1]) == CONST_INT
612 || GET_CODE (operands[1]) == CONST_DOUBLE)
614 output_asm_insn (\"mov %L0,%H0\", operands);
616 output_asm_insn (\"mov %H1,%H0\", operands);
621 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
625 ;; ----------------------------------------------------------------------
627 ;; ----------------------------------------------------------------------
629 ;; Go ahead and define tstsi so we can eliminate redundant tst insns
630 ;; when we start trying to optimize this port.
632 [(set (cc0) (match_operand:SI 0 "register_operand" "da"))]
634 "* return output_tst (operands[0], insn);"
635 [(set_attr "cc" "set_znv")])
638 [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "d")))]
640 "* return output_tst (operands[0], insn);"
641 [(set_attr "cc" "set_znv")])
644 [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "d")))]
646 "* return output_tst (operands[0], insn);"
647 [(set_attr "cc" "set_znv")])
652 (compare (match_operand:SI 0 "register_operand" "!*d*a,da")
653 (match_operand:SI 1 "nonmemory_operand" "!*0,dai")))]
658 [(set_attr "cc" "invert,compare")])
660 ;; ----------------------------------------------------------------------
662 ;; ----------------------------------------------------------------------
664 (define_expand "addsi3"
665 [(set (match_operand:SI 0 "register_operand" "")
666 (plus:SI (match_operand:SI 1 "register_operand" "")
667 (match_operand:SI 2 "nonmemory_operand" "")))]
671 /* We can't add a variable amount directly to the stack pointer;
672 so do so via a temporary register. */
673 if (operands[0] == stack_pointer_rtx
674 && GET_CODE (operands[1]) != CONST_INT
675 && GET_CODE (operands[2]) != CONST_INT)
677 rtx temp = gen_reg_rtx (SImode);
678 emit_move_insn (temp, gen_rtx (PLUS, SImode, operands[1], operands[2]));
679 emit_move_insn (operands[0], temp);
685 [(set (match_operand:SI 0 "register_operand" "=d,a,a,da,x,&!da")
686 (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,da")
687 (match_operand:SI 2 "nonmemory_operand" "J,J,L,dai,i,da")))]
695 mov %2,%0\;add %1,%0"
696 [(set_attr "cc" "set_zn,none_0hit,none_0hit,set_zn,none_0hit,set_zn")])
698 ;; ----------------------------------------------------------------------
699 ;; SUBTRACT INSTRUCTIONS
700 ;; ----------------------------------------------------------------------
702 (define_insn "subsi3"
703 [(set (match_operand:SI 0 "register_operand" "=da")
704 (minus:SI (match_operand:SI 1 "register_operand" "0")
705 (match_operand:SI 2 "nonmemory_operand" "dai")))]
708 [(set_attr "cc" "set_zn")])
710 (define_expand "negsi2"
711 [(set (match_operand:SI 0 "register_operand" "")
712 (neg:SI (match_operand:SI 1 "register_operand" "")))]
716 rtx target = gen_reg_rtx (SImode);
718 emit_move_insn (target, GEN_INT (0));
719 emit_insn (gen_subsi3 (target, target, operands[1]));
720 emit_move_insn (operands[0], target);
724 ;; ----------------------------------------------------------------------
725 ;; MULTIPLY INSTRUCTIONS
726 ;; ----------------------------------------------------------------------
728 (define_insn "mulsi3"
729 [(set (match_operand:SI 0 "register_operand" "=d")
730 (mult:SI (match_operand:SI 1 "register_operand" "%0")
731 (match_operand:SI 2 "register_operand" "d")))]
734 [(set_attr "cc" "set_zn")])
736 (define_insn "udivmodsi4"
737 [(set (match_operand:SI 0 "general_operand" "=d")
738 (udiv:SI (match_operand:SI 1 "general_operand" "0")
739 (match_operand:SI 2 "general_operand" "d")))
740 (set (match_operand:SI 3 "general_operand" "=&d")
741 (umod:SI (match_dup 1) (match_dup 2)))]
746 output_asm_insn (\"mov %0,mdr\", &zero_dreg);
748 output_asm_insn (\"sub %3,%3\;mov %3,mdr\", operands);
750 if (find_reg_note (insn, REG_UNUSED, operands[3]))
751 return \"divu %2,%0\";
753 return \"divu %2,%0\;mov mdr,%3\";
755 [(set_attr "cc" "set_zn")])
757 (define_insn "divmodsi4"
758 [(set (match_operand:SI 0 "general_operand" "=d")
759 (div:SI (match_operand:SI 1 "general_operand" "0")
760 (match_operand:SI 2 "general_operand" "d")))
761 (set (match_operand:SI 3 "general_operand" "=d")
762 (mod:SI (match_dup 1) (match_dup 2)))]
766 if (find_reg_note (insn, REG_UNUSED, operands[3]))
767 return \"ext %0\;div %2,%0\";
769 return \"ext %0\;div %2,%0\;mov mdr,%3\";
771 [(set_attr "cc" "set_zn")])
774 ;; ----------------------------------------------------------------------
776 ;; ----------------------------------------------------------------------
778 (define_insn "andsi3"
779 [(set (match_operand:SI 0 "register_operand" "=d,d")
780 (and:SI (match_operand:SI 1 "register_operand" "%0,0")
781 (match_operand:SI 2 "nonmemory_operand" "N,di")))]
785 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff)
787 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xffff)
789 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x7fffffff)
790 return \"add %0,%0\;lsr 1,%0\";
791 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x3fffffff)
792 return \"asl2 %0\;lsr 2,%0\";
793 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x1fffffff)
794 return \"add %0,%0\;asl2 %0\;lsr 3,%0\";
795 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x0fffffff)
796 return \"asl2 %0,%0\;asl2 %0\;lsr 4,%0\";
797 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffe)
798 return \"lsr 1,%0\;add %0,%0\";
799 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffc)
800 return \"lsr 2,%0\;asl2 %0\";
801 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff8)
802 return \"lsr 3,%0\;add %0,%0\;asl2 %0\";
803 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff0)
804 return \"lsr 4,%0\;asl2 %0\;asl2 %0\";
805 return \"and %2,%0\";
807 [(set_attr "cc" "none_0hit,set_znv")])
809 ;; ----------------------------------------------------------------------
811 ;; ----------------------------------------------------------------------
813 (define_insn "iorsi3"
814 [(set (match_operand:SI 0 "register_operand" "=d")
815 (ior:SI (match_operand:SI 1 "register_operand" "%0")
816 (match_operand:SI 2 "nonmemory_operand" "di")))]
819 [(set_attr "cc" "set_znv")])
821 ;; ----------------------------------------------------------------------
823 ;; ----------------------------------------------------------------------
825 (define_insn "xorsi3"
826 [(set (match_operand:SI 0 "register_operand" "=d")
827 (xor:SI (match_operand:SI 1 "register_operand" "%0")
828 (match_operand:SI 2 "nonmemory_operand" "di")))]
831 [(set_attr "cc" "set_znv")])
833 ;; ----------------------------------------------------------------------
835 ;; ----------------------------------------------------------------------
837 (define_insn "one_cmplsi2"
838 [(set (match_operand:SI 0 "register_operand" "=d")
839 (not:SI (match_operand:SI 1 "register_operand" "0")))]
842 [(set_attr "cc" "set_znv")])
844 ;; -----------------------------------------------------------------
846 ;; -----------------------------------------------------------------
849 ;; These set/clear memory in byte sized chunks.
851 ;; They are no smaller/faster than loading the value into a register
852 ;; and storing the register, but they don't need a scratch register
853 ;; which may allow for better code generation.
855 [(set (match_operand:QI 0 "general_operand" "=R,d") (const_int 0))]
860 [(set_attr "cc" "clobber")])
863 [(set (match_operand:QI 0 "general_operand" "=R,d") (const_int -1))]
868 [(set_attr "cc" "clobber,none_0hit")])
871 [(set (match_operand:QI 0 "general_operand" "=R,d")
873 (and:SI (subreg:SI (match_dup 0) 0)
874 (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
879 [(set_attr "cc" "clobber,set_znv")])
882 [(set (match_operand:QI 0 "general_operand" "=R,d")
884 (ior:SI (subreg:SI (match_dup 0) 0)
885 (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
890 [(set_attr "cc" "clobber,set_znv")])
894 (zero_extract:SI (match_operand:SI 0 "register_operand" "d")
895 (match_operand 1 "const_int_operand" "")
896 (match_operand 2 "const_int_operand" "")))]
900 int len = INTVAL (operands[1]);
901 int bit = INTVAL (operands[2]);
912 xoperands[0] = operands[0];
913 xoperands[1] = GEN_INT (mask);
914 output_asm_insn (\"btst %1,%0\", xoperands);
917 [(set_attr "cc" "set_znv")])
921 (zero_extract:SI (match_operand:QI 0 "general_operand" "R,d")
922 (match_operand 1 "const_int_operand" "")
923 (match_operand 2 "const_int_operand" "")))]
924 "INTVAL (operands[1]) <= 8 && INTVAL (operands[2]) <= 7"
927 int len = INTVAL (operands[1]);
928 int bit = INTVAL (operands[2]);
939 xoperands[0] = operands[0];
940 xoperands[1] = GEN_INT (mask);
941 if (GET_CODE (operands[0]) == REG)
942 output_asm_insn (\"btst %1,%0\", xoperands);
944 output_asm_insn (\"btst %1,%A0\", xoperands);
947 [(set_attr "cc" "set_znv")])
950 [(set (cc0) (and:SI (match_operand:SI 0 "register_operand" "d")
951 (match_operand:SI 1 "const_int_operand" "")))]
954 [(set_attr "cc" "set_znv")])
959 (subreg:SI (match_operand:QI 0 "general_operand" "R,d") 0)
960 (match_operand:SI 1 "const_int_operand" "")))]
965 [(set_attr "cc" "set_znv")])
968 ;; ----------------------------------------------------------------------
970 ;; ----------------------------------------------------------------------
972 ;; Conditional jump instructions
976 (if_then_else (le (cc0)
978 (label_ref (match_operand 0 "" ""))
983 (define_expand "bleu"
985 (if_then_else (leu (cc0)
987 (label_ref (match_operand 0 "" ""))
994 (if_then_else (ge (cc0)
996 (label_ref (match_operand 0 "" ""))
1001 (define_expand "bgeu"
1003 (if_then_else (geu (cc0)
1005 (label_ref (match_operand 0 "" ""))
1010 (define_expand "blt"
1012 (if_then_else (lt (cc0)
1014 (label_ref (match_operand 0 "" ""))
1019 (define_expand "bltu"
1021 (if_then_else (ltu (cc0)
1023 (label_ref (match_operand 0 "" ""))
1028 (define_expand "bgt"
1030 (if_then_else (gt (cc0)
1032 (label_ref (match_operand 0 "" ""))
1037 (define_expand "bgtu"
1039 (if_then_else (gtu (cc0)
1041 (label_ref (match_operand 0 "" ""))
1046 (define_expand "beq"
1048 (if_then_else (eq (cc0)
1050 (label_ref (match_operand 0 "" ""))
1055 (define_expand "bne"
1057 (if_then_else (ne (cc0)
1059 (label_ref (match_operand 0 "" ""))
1066 (if_then_else (match_operator 1 "comparison_operator"
1067 [(cc0) (const_int 0)])
1068 (label_ref (match_operand 0 "" ""))
1073 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1074 && (GET_CODE (operands[1]) == GT
1075 || GET_CODE (operands[1]) == GE
1076 || GET_CODE (operands[1]) == LE
1077 || GET_CODE (operands[1]) == LT))
1081 [(set_attr "cc" "none")])
1085 (if_then_else (match_operator 1 "comparison_operator"
1086 [(cc0) (const_int 0)])
1088 (label_ref (match_operand 0 "" ""))))]
1092 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1093 && (GET_CODE (operands[1]) == GT
1094 || GET_CODE (operands[1]) == GE
1095 || GET_CODE (operands[1]) == LE
1096 || GET_CODE (operands[1]) == LT))
1100 [(set_attr "cc" "none")])
1102 ;; Unconditional and other jump instructions.
1106 (label_ref (match_operand 0 "" "")))]
1109 [(set_attr "cc" "none")])
1111 (define_insn "indirect_jump"
1112 [(set (pc) (match_operand:SI 0 "register_operand" "a"))]
1115 [(set_attr "cc" "none")])
1117 (define_insn "tablejump"
1118 [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1119 (use (label_ref (match_operand 1 "" "")))]
1122 [(set_attr "cc" "none")])
1124 ;; Call subroutine with no return value.
1126 (define_expand "call"
1127 [(call (match_operand:QI 0 "general_operand" "")
1128 (match_operand:SI 1 "general_operand" ""))]
1132 if (! call_address_operand (XEXP (operands[0], 0)))
1133 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
1134 emit_call_insn (gen_call_internal (XEXP (operands[0], 0), operands[1]));
1138 (define_insn "call_internal"
1139 [(call (mem:QI (match_operand:SI 0 "call_address_operand" "aS"))
1140 (match_operand:SI 1 "general_operand" "g"))]
1144 if (REG_P (operands[0]))
1145 return \"calls %C0\";
1147 return \"call %C0,[],0\";
1149 [(set_attr "cc" "clobber")])
1151 ;; Call subroutine, returning value in operand 0
1152 ;; (which must be a hard register).
1154 (define_expand "call_value"
1155 [(set (match_operand 0 "" "")
1156 (call (match_operand:QI 1 "general_operand" "")
1157 (match_operand:SI 2 "general_operand" "")))]
1161 if (! call_address_operand (XEXP (operands[1], 0)))
1162 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
1163 emit_call_insn (gen_call_value_internal (operands[0],
1164 XEXP (operands[1], 0),
1169 (define_insn "call_value_internal"
1170 [(set (match_operand 0 "" "=da")
1171 (call (mem:QI (match_operand:SI 1 "call_address_operand" "aS"))
1172 (match_operand:SI 2 "general_operand" "g")))]
1176 if (REG_P (operands[1]))
1177 return \"calls %C1\";
1179 return \"call %C1,[],0\";
1181 [(set_attr "cc" "clobber")])
1183 (define_expand "untyped_call"
1184 [(parallel [(call (match_operand 0 "" "")
1186 (match_operand 1 "" "")
1187 (match_operand 2 "" "")])]
1193 emit_call_insn (gen_call (operands[0], const0_rtx));
1195 for (i = 0; i < XVECLEN (operands[2], 0); i++)
1197 rtx set = XVECEXP (operands[2], 0, i);
1198 emit_move_insn (SET_DEST (set), SET_SRC (set));
1207 [(set_attr "cc" "none")])
1209 ;; ----------------------------------------------------------------------
1210 ;; EXTEND INSTRUCTIONS
1211 ;; ----------------------------------------------------------------------
1213 (define_insn "zero_extendqisi2"
1214 [(set (match_operand:SI 0 "general_operand" "=d,d,d")
1216 (match_operand:QI 1 "general_operand" "0,d,m")))]
1222 [(set_attr "cc" "none_0hit")])
1224 (define_insn "zero_extendhisi2"
1225 [(set (match_operand:SI 0 "general_operand" "=d,d,d")
1227 (match_operand:HI 1 "general_operand" "0,d,m")))]
1233 [(set_attr "cc" "none_0hit")])
1235 ;;- sign extension instructions
1237 (define_insn "extendqisi2"
1238 [(set (match_operand:SI 0 "general_operand" "=d,d")
1240 (match_operand:QI 1 "general_operand" "0,d")))]
1245 [(set_attr "cc" "none_0hit")])
1247 (define_insn "extendhisi2"
1248 [(set (match_operand:SI 0 "general_operand" "=d,d")
1250 (match_operand:HI 1 "general_operand" "0,d")))]
1255 [(set_attr "cc" "none_0hit")])
1257 ;; ----------------------------------------------------------------------
1259 ;; ----------------------------------------------------------------------
1261 (define_insn "ashlsi3"
1262 [(set (match_operand:SI 0 "register_operand" "=da,d,d,d,d")
1264 (match_operand:SI 1 "register_operand" "0,0,0,0,0")
1265 (match_operand:QI 2 "nonmemory_operand" "J,K,M,L,di")))]
1273 [(set_attr "cc" "set_zn")])
1275 (define_insn "lshrsi3"
1276 [(set (match_operand:SI 0 "register_operand" "=d")
1278 (match_operand:SI 1 "register_operand" "0")
1279 (match_operand:QI 2 "nonmemory_operand" "di")))]
1282 [(set_attr "cc" "set_zn")])
1284 (define_insn "ashrsi3"
1285 [(set (match_operand:SI 0 "register_operand" "=d")
1287 (match_operand:SI 1 "register_operand" "0")
1288 (match_operand:QI 2 "nonmemory_operand" "di")))]
1291 [(set_attr "cc" "set_zn")])
1293 ;; ----------------------------------------------------------------------
1294 ;; PROLOGUE/EPILOGUE
1295 ;; ----------------------------------------------------------------------
1296 (define_expand "prologue"
1299 "expand_prologue (); DONE;")
1301 (define_expand "epilogue"
1310 (define_insn "return_internal"
1314 [(set_attr "cc" "clobber")])
1316 ;; This insn restores the callee saved registers and does a return, it
1317 ;; can also deallocate stack space.
1318 (define_insn "return_internal_regs"
1320 (match_operand:SI 0 "const_int_operand" "i")
1323 "ret [d2,d3,a2,a3],%0"
1324 [(set_attr "cc" "clobber")])
1326 (define_insn "store_movm"
1329 "movm [d2,d3,a2,a3],(sp)"
1330 [(set_attr "cc" "clobber")])
1332 (define_insn "return"
1334 "can_use_return_insn ()"
1337 rtx next = next_active_insn (insn);
1340 && GET_CODE (next) == JUMP_INSN
1341 && GET_CODE (PATTERN (next)) == RETURN)
1346 [(set_attr "cc" "clobber")])
1348 ;; Try to combine consecutive updates of the stack pointer (or any
1349 ;; other register for that matter).
1351 [(set (match_operand:SI 0 "register_operand" "=dax")
1352 (plus:SI (match_dup 0)
1353 (match_operand 1 "const_int_operand" "")))
1355 (plus:SI (match_dup 0)
1356 (match_operand 2 "const_int_operand" "")))]
1360 operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]));
1361 return \"add %1,%0\";
1363 [(set_attr "cc" "clobber")])
1366 ;; We had patterns to check eq/ne, but the they don't work because
1367 ;; 0x80000000 + 0x80000000 = 0x0 with a carry out.
1369 ;; The Z flag and C flag would be set, and we have no way to
1370 ;; check for the Z flag set and C flag clear.
1372 ;; This will work on the mn10200 because we can check the ZX flag
1373 ;; if the comparison is in HImode.
1375 [(set (cc0) (match_operand:SI 0 "register_operand" "d"))
1376 (set (pc) (if_then_else (ge (cc0) (const_int 0))
1377 (match_operand 1 "" "")
1379 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1381 [(set_attr "cc" "clobber")])
1384 [(set (cc0) (match_operand:SI 0 "register_operand" "d"))
1385 (set (pc) (if_then_else (lt (cc0) (const_int 0))
1386 (match_operand 1 "" "")
1388 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1390 [(set_attr "cc" "clobber")])
1393 [(set (cc0) (match_operand:SI 0 "register_operand" "d"))
1394 (set (pc) (if_then_else (ge (cc0) (const_int 0))
1396 (match_operand 1 "" "")))]
1397 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1399 [(set_attr "cc" "clobber")])
1402 [(set (cc0) (match_operand:SI 0 "register_operand" "d"))
1403 (set (pc) (if_then_else (lt (cc0) (const_int 0))
1405 (match_operand 1 "" "")))]
1406 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1408 [(set_attr "cc" "clobber")])