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 - insn sets flags z,n. v is unusable c is set to 0.
34 ;; (c may not really be set to 0 but that's ok, we don't need it anyway).
35 ;; set_zn_c0 - insn sets z,n to usable values. v is unknown. c may or may not
36 ;; be known (if it isn't that's ok, we don't need it anyway).
37 ;; compare - compare instruction
38 ;; invert -- like compare, but flags are inverted.
39 ;; clobber - value of cc is unknown
40 (define_attr "cc" "none,none_0hit,tst,set_zn_c0,compare,clobber,invert"
41 (const_string "clobber"))
43 ;; ----------------------------------------------------------------------
45 ;; ----------------------------------------------------------------------
49 (define_expand "movqi"
50 [(set (match_operand:QI 0 "general_operand" "")
51 (match_operand:QI 1 "general_operand" ""))]
55 /* One of the ops has to be in a register */
56 if (!register_operand (operand0, QImode)
57 && !register_operand (operand1, QImode))
58 operands[1] = copy_to_mode_reg (QImode, operand1);
62 [(set (match_operand:QI 0 "general_operand" "=d,a,d,a,d,a,d,a,d,m")
63 (match_operand:QI 1 "general_operand" "0,0,I,I,a,d,di,ia,m,d"))]
64 "register_operand (operands[0], QImode)
65 || register_operand (operands[1], QImode)"
68 switch (which_alternative)
80 xoperands[0] = operands[0];
81 xoperands[1] = zero_areg;
82 if (rtx_equal_p (xoperands[0], xoperands[1]))
83 output_asm_insn (\"sub %1,%0\", xoperands);
85 output_asm_insn (\"mov %1,%0\", xoperands);
97 return \"movbu %1,%0\";
100 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
104 (define_expand "movhi"
105 [(set (match_operand:HI 0 "general_operand" "")
106 (match_operand:HI 1 "general_operand" ""))]
110 /* One of the ops has to be in a register */
111 if (!register_operand (operand1, HImode)
112 && !register_operand (operand0, HImode))
113 operands[1] = copy_to_mode_reg (HImode, operand1);
117 [(set (match_operand:HI 0 "general_operand" "=d,a,d,a,d,a,d,a,d,m")
118 (match_operand:HI 1 "general_operand" "0,0,I,I,a,d,di,ia,m,d"))]
119 "register_operand (operands[0], HImode)
120 || register_operand (operands[1], HImode)"
123 switch (which_alternative)
135 xoperands[0] = operands[0];
136 xoperands[1] = zero_areg;
137 if (rtx_equal_p (xoperands[0], xoperands[1]))
138 output_asm_insn (\"sub %1,%0\", xoperands);
140 output_asm_insn (\"mov %1,%0\", xoperands);
149 return \"mov %1,%0\";
152 return \"movhu %1,%0\";
155 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
159 ;; We use this to handle addition of two values when one operand is the
160 ;; stack pointer and the other is a memory reference of some kind. Reload
161 ;; does not handle them correctly without this expander.
162 (define_expand "reload_insi"
163 [(set (match_operand:SI 0 "register_operand" "=a")
164 (match_operand:SI 1 "impossible_plus_operand" ""))
165 (clobber (match_operand:SI 2 "register_operand" "=&a"))]
169 emit_move_insn (operands[0], XEXP (operands[1], 0));
170 emit_move_insn (operands[2], XEXP (operands[1], 1));
171 emit_insn (gen_addsi3 (operands[0], operands[0], operands[2]));
175 (define_expand "movsi"
176 [(set (match_operand:SI 0 "general_operand" "")
177 (match_operand:SI 1 "general_operand" ""))]
181 /* One of the ops has to be in a register */
182 if (!register_operand (operand1, SImode)
183 && !register_operand (operand0, SImode))
184 operands[1] = copy_to_mode_reg (SImode, operand1);
188 [(set (match_operand:SI 0 "general_operand"
189 "=d,a,d,a,dm,dm,am,am,d,d,a,a,aR,x")
190 (match_operand:SI 1 "general_operand"
191 "0,0,I,I,d,a,d,a,dim,aim,dim,aim,x,aR"))]
192 "register_operand (operands[0], SImode)
193 || register_operand (operands[1], SImode)"
196 switch (which_alternative)
208 xoperands[0] = operands[0];
209 xoperands[1] = zero_areg;
210 if (rtx_equal_p (xoperands[0], xoperands[1]))
211 output_asm_insn (\"sub %1,%0\", xoperands);
213 output_asm_insn (\"mov %1,%0\", xoperands);
228 return \"mov %1,%0\";
231 [(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")])
233 (define_expand "movsf"
234 [(set (match_operand:SF 0 "general_operand" "")
235 (match_operand:SF 1 "general_operand" ""))]
239 /* One of the ops has to be in a register */
240 if (!register_operand (operand1, SFmode)
241 && !register_operand (operand0, SFmode))
242 operands[1] = copy_to_mode_reg (SFmode, operand1);
246 [(set (match_operand:SF 0 "general_operand" "=d,a,d,a,dam,da")
247 (match_operand:SF 1 "general_operand" "0,0,G,G,da,daim"))]
248 "register_operand (operands[0], SFmode)
249 || register_operand (operands[1], SFmode)"
252 switch (which_alternative)
264 xoperands[0] = operands[0];
265 xoperands[1] = zero_areg;
266 if (rtx_equal_p (xoperands[0], xoperands[1]))
267 output_asm_insn (\"sub %1,%0\", xoperands);
269 output_asm_insn (\"mov %1,%0\", xoperands);
276 return \"mov %1,%0\";
279 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit")])
281 (define_expand "movdi"
282 [(set (match_operand:DI 0 "general_operand" "")
283 (match_operand:DI 1 "general_operand" ""))]
287 /* One of the ops has to be in a register */
288 if (!register_operand (operand1, DImode)
289 && !register_operand (operand0, DImode))
290 operands[1] = copy_to_mode_reg (DImode, operand1);
294 [(set (match_operand:DI 0 "general_operand"
295 "=d,a,d,a,dm,dm,am,am,d,d,a,a")
296 (match_operand:DI 1 "general_operand"
297 "0,0,I,I,d,a,d,a,dim,aim,dim,aim"))]
298 "register_operand (operands[0], DImode)
299 || register_operand (operands[1], DImode)"
305 switch (which_alternative)
312 return \"clr %L0\;clr %H0\";
318 xoperands[0] = operands[0];
319 xoperands[1] = zero_areg ? zero_areg : operands[1];
320 if (rtx_equal_p (xoperands[0], xoperands[1]))
321 output_asm_insn (\"sub %L1,%L0\;mov %L0,%H0\", xoperands);
323 output_asm_insn (\"mov %1,%L0\;mov %L0,%H0\", xoperands);
334 if (GET_CODE (operands[1]) == CONST_INT)
336 val[0] = INTVAL (operands[1]);
337 val[1] = val[0] < 0 ? -1 : 0;
339 if (GET_CODE (operands[1]) == CONST_DOUBLE)
341 if (GET_MODE (operands[1]) == DFmode)
343 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
344 REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
346 else if (GET_MODE (operands[1]) == VOIDmode
347 || GET_MODE (operands[1]) == DImode)
349 val[0] = CONST_DOUBLE_LOW (operands[1]);
350 val[1] = CONST_DOUBLE_HIGH (operands[1]);
354 if (GET_CODE (operands[1]) == MEM
355 && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
357 rtx temp = operands[0];
359 while (GET_CODE (temp) == SUBREG)
360 temp = SUBREG_REG (temp);
362 if (GET_CODE (temp) != REG)
365 if (reg_overlap_mentioned_p (gen_rtx (REG, SImode, REGNO (temp)),
366 XEXP (operands[1], 0)))
367 return \"mov %H1,%H0\;mov %L1,%L0\";
369 return \"mov %L1,%L0\;mov %H1,%H0\";
372 else if (GET_CODE (operands[1]) == MEM
373 && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
374 && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
378 xoperands[0] = operands[0];
379 xoperands[1] = XEXP (operands[1], 0);
381 output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\",
387 if ((GET_CODE (operands[1]) == CONST_INT
388 || GET_CODE (operands[1]) == CONST_DOUBLE)
391 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
392 output_asm_insn (\"clr %L0\", operands);
397 xoperands[0] = operands[0];
398 xoperands[1] = zero_areg;
399 if (rtx_equal_p (xoperands[0], xoperands[1]))
400 output_asm_insn (\"sub %L0,%L0\", xoperands);
402 output_asm_insn (\"mov %1,%L0\", xoperands);
405 output_asm_insn (\"mov %L1,%L0\", operands);
408 output_asm_insn (\"mov %L1,%L0\", operands);
410 if ((GET_CODE (operands[1]) == CONST_INT
411 || GET_CODE (operands[1]) == CONST_DOUBLE)
414 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
415 output_asm_insn (\"clr %H0\", operands);
420 xoperands[0] = operands[0];
421 xoperands[1] = zero_areg;
422 if (rtx_equal_p (xoperands[0], xoperands[1]))
423 output_asm_insn (\"sub %H0,%H0\", xoperands);
425 output_asm_insn (\"mov %1,%H0\", xoperands);
428 output_asm_insn (\"mov %H1,%H0\", operands);
430 else if ((GET_CODE (operands[1]) == CONST_INT
431 || GET_CODE (operands[1]) == CONST_DOUBLE)
433 output_asm_insn (\"mov %L0,%H0\", operands);
435 output_asm_insn (\"mov %H1,%H0\", operands);
440 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
442 (define_expand "movdf"
443 [(set (match_operand:DF 0 "general_operand" "")
444 (match_operand:DF 1 "general_operand" ""))]
448 /* One of the ops has to be in a register */
449 if (!register_operand (operand1, DFmode)
450 && !register_operand (operand0, DFmode))
451 operands[1] = copy_to_mode_reg (DFmode, operand1);
455 [(set (match_operand:DF 0 "general_operand"
456 "=d,a,d,a,dm,dm,am,am,d,d,a,a")
457 (match_operand:DF 1 "general_operand"
458 "0,0,G,G,d,a,d,a,dim,aim,dim,aim"))]
459 "register_operand (operands[0], DFmode)
460 || register_operand (operands[1], DFmode)"
466 switch (which_alternative)
473 return \"clr %L0\;clr %H0\";
479 xoperands[0] = operands[0];
480 xoperands[1] = zero_areg ? zero_areg : operands[1];
481 if (rtx_equal_p (xoperands[0], xoperands[1]))
482 output_asm_insn (\"sub %L1,%L0\;mov %L0,%H0\", xoperands);
484 output_asm_insn (\"mov %1,%L0\;mov %L0,%H0\", xoperands);
495 if (GET_CODE (operands[1]) == CONST_INT)
497 val[0] = INTVAL (operands[1]);
498 val[1] = val[0] < 0 ? -1 : 0;
500 if (GET_CODE (operands[1]) == CONST_DOUBLE)
502 if (GET_MODE (operands[1]) == DFmode)
504 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
505 REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
507 else if (GET_MODE (operands[1]) == VOIDmode
508 || GET_MODE (operands[1]) == DImode)
510 val[0] = CONST_DOUBLE_LOW (operands[1]);
511 val[1] = CONST_DOUBLE_HIGH (operands[1]);
515 if (GET_CODE (operands[1]) == MEM
516 && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
518 rtx temp = operands[0];
520 while (GET_CODE (temp) == SUBREG)
521 temp = SUBREG_REG (temp);
523 if (GET_CODE (temp) != REG)
526 if (reg_overlap_mentioned_p (gen_rtx (REG, SImode, REGNO (temp)),
527 XEXP (operands[1], 0)))
528 return \"mov %H1,%H0\;mov %L1,%L0\";
530 return \"mov %L1,%L0\;mov %H1,%H0\";
533 else if (GET_CODE (operands[1]) == MEM
534 && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
535 && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
539 xoperands[0] = operands[0];
540 xoperands[1] = XEXP (operands[1], 0);
542 output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\",
548 if ((GET_CODE (operands[1]) == CONST_INT
549 || GET_CODE (operands[1]) == CONST_DOUBLE)
552 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
553 output_asm_insn (\"clr %L0\", operands);
558 xoperands[0] = operands[0];
559 xoperands[1] = zero_areg;
560 if (rtx_equal_p (xoperands[0], xoperands[1]))
561 output_asm_insn (\"sub %L0,%L0\", xoperands);
563 output_asm_insn (\"mov %1,%L0\", xoperands);
566 output_asm_insn (\"mov %L1,%L0\", operands);
569 output_asm_insn (\"mov %L1,%L0\", operands);
571 if ((GET_CODE (operands[1]) == CONST_INT
572 || GET_CODE (operands[1]) == CONST_DOUBLE)
575 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
576 output_asm_insn (\"clr %H0\", operands);
581 xoperands[0] = operands[0];
582 xoperands[1] = zero_areg;
583 if (rtx_equal_p (xoperands[0], xoperands[1]))
584 output_asm_insn (\"sub %H0,%H0\", xoperands);
586 output_asm_insn (\"mov %1,%H0\", xoperands);
589 output_asm_insn (\"mov %H1,%H0\", operands);
591 else if ((GET_CODE (operands[1]) == CONST_INT
592 || GET_CODE (operands[1]) == CONST_DOUBLE)
594 output_asm_insn (\"mov %L0,%H0\", operands);
596 output_asm_insn (\"mov %H1,%H0\", operands);
601 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
605 ;; ----------------------------------------------------------------------
607 ;; ----------------------------------------------------------------------
609 ;; Go ahead and define tstsi so we can eliminate redundant tst insns
610 ;; when we start trying to optimize this port.
612 [(set (cc0) (match_operand:SI 0 "register_operand" "da"))]
614 "* return output_tst (operands[0], insn);"
615 [(set_attr "cc" "tst")])
618 [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "d")))]
620 "* return output_tst (operands[0], insn);"
621 [(set_attr "cc" "tst")])
624 [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "d")))]
626 "* return output_tst (operands[0], insn);"
627 [(set_attr "cc" "tst")])
632 (compare (match_operand:SI 0 "register_operand" "!*d*a,da")
633 (match_operand:SI 1 "nonmemory_operand" "!*0,dai")))]
638 [(set_attr "cc" "invert,compare")])
640 ;; ----------------------------------------------------------------------
642 ;; ----------------------------------------------------------------------
644 (define_expand "addsi3"
645 [(set (match_operand:SI 0 "register_operand" "")
646 (plus:SI (match_operand:SI 1 "register_operand" "")
647 (match_operand:SI 2 "nonmemory_operand" "")))]
651 /* We can't add a variable amount directly to the stack pointer;
652 so do so via a temporary register. */
653 if (operands[0] == stack_pointer_rtx
654 && GET_CODE (operands[1]) != CONST_INT
655 && GET_CODE (operands[2]) != CONST_INT)
657 rtx temp = gen_reg_rtx (SImode);
658 emit_move_insn (temp, gen_rtx (PLUS, SImode, operands[1], operands[2]));
659 emit_move_insn (operands[0], temp);
665 [(set (match_operand:SI 0 "register_operand" "=d,a,a,da,x,&!da")
666 (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,da")
667 (match_operand:SI 2 "nonmemory_operand" "J,J,L,dai,i,da")))]
675 mov %2,%0\;add %1,%0"
676 [(set_attr "cc" "set_zn_c0,none_0hit,none_0hit,set_zn_c0,none_0hit,set_zn_c0")])
678 (define_expand "adddi3"
679 [(set (reg:DI 0) (match_operand:DI 1 "register_operand" ""))
680 (set (reg:DI 2) (match_operand:DI 2 "nonmemory_operand" ""))
681 (set (reg:DI 0) (plus:DI (reg:DI 0) (reg:DI 2)))
682 (set (match_operand:DI 0 "register_operand" "") (reg:DI 0))]
686 if (GET_CODE (operands[2]) == CONST_INT)
688 rtx reg0 = gen_rtx (REG, DImode, 0);
690 emit_move_insn (reg0, operands[1]);
691 emit_insn (gen_adddi3_const (operands[2]));
692 emit_move_insn (operands[0], reg0);
697 ;; The general adddi3 pattern.
699 [(set (reg:DI 0) (plus:DI (reg:DI 0) (reg:DI 2)))]
701 "add d2,d0\;addc d3,d1"
702 [(set_attr "cc" "clobber")])
704 ;; adddi3 with on operand being a constant.
705 (define_insn "adddi3_const"
707 (plus:DI (reg:DI 0) (match_operand:DI 0 "const_int_operand" "i")))
708 (clobber (reg:DI 2))]
712 long value = INTVAL (operands[0]);
715 return \"mov -1,d2\;add %0,d0\;addc d2,d1\";
717 return \"clr d2\;add %0,d0\;addc d2,d1\";
719 [(set_attr "cc" "clobber")])
720 ;; ----------------------------------------------------------------------
721 ;; SUBTRACT INSTRUCTIONS
722 ;; ----------------------------------------------------------------------
724 (define_insn "subsi3"
725 [(set (match_operand:SI 0 "register_operand" "=da")
726 (minus:SI (match_operand:SI 1 "register_operand" "0")
727 (match_operand:SI 2 "nonmemory_operand" "dai")))]
730 [(set_attr "cc" "set_zn_c0")])
732 (define_expand "negsi2"
733 [(set (match_operand:SI 0 "register_operand" "")
734 (neg:SI (match_operand:SI 1 "register_operand" "")))]
738 rtx target = gen_reg_rtx (SImode);
740 emit_move_insn (target, GEN_INT (0));
741 emit_insn (gen_subsi3 (target, target, operands[1]));
742 emit_move_insn (operands[0], target);
746 (define_expand "subdi3"
747 [(set (reg:DI 0) (match_operand:DI 1 "register_operand" ""))
748 (set (reg:DI 2) (match_operand:DI 2 "nonmemory_operand" ""))
749 (set (reg:DI 0) (minus:DI (reg:DI 0) (reg:DI 2)))
750 (set (match_operand:DI 0 "register_operand" "") (reg:DI 0))]
755 [(set (reg:DI 0) (minus:DI (reg:DI 0) (reg:DI 2)))]
757 "sub d2,d0\;subc d3,d1"
758 [(set_attr "cc" "clobber")])
760 ;; ----------------------------------------------------------------------
761 ;; MULTIPLY INSTRUCTIONS
762 ;; ----------------------------------------------------------------------
764 (define_insn "mulsi3"
765 [(set (match_operand:SI 0 "register_operand" "=d")
766 (mult:SI (match_operand:SI 1 "register_operand" "%0")
767 (match_operand:SI 2 "register_operand" "d")))]
770 [(set_attr "cc" "set_zn_c0")])
772 (define_expand "udivmodsi4"
773 [(parallel [(set (match_operand:SI 0 "register_operand" "")
774 (udiv:SI (match_operand:SI 1 "register_operand" "")
775 (match_operand:SI 2 "register_operand" "")))
776 (set (match_operand:SI 3 "register_operand" "")
777 (umod:SI (match_dup 1) (match_dup 2)))])]
781 rtx reg = gen_reg_rtx (SImode);
782 emit_move_insn (reg, GEN_INT (0));
783 emit_insn (gen_clear_mdr (reg));
787 [(set (match_operand:SI 0 "general_operand" "=d")
788 (udiv:SI (match_operand:SI 1 "general_operand" "0")
789 (match_operand:SI 2 "general_operand" "d")))
790 (set (match_operand:SI 3 "general_operand" "=d")
791 (umod:SI (match_dup 1) (match_dup 2)))]
795 if (find_reg_note (insn, REG_UNUSED, operands[3]))
796 return \"divu %2,%0\";
798 return \"divu %2,%0\;mov mdr,%3\";
800 [(set_attr "cc" "set_zn_c0")])
802 (define_expand "divmodsi4"
803 [(parallel [(set (match_operand:SI 0 "register_operand" "")
804 (div:SI (match_operand:SI 1 "register_operand" "")
805 (match_operand:SI 2 "register_operand" "")))
806 (set (match_operand:SI 3 "register_operand" "")
807 (mod:SI (match_dup 1) (match_dup 2)))])]
812 [(set (match_operand:SI 0 "general_operand" "=d")
813 (div:SI (match_operand:SI 1 "general_operand" "0")
814 (match_operand:SI 2 "general_operand" "d")))
815 (set (match_operand:SI 3 "general_operand" "=d")
816 (mod:SI (match_dup 1) (match_dup 2)))]
820 if (find_reg_note (insn, REG_UNUSED, operands[3]))
821 return \"ext %0\;div %2,%0\";
823 return \"ext %0\;div %2,%0\;mov mdr,%3\";
825 [(set_attr "cc" "set_zn_c0")])
827 (define_insn "clear_mdr"
828 [(unspec_volatile [(const_int 2)] 0)
829 (use (match_operand:SI 0 "register_operand" "d"))]
832 [(set_attr "cc" "none")])
834 ;; ----------------------------------------------------------------------
836 ;; ----------------------------------------------------------------------
838 (define_insn "andsi3"
839 [(set (match_operand:SI 0 "register_operand" "=d,d")
840 (and:SI (match_operand:SI 1 "register_operand" "%0,0")
841 (match_operand:SI 2 "nonmemory_operand" "N,di")))]
845 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff)
847 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xffff)
849 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x7fffffff)
850 return \"add %0,%0\;lsr 1,%0\";
851 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x3fffffff)
852 return \"asl2 %0\;lsr 2,%0\";
853 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x1fffffff)
854 return \"add %0,%0\;asl2 %0\;lsr 3,%0\";
855 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x0fffffff)
856 return \"asl2 %0,%0\;asl2 %0\;lsr 4,%0\";
857 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffe)
858 return \"lsr 1,%0\;add %0,%0\";
859 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffc)
860 return \"lsr 2,%0\;asl2 %0\";
861 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff8)
862 return \"lsr 3,%0\;add %0,%0\;asl2 %0\";
863 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff0)
864 return \"lsr 4,%0\;asl2 %0\;asl2 %0\";
865 return \"and %2,%0\";
867 [(set_attr "cc" "none_0hit,set_zn_c0")])
869 ;; ----------------------------------------------------------------------
871 ;; ----------------------------------------------------------------------
873 (define_insn "iorsi3"
874 [(set (match_operand:SI 0 "register_operand" "=d")
875 (ior:SI (match_operand:SI 1 "register_operand" "%0")
876 (match_operand:SI 2 "nonmemory_operand" "di")))]
879 [(set_attr "cc" "set_zn_c0")])
881 ;; ----------------------------------------------------------------------
883 ;; ----------------------------------------------------------------------
885 (define_insn "xorsi3"
886 [(set (match_operand:SI 0 "register_operand" "=d")
887 (xor:SI (match_operand:SI 1 "register_operand" "%0")
888 (match_operand:SI 2 "nonmemory_operand" "di")))]
891 [(set_attr "cc" "set_zn_c0")])
893 ;; ----------------------------------------------------------------------
895 ;; ----------------------------------------------------------------------
897 (define_insn "one_cmplsi2"
898 [(set (match_operand:SI 0 "register_operand" "=d")
899 (not:SI (match_operand:SI 1 "register_operand" "0")))]
902 [(set_attr "cc" "set_zn_c0")])
904 ;; -----------------------------------------------------------------
906 ;; -----------------------------------------------------------------
909 ;; These set/clear memory in byte sized chunks.
911 ;; They are no smaller/faster than loading the value into a register
912 ;; and storing the register, but they don't need a scratch register
913 ;; which may allow for better code generation.
915 [(set (match_operand:QI 0 "general_operand" "=R,d") (const_int 0))]
920 [(set_attr "cc" "clobber")])
923 [(set (match_operand:QI 0 "general_operand" "=R,d") (const_int -1))]
928 [(set_attr "cc" "clobber,none_0hit")])
931 [(set (match_operand:QI 0 "general_operand" "=R,d")
933 (and:SI (subreg:SI (match_dup 0) 0)
934 (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
939 [(set_attr "cc" "clobber,set_zn_c0")])
942 [(set (match_operand:QI 0 "general_operand" "=R,d")
944 (ior:SI (subreg:SI (match_dup 0) 0)
945 (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
950 [(set_attr "cc" "clobber")])
954 (zero_extract:SI (match_operand:SI 0 "register_operand" "d")
955 (match_operand 1 "const_int_operand" "")
956 (match_operand 2 "const_int_operand" "")))]
960 int len = INTVAL (operands[1]);
961 int bit = INTVAL (operands[2]);
972 xoperands[0] = operands[0];
973 xoperands[1] = GEN_INT (mask);
974 output_asm_insn (\"btst %1,%0\", xoperands);
977 [(set_attr "cc" "set_zn_c0")])
981 (zero_extract:SI (match_operand:QI 0 "general_operand" "R,d")
982 (match_operand 1 "const_int_operand" "")
983 (match_operand 2 "const_int_operand" "")))]
984 "INTVAL (operands[1]) <= 8 && INTVAL (operands[2]) <= 7"
987 int len = INTVAL (operands[1]);
988 int bit = INTVAL (operands[2]);
999 xoperands[0] = operands[0];
1000 xoperands[1] = GEN_INT (mask);
1001 if (GET_CODE (operands[0]) == REG)
1002 output_asm_insn (\"btst %1,%0\", xoperands);
1004 output_asm_insn (\"btst %1,%A0\", xoperands);
1007 [(set_attr "cc" "set_zn_c0")])
1010 [(set (cc0) (and:SI (match_operand:SI 0 "register_operand" "d")
1011 (match_operand:SI 1 "const_int_operand" "")))]
1014 [(set_attr "cc" "set_zn_c0")])
1019 (subreg:SI (match_operand:QI 0 "general_operand" "R,d") 0)
1020 (match_operand:SI 1 "const_int_operand" "")))]
1025 [(set_attr "cc" "set_zn_c0")])
1027 ;; -----------------------------------------------------------------
1028 ;; -----------------------------------------------------------------
1030 ;; -----------------------------------------------------------------
1031 ;; It's probably worth the time to define setcc type insns too
1034 ;; ----------------------------------------------------------------------
1035 ;; JUMP INSTRUCTIONS
1036 ;; ----------------------------------------------------------------------
1038 ;; Conditional jump instructions
1040 (define_expand "ble"
1042 (if_then_else (le (cc0)
1044 (label_ref (match_operand 0 "" ""))
1049 (define_expand "bleu"
1051 (if_then_else (leu (cc0)
1053 (label_ref (match_operand 0 "" ""))
1058 (define_expand "bge"
1060 (if_then_else (ge (cc0)
1062 (label_ref (match_operand 0 "" ""))
1067 (define_expand "bgeu"
1069 (if_then_else (geu (cc0)
1071 (label_ref (match_operand 0 "" ""))
1076 (define_expand "blt"
1078 (if_then_else (lt (cc0)
1080 (label_ref (match_operand 0 "" ""))
1085 (define_expand "bltu"
1087 (if_then_else (ltu (cc0)
1089 (label_ref (match_operand 0 "" ""))
1094 (define_expand "bgt"
1096 (if_then_else (gt (cc0)
1098 (label_ref (match_operand 0 "" ""))
1103 (define_expand "bgtu"
1105 (if_then_else (gtu (cc0)
1107 (label_ref (match_operand 0 "" ""))
1112 (define_expand "beq"
1114 (if_then_else (eq (cc0)
1116 (label_ref (match_operand 0 "" ""))
1121 (define_expand "bne"
1123 (if_then_else (ne (cc0)
1125 (label_ref (match_operand 0 "" ""))
1132 (if_then_else (match_operator 1 "comparison_operator"
1133 [(cc0) (const_int 0)])
1134 (label_ref (match_operand 0 "" ""))
1139 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1140 && (GET_CODE (operands[1]) == GT
1141 || GET_CODE (operands[1]) == GE
1142 || GET_CODE (operands[1]) == LE
1143 || GET_CODE (operands[1]) == LT))
1147 [(set_attr "cc" "none")])
1151 (if_then_else (match_operator 1 "comparison_operator"
1152 [(cc0) (const_int 0)])
1154 (label_ref (match_operand 0 "" ""))))]
1158 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1159 && (GET_CODE (operands[1]) == GT
1160 || GET_CODE (operands[1]) == GE
1161 || GET_CODE (operands[1]) == LE
1162 || GET_CODE (operands[1]) == LT))
1166 [(set_attr "cc" "none")])
1168 ;; Unconditional and other jump instructions.
1172 (label_ref (match_operand 0 "" "")))]
1175 [(set_attr "cc" "none")])
1177 (define_insn "indirect_jump"
1178 [(set (pc) (match_operand:SI 0 "register_operand" "a"))]
1181 [(set_attr "cc" "none")])
1183 (define_insn "tablejump"
1184 [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1185 (use (label_ref (match_operand 1 "" "")))]
1188 [(set_attr "cc" "none")])
1190 ;; Call subroutine with no return value.
1192 (define_expand "call"
1193 [(call (match_operand:QI 0 "general_operand" "")
1194 (match_operand:SI 1 "general_operand" ""))]
1198 if (! call_address_operand (XEXP (operands[0], 0)))
1199 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
1200 emit_call_insn (gen_call_internal (XEXP (operands[0], 0), operands[1]));
1204 (define_insn "call_internal"
1205 [(call (mem:QI (match_operand:SI 0 "call_address_operand" "aS"))
1206 (match_operand:SI 1 "general_operand" "g"))]
1209 [(set_attr "cc" "clobber")])
1211 ;; Call subroutine, returning value in operand 0
1212 ;; (which must be a hard register).
1214 (define_expand "call_value"
1215 [(set (match_operand 0 "" "")
1216 (call (match_operand:QI 1 "general_operand" "")
1217 (match_operand:SI 2 "general_operand" "")))]
1221 if (! call_address_operand (XEXP (operands[1], 0)))
1222 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
1223 emit_call_insn (gen_call_value_internal (operands[0],
1224 XEXP (operands[1], 0),
1229 (define_insn "call_value_internal"
1230 [(set (match_operand 0 "" "=da")
1231 (call (mem:QI (match_operand:SI 1 "call_address_operand" "aS"))
1232 (match_operand:SI 2 "general_operand" "g")))]
1235 [(set_attr "cc" "clobber")])
1237 (define_expand "untyped_call"
1238 [(parallel [(call (match_operand 0 "" "")
1240 (match_operand 1 "" "")
1241 (match_operand 2 "" "")])]
1247 emit_call_insn (gen_call (operands[0], const0_rtx));
1249 for (i = 0; i < XVECLEN (operands[2], 0); i++)
1251 rtx set = XVECEXP (operands[2], 0, i);
1252 emit_move_insn (SET_DEST (set), SET_SRC (set));
1261 [(set_attr "cc" "none")])
1263 ;; ----------------------------------------------------------------------
1264 ;; EXTEND INSTRUCTIONS
1265 ;; ----------------------------------------------------------------------
1267 (define_insn "zero_extendqisi2"
1268 [(set (match_operand:SI 0 "general_operand" "=d,d,d")
1270 (match_operand:QI 1 "general_operand" "0,d,m")))]
1276 [(set_attr "cc" "none_0hit")])
1278 (define_insn "zero_extendhisi2"
1279 [(set (match_operand:SI 0 "general_operand" "=d,d,d")
1281 (match_operand:HI 1 "general_operand" "0,d,m")))]
1287 [(set_attr "cc" "none_0hit")])
1289 ;;- sign extension instructions
1291 (define_insn "extendqisi2"
1292 [(set (match_operand:SI 0 "general_operand" "=d,d")
1294 (match_operand:QI 1 "general_operand" "0,d")))]
1299 [(set_attr "cc" "none_0hit")])
1301 (define_insn "extendhisi2"
1302 [(set (match_operand:SI 0 "general_operand" "=d,d")
1304 (match_operand:HI 1 "general_operand" "0,d")))]
1309 [(set_attr "cc" "none_0hit")])
1311 ;; ----------------------------------------------------------------------
1313 ;; ----------------------------------------------------------------------
1315 (define_insn "ashlsi3"
1316 [(set (match_operand:SI 0 "register_operand" "=da,d,d,d,d")
1318 (match_operand:SI 1 "register_operand" "0,0,0,0,0")
1319 (match_operand:QI 2 "nonmemory_operand" "J,K,M,L,di")))]
1327 [(set_attr "cc" "set_zn_c0")])
1329 (define_insn "lshrsi3"
1330 [(set (match_operand:SI 0 "register_operand" "=d")
1332 (match_operand:SI 1 "register_operand" "0")
1333 (match_operand:QI 2 "nonmemory_operand" "di")))]
1336 [(set_attr "cc" "set_zn_c0")])
1338 (define_insn "ashrsi3"
1339 [(set (match_operand:SI 0 "register_operand" "=d")
1341 (match_operand:SI 1 "register_operand" "0")
1342 (match_operand:QI 2 "nonmemory_operand" "di")))]
1345 [(set_attr "cc" "set_zn_c0")])
1347 ;; ----------------------------------------------------------------------
1348 ;; PROLOGUE/EPILOGUE
1349 ;; ----------------------------------------------------------------------
1350 (define_expand "prologue"
1353 "expand_prologue (); DONE;")
1355 (define_expand "epilogue"
1364 (define_insn "return_internal"
1368 [(set_attr "cc" "clobber")])
1370 ;; This insn restores the callee saved registers and does a return, it
1371 ;; can also deallocate stack space.
1372 (define_insn "return_internal_regs"
1374 (match_operand:SI 0 "const_int_operand" "i")
1377 "ret [d2,d3,a2,a3],%0"
1378 [(set_attr "cc" "clobber")])
1380 (define_insn "store_movm"
1383 "movm [d2,d3,a2,a3],(sp)"
1384 [(set_attr "cc" "clobber")])
1386 (define_insn "return"
1388 "can_use_return_insn ()"
1391 rtx next = next_active_insn (insn);
1394 && GET_CODE (next) == JUMP_INSN
1395 && GET_CODE (PATTERN (next)) == RETURN)
1400 [(set_attr "cc" "clobber")])
1402 ;; Try to combine consecutive updates of the stack pointer (or any
1403 ;; other register for that matter).
1405 [(set (match_operand:SI 0 "register_operand" "=dax")
1406 (plus:SI (match_dup 0)
1407 (match_operand 1 "const_int_operand" "")))
1409 (plus:SI (match_dup 0)
1410 (match_operand 2 "const_int_operand" "")))]
1414 operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]));
1415 return \"add %1,%0\";
1417 [(set_attr "cc" "clobber")])
1420 ;; We had patterns to check eq/ne, but the they don't work because
1421 ;; 0x80000000 + 0x80000000 = 0x0 with a carry out.
1423 ;; The Z flag and C flag would be set, and we have no way to
1424 ;; check for the Z flag set and C flag clear.
1426 ;; This will work on the mn10200 because we can check the ZX flag
1427 ;; if the comparison is in HImode.
1429 [(set (cc0) (match_operand:SI 0 "register_operand" "d"))
1430 (set (pc) (if_then_else (ge (cc0) (const_int 0))
1431 (match_operand 1 "" "")
1433 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1435 [(set_attr "cc" "clobber")])
1438 [(set (cc0) (match_operand:SI 0 "register_operand" "d"))
1439 (set (pc) (if_then_else (lt (cc0) (const_int 0))
1440 (match_operand 1 "" "")
1442 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1444 [(set_attr "cc" "clobber")])
1447 [(set (cc0) (match_operand:SI 0 "register_operand" "d"))
1448 (set (pc) (if_then_else (ge (cc0) (const_int 0))
1450 (match_operand 1 "" "")))]
1451 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1453 [(set_attr "cc" "clobber")])
1456 [(set (cc0) (match_operand:SI 0 "register_operand" "d"))
1457 (set (pc) (if_then_else (lt (cc0) (const_int 0))
1459 (match_operand 1 "" "")))]
1460 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1462 [(set_attr "cc" "clobber")])