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 usable values; c is unusable.
34 ;; set_zn - insn sets z,n to usable values; v,c are unusable.
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")))]
736 return
\"nop\;nop\;mul %
2,%
0\";
738 return
\"mul %
2,%
0\";
740 [(set_attr "cc" "set_zn")])
742 (define_insn "udivmodsi4"
743 [(set (match_operand:SI
0 "general_operand" "=d")
744 (udiv:SI (match_operand:SI
1 "general_operand" "
0")
745 (match_operand:SI
2 "general_operand" "d")))
746 (set (match_operand:SI
3 "general_operand" "=&d")
747 (umod:SI (match_dup
1) (match_dup
2)))]
752 output_asm_insn (
\"mov %
0,mdr
\", &zero_dreg);
754 output_asm_insn (
\"sub %
3,%
3\;mov %
3,mdr
\", operands);
756 if (find_reg_note (insn, REG_UNUSED, operands[
3]))
757 return
\"divu %
2,%
0\";
759 return
\"divu %
2,%
0\;mov mdr,%
3\";
761 [(set_attr "cc" "set_zn")])
763 (define_insn "divmodsi4"
764 [(set (match_operand:SI
0 "general_operand" "=d")
765 (div:SI (match_operand:SI
1 "general_operand" "
0")
766 (match_operand:SI
2 "general_operand" "d")))
767 (set (match_operand:SI
3 "general_operand" "=d")
768 (mod:SI (match_dup
1) (match_dup
2)))]
772 if (find_reg_note (insn, REG_UNUSED, operands[
3]))
773 return
\"ext %
0\;div %
2,%
0\";
775 return
\"ext %
0\;div %
2,%
0\;mov mdr,%
3\";
777 [(set_attr "cc" "set_zn")])
780 ;; ----------------------------------------------------------------------
782 ;; ----------------------------------------------------------------------
784 (define_insn "andsi3"
785 [(set (match_operand:SI
0 "register_operand" "=d,d")
786 (and:SI (match_operand:SI
1 "register_operand" "%
0,
0")
787 (match_operand:SI
2 "nonmemory_operand" "N,di")))]
791 if (GET_CODE (operands[
2]) == CONST_INT && INTVAL (operands[
2]) ==
0xff)
793 if (GET_CODE (operands[
2]) == CONST_INT && INTVAL (operands[
2]) ==
0xffff)
795 if (GET_CODE (operands[
2]) == CONST_INT && INTVAL (operands[
2]) ==
0x7fffffff)
796 return
\"add %
0,%
0\;lsr
1,%
0\";
797 if (GET_CODE (operands[
2]) == CONST_INT && INTVAL (operands[
2]) ==
0x3fffffff)
798 return
\"asl2 %
0\;lsr
2,%
0\";
799 if (GET_CODE (operands[
2]) == CONST_INT && INTVAL (operands[
2]) ==
0x1fffffff)
800 return
\"add %
0,%
0\;asl2 %
0\;lsr
3,%
0\";
801 if (GET_CODE (operands[
2]) == CONST_INT && INTVAL (operands[
2]) ==
0x0fffffff)
802 return
\"asl2 %
0,%
0\;asl2 %
0\;lsr
4,%
0\";
803 if (GET_CODE (operands[
2]) == CONST_INT && INTVAL (operands[
2]) ==
0xfffffffe)
804 return
\"lsr
1,%
0\;add %
0,%
0\";
805 if (GET_CODE (operands[
2]) == CONST_INT && INTVAL (operands[
2]) ==
0xfffffffc)
806 return
\"lsr
2,%
0\;asl2 %
0\";
807 if (GET_CODE (operands[
2]) == CONST_INT && INTVAL (operands[
2]) ==
0xfffffff8)
808 return
\"lsr
3,%
0\;add %
0,%
0\;asl2 %
0\";
809 if (GET_CODE (operands[
2]) == CONST_INT && INTVAL (operands[
2]) ==
0xfffffff0)
810 return
\"lsr
4,%
0\;asl2 %
0\;asl2 %
0\";
811 return
\"and %
2,%
0\";
813 [(set_attr "cc" "none_0hit,set_znv")])
815 ;; ----------------------------------------------------------------------
817 ;; ----------------------------------------------------------------------
819 (define_insn "iorsi3"
820 [(set (match_operand:SI
0 "register_operand" "=d")
821 (ior:SI (match_operand:SI
1 "register_operand" "%
0")
822 (match_operand:SI
2 "nonmemory_operand" "di")))]
825 [(set_attr "cc" "set_znv")])
827 ;; ----------------------------------------------------------------------
829 ;; ----------------------------------------------------------------------
831 (define_insn "xorsi3"
832 [(set (match_operand:SI
0 "register_operand" "=d")
833 (xor:SI (match_operand:SI
1 "register_operand" "%
0")
834 (match_operand:SI
2 "nonmemory_operand" "di")))]
837 [(set_attr "cc" "set_znv")])
839 ;; ----------------------------------------------------------------------
841 ;; ----------------------------------------------------------------------
843 (define_insn "one_cmplsi2"
844 [(set (match_operand:SI
0 "register_operand" "=d")
845 (not:SI (match_operand:SI
1 "register_operand" "
0")))]
848 [(set_attr "cc" "set_znv")])
850 ;; -----------------------------------------------------------------
852 ;; -----------------------------------------------------------------
855 ;; These set/clear memory in byte sized chunks.
857 ;; They are no smaller/faster than loading the value into a register
858 ;; and storing the register, but they don't need a scratch register
859 ;; which may allow for better code generation.
861 [(set (match_operand:QI
0 "general_operand" "=R,d") (const_int
0))]
866 [(set_attr "cc" "clobber")])
869 [(set (match_operand:QI
0 "general_operand" "=R,d") (const_int -
1))]
874 [(set_attr "cc" "clobber,none_0hit")])
877 [(set (match_operand:QI
0 "general_operand" "=R,d")
879 (and:SI (subreg:SI (match_dup
0)
0)
880 (match_operand:SI
1 "const_int_operand" "i,i"))
0))]
885 [(set_attr "cc" "clobber,set_znv")])
888 [(set (match_operand:QI
0 "general_operand" "=R,d")
890 (ior:SI (subreg:SI (match_dup
0)
0)
891 (match_operand:SI
1 "const_int_operand" "i,i"))
0))]
896 [(set_attr "cc" "clobber,set_znv")])
900 (zero_extract:SI (match_operand:SI
0 "register_operand" "d")
901 (match_operand
1 "const_int_operand" "")
902 (match_operand
2 "const_int_operand" "")))]
906 int len = INTVAL (operands[
1]);
907 int bit = INTVAL (operands[
2]);
918 xoperands[
0] = operands[
0];
919 xoperands[
1] = GEN_INT (mask);
920 output_asm_insn (
\"btst %
1,%
0\", xoperands);
923 [(set_attr "cc" "set_znv")])
927 (zero_extract:SI (match_operand:QI
0 "general_operand" "R,d")
928 (match_operand
1 "const_int_operand" "")
929 (match_operand
2 "const_int_operand" "")))]
930 "mask_ok_for_mem_btst (INTVAL (operands[
1]), INTVAL (operands[
2]))"
933 int len = INTVAL (operands[
1]);
934 int bit = INTVAL (operands[
2]);
945 /* If the source operand is not a reg (ie it is memory), then extract the
946 bits from mask that we actually want to test. Note that the mask will
947 never cross a byte boundary. */
948 if (!REG_P (operands[
0]))
952 else if (mask &
0xff00)
953 mask = (mask >>
8) &
0xff;
954 else if (mask &
0xff0000)
955 mask = (mask >>
16) &
0xff;
956 else if (mask &
0xff000000)
957 mask = (mask >>
24) &
0xff;
960 xoperands[
0] = operands[
0];
961 xoperands[
1] = GEN_INT (mask);
962 if (GET_CODE (operands[
0]) == REG)
963 output_asm_insn (
\"btst %
1,%
0\", xoperands);
965 output_asm_insn (
\"btst %
1,%A0
\", xoperands);
968 [(set_attr "cc" "set_znv")])
971 [(set (cc0) (and:SI (match_operand:SI
0 "register_operand" "d")
972 (match_operand:SI
1 "const_int_operand" "")))]
975 [(set_attr "cc" "set_znv")])
980 (subreg:SI (match_operand:QI
0 "general_operand" "R,d")
0)
981 (match_operand:SI
1 "const_8bit_operand" "")))]
986 [(set_attr "cc" "set_znv")])
989 ;; ----------------------------------------------------------------------
991 ;; ----------------------------------------------------------------------
993 ;; Conditional jump instructions
997 (if_then_else (le (cc0)
999 (label_ref (match_operand
0 "" ""))
1004 (define_expand "bleu"
1006 (if_then_else (leu (cc0)
1008 (label_ref (match_operand
0 "" ""))
1013 (define_expand "bge"
1015 (if_then_else (ge (cc0)
1017 (label_ref (match_operand
0 "" ""))
1022 (define_expand "bgeu"
1024 (if_then_else (geu (cc0)
1026 (label_ref (match_operand
0 "" ""))
1031 (define_expand "blt"
1033 (if_then_else (lt (cc0)
1035 (label_ref (match_operand
0 "" ""))
1040 (define_expand "bltu"
1042 (if_then_else (ltu (cc0)
1044 (label_ref (match_operand
0 "" ""))
1049 (define_expand "bgt"
1051 (if_then_else (gt (cc0)
1053 (label_ref (match_operand
0 "" ""))
1058 (define_expand "bgtu"
1060 (if_then_else (gtu (cc0)
1062 (label_ref (match_operand
0 "" ""))
1067 (define_expand "beq"
1069 (if_then_else (eq (cc0)
1071 (label_ref (match_operand
0 "" ""))
1076 (define_expand "bne"
1078 (if_then_else (ne (cc0)
1080 (label_ref (match_operand
0 "" ""))
1087 (if_then_else (match_operator
1 "comparison_operator"
1088 [(cc0) (const_int
0)])
1089 (label_ref (match_operand
0 "" ""))
1094 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) !=
0
1095 && (GET_CODE (operands[
1]) == GT
1096 || GET_CODE (operands[
1]) == GE
1097 || GET_CODE (operands[
1]) == LE
1098 || GET_CODE (operands[
1]) == LT))
1102 [(set_attr "cc" "none")])
1106 (if_then_else (match_operator
1 "comparison_operator"
1107 [(cc0) (const_int
0)])
1109 (label_ref (match_operand
0 "" ""))))]
1113 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) !=
0
1114 && (GET_CODE (operands[
1]) == GT
1115 || GET_CODE (operands[
1]) == GE
1116 || GET_CODE (operands[
1]) == LE
1117 || GET_CODE (operands[
1]) == LT))
1121 [(set_attr "cc" "none")])
1123 ;; Unconditional and other jump instructions.
1127 (label_ref (match_operand
0 "" "")))]
1130 [(set_attr "cc" "none")])
1132 (define_insn "indirect_jump"
1133 [(set (pc) (match_operand:SI
0 "register_operand" "a"))]
1136 [(set_attr "cc" "none")])
1138 (define_insn "tablejump"
1139 [(set (pc) (match_operand:SI
0 "register_operand" "a"))
1140 (use (label_ref (match_operand
1 "" "")))]
1143 [(set_attr "cc" "none")])
1145 ;; Call subroutine with no return value.
1147 (define_expand "call"
1148 [(call (match_operand:QI
0 "general_operand" "")
1149 (match_operand:SI
1 "general_operand" ""))]
1153 if (! call_address_operand (XEXP (operands[
0],
0)))
1154 XEXP (operands[
0],
0) = force_reg (SImode, XEXP (operands[
0],
0));
1155 emit_call_insn (gen_call_internal (XEXP (operands[
0],
0), operands[
1]));
1159 (define_insn "call_internal"
1160 [(call (mem:QI (match_operand:SI
0 "call_address_operand" "aS"))
1161 (match_operand:SI
1 "general_operand" "g"))]
1165 if (REG_P (operands[
0]))
1166 return
\"calls %C0
\";
1168 return
\"call %C0,[],
0\";
1170 [(set_attr "cc" "clobber")])
1172 ;; Call subroutine, returning value in operand
0
1173 ;; (which must be a hard register).
1175 (define_expand "call_value"
1176 [(set (match_operand
0 "" "")
1177 (call (match_operand:QI
1 "general_operand" "")
1178 (match_operand:SI
2 "general_operand" "")))]
1182 if (! call_address_operand (XEXP (operands[
1],
0)))
1183 XEXP (operands[
1],
0) = force_reg (SImode, XEXP (operands[
1],
0));
1184 emit_call_insn (gen_call_value_internal (operands[
0],
1185 XEXP (operands[
1],
0),
1190 (define_insn "call_value_internal"
1191 [(set (match_operand
0 "" "=da")
1192 (call (mem:QI (match_operand:SI
1 "call_address_operand" "aS"))
1193 (match_operand:SI
2 "general_operand" "g")))]
1197 if (REG_P (operands[
1]))
1198 return
\"calls %C1
\";
1200 return
\"call %C1,[],
0\";
1202 [(set_attr "cc" "clobber")])
1204 (define_expand "untyped_call"
1205 [(parallel [(call (match_operand
0 "" "")
1207 (match_operand
1 "" "")
1208 (match_operand
2 "" "")])]
1214 emit_call_insn (gen_call (operands[
0], const0_rtx));
1216 for (i =
0; i < XVECLEN (operands[
2],
0); i++)
1218 rtx set = XVECEXP (operands[
2],
0, i);
1219 emit_move_insn (SET_DEST (set), SET_SRC (set));
1228 [(set_attr "cc" "none")])
1230 ;; ----------------------------------------------------------------------
1231 ;; EXTEND INSTRUCTIONS
1232 ;; ----------------------------------------------------------------------
1234 (define_insn "zero_extendqisi2"
1235 [(set (match_operand:SI
0 "general_operand" "=d,d,d")
1237 (match_operand:QI
1 "general_operand" "
0,d,m")))]
1243 [(set_attr "cc" "none_0hit")])
1245 (define_insn "zero_extendhisi2"
1246 [(set (match_operand:SI
0 "general_operand" "=d,d,d")
1248 (match_operand:HI
1 "general_operand" "
0,d,m")))]
1254 [(set_attr "cc" "none_0hit")])
1256 ;;- sign extension instructions
1258 (define_insn "extendqisi2"
1259 [(set (match_operand:SI
0 "general_operand" "=d,d")
1261 (match_operand:QI
1 "general_operand" "
0,d")))]
1266 [(set_attr "cc" "none_0hit")])
1268 (define_insn "extendhisi2"
1269 [(set (match_operand:SI
0 "general_operand" "=d,d")
1271 (match_operand:HI
1 "general_operand" "
0,d")))]
1276 [(set_attr "cc" "none_0hit")])
1278 ;; ----------------------------------------------------------------------
1280 ;; ----------------------------------------------------------------------
1282 (define_insn "ashlsi3"
1283 [(set (match_operand:SI
0 "register_operand" "=da,d,d,d,d")
1285 (match_operand:SI
1 "register_operand" "
0,
0,
0,
0,
0")
1286 (match_operand:QI
2 "nonmemory_operand" "J,K,M,L,di")))]
1294 [(set_attr "cc" "set_zn")])
1296 (define_insn "lshrsi3"
1297 [(set (match_operand:SI
0 "register_operand" "=d")
1299 (match_operand:SI
1 "register_operand" "
0")
1300 (match_operand:QI
2 "nonmemory_operand" "di")))]
1303 [(set_attr "cc" "set_zn")])
1305 (define_insn "ashrsi3"
1306 [(set (match_operand:SI
0 "register_operand" "=d")
1308 (match_operand:SI
1 "register_operand" "
0")
1309 (match_operand:QI
2 "nonmemory_operand" "di")))]
1312 [(set_attr "cc" "set_zn")])
1314 ;; ----------------------------------------------------------------------
1315 ;; PROLOGUE/EPILOGUE
1316 ;; ----------------------------------------------------------------------
1317 (define_expand "prologue"
1320 "expand_prologue (); DONE;")
1322 (define_expand "epilogue"
1331 (define_insn "return_internal"
1335 [(set_attr "cc" "clobber")])
1337 ;; This insn restores the callee saved registers and does a return, it
1338 ;; can also deallocate stack space.
1339 (define_insn "return_internal_regs"
1341 (match_operand:SI
0 "const_int_operand" "i")
1344 "ret [d2,d3,a2,a3],%
0"
1345 [(set_attr "cc" "clobber")])
1347 (define_insn "store_movm"
1350 "movm [d2,d3,a2,a3],(sp)"
1351 [(set_attr "cc" "clobber")])
1353 (define_insn "return"
1355 "can_use_return_insn ()"
1358 rtx next = next_active_insn (insn);
1361 && GET_CODE (next) == JUMP_INSN
1362 && GET_CODE (PATTERN (next)) == RETURN)
1367 [(set_attr "cc" "clobber")])
1369 ;; Try to combine consecutive updates of the stack pointer (or any
1370 ;; other register for that matter).
1372 [(set (match_operand:SI
0 "register_operand" "=dax")
1373 (plus:SI (match_dup
0)
1374 (match_operand
1 "const_int_operand" "")))
1376 (plus:SI (match_dup
0)
1377 (match_operand
2 "const_int_operand" "")))]
1381 operands[
1] = GEN_INT (INTVAL (operands[
2]) + INTVAL (operands[
1]));
1382 return
\"add %
1,%
0\";
1384 [(set_attr "cc" "clobber")])
1387 ;; We had patterns to check eq/ne, but the they don't work because
1388 ;;
0x80000000 +
0x80000000 =
0x0 with a carry out.
1390 ;; The Z flag and C flag would be set, and we have no way to
1391 ;; check for the Z flag set and C flag clear.
1393 ;; This will work on the mn10200 because we can check the ZX flag
1394 ;; if the comparison is in HImode.
1396 [(set (cc0) (match_operand:SI
0 "register_operand" "d"))
1397 (set (pc) (if_then_else (ge (cc0) (const_int
0))
1398 (match_operand
1 "" "")
1400 "dead_or_set_p (ins1, operands[
0]) && REG_OK_FOR_INDEX_P (operands[
0])"
1402 [(set_attr "cc" "clobber")])
1405 [(set (cc0) (match_operand:SI
0 "register_operand" "d"))
1406 (set (pc) (if_then_else (lt (cc0) (const_int
0))
1407 (match_operand
1 "" "")
1409 "dead_or_set_p (ins1, operands[
0]) && REG_OK_FOR_INDEX_P (operands[
0])"
1411 [(set_attr "cc" "clobber")])
1414 [(set (cc0) (match_operand:SI
0 "register_operand" "d"))
1415 (set (pc) (if_then_else (ge (cc0) (const_int
0))
1417 (match_operand
1 "" "")))]
1418 "dead_or_set_p (ins1, operands[
0]) && REG_OK_FOR_INDEX_P (operands[
0])"
1420 [(set_attr "cc" "clobber")])
1423 [(set (cc0) (match_operand:SI
0 "register_operand" "d"))
1424 (set (pc) (if_then_else (lt (cc0) (const_int
0))
1426 (match_operand
1 "" "")))]
1427 "dead_or_set_p (ins1, operands[
0]) && REG_OK_FOR_INDEX_P (operands[
0])"
1429 [(set_attr "cc" "clobber")])