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" "=dx,*a,dx,*a,dx,*a,dx,*a,dx,m")
61 (match_operand:QI 1 "general_operand" "0,0,I,I,a,dx,dxi,ia,m,dx"))]
62 "register_operand (operands[0], QImode)
63 || register_operand (operands[1], QImode)"
66 switch (which_alternative)
78 if (GET_CODE (operands[1]) == CONST_DOUBLE)
81 xoperands[0] = operands[0];
82 xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
83 output_asm_insn (\"mov %1,%0\", xoperands);
90 return \"movbu %1,%0\";
93 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
97 (define_expand "movhi"
98 [(set (match_operand:HI 0 "general_operand" "")
99 (match_operand:HI 1 "general_operand" ""))]
103 /* One of the ops has to be in a register */
104 if (!register_operand (operand1, HImode)
105 && !register_operand (operand0, HImode))
106 operands[1] = copy_to_mode_reg (HImode, operand1);
110 [(set (match_operand:HI 0 "general_operand" "=dx,*a,dx,*a,dx,*a,dx,*a,dx,m")
111 (match_operand:HI 1 "general_operand" "0,0,I,I,a,dx,dxi,ia,m,dx"))]
112 "register_operand (operands[0], HImode)
113 || register_operand (operands[1], HImode)"
116 switch (which_alternative)
128 if (GET_CODE (operands[1]) == CONST_DOUBLE)
131 xoperands[0] = operands[0];
132 xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
133 output_asm_insn (\"mov %1,%0\", xoperands);
136 return \"mov %1,%0\";
139 return \"movhu %1,%0\";
142 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
146 ;; We use this to handle addition of two values when one operand is the
147 ;; stack pointer and the other is a memory reference of some kind. Reload
148 ;; does not handle them correctly without this expander.
149 (define_expand "reload_insi"
150 [(set (match_operand:SI 0 "register_operand" "=a")
151 (match_operand:SI 1 "impossible_plus_operand" ""))
152 (clobber (match_operand:SI 2 "register_operand" "=&r"))]
156 if (XEXP (operands[1], 0) == stack_pointer_rtx)
158 emit_move_insn (operands[0], XEXP (operands[1], 0));
159 if (GET_CODE (XEXP (operands[1], 1)) == SUBREG
160 && (GET_MODE_SIZE (GET_MODE (XEXP (operands[1], 1)))
161 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (operands[1], 1))))))
162 emit_move_insn (operands[2],
163 gen_rtx (ZERO_EXTEND, GET_MODE (XEXP (operands[1], 1)),
164 SUBREG_REG (XEXP (operands[1], 1))));
166 emit_move_insn (operands[2], XEXP (operands[1], 1));
170 emit_move_insn (operands[0], XEXP (operands[1], 1));
171 if (GET_CODE (XEXP (operands[1], 0)) == SUBREG
172 && (GET_MODE_SIZE (GET_MODE (XEXP (operands[1], 0)))
173 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (operands[1], 0))))))
174 emit_move_insn (operands[2],
175 gen_rtx (ZERO_EXTEND, GET_MODE (XEXP (operands[1], 0)),
176 SUBREG_REG (XEXP (operands[1], 0))));
178 emit_move_insn (operands[2], XEXP (operands[1], 0));
180 emit_insn (gen_addsi3 (operands[0], operands[0], operands[2]));
184 (define_expand "movsi"
185 [(set (match_operand:SI 0 "general_operand" "")
186 (match_operand:SI 1 "general_operand" ""))]
190 /* One of the ops has to be in a register */
191 if (!register_operand (operand1, SImode)
192 && !register_operand (operand0, SImode))
193 operands[1] = copy_to_mode_reg (SImode, operand1);
197 [(set (match_operand:SI 0 "general_operand"
198 "=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax,axR,y")
199 (match_operand:SI 1 "general_operand"
200 "0,0,I,I,dx,ax,dx,ax,dixm,aixm,dixm,aixm,xy,axR"))]
201 "register_operand (operands[0], SImode)
202 || register_operand (operands[1], SImode)"
205 switch (which_alternative)
223 if (GET_CODE (operands[1]) == CONST_DOUBLE)
226 xoperands[0] = operands[0];
227 xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
228 output_asm_insn (\"mov %1,%0\", xoperands);
231 return \"mov %1,%0\";
234 [(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")])
236 (define_expand "movsf"
237 [(set (match_operand:SF 0 "general_operand" "")
238 (match_operand:SF 1 "general_operand" ""))]
242 /* One of the ops has to be in a register */
243 if (!register_operand (operand1, SFmode)
244 && !register_operand (operand0, SFmode))
245 operands[1] = copy_to_mode_reg (SFmode, operand1);
249 [(set (match_operand:SF 0 "general_operand" "=dx,ax,dx,a,daxm,dax")
250 (match_operand:SF 1 "general_operand" "0,0,G,G,dax,daxim"))]
251 "register_operand (operands[0], SFmode)
252 || register_operand (operands[1], SFmode)"
255 switch (which_alternative)
265 return \"mov %1,%0\";
268 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit")])
270 (define_expand "movdi"
271 [(set (match_operand:DI 0 "general_operand" "")
272 (match_operand:DI 1 "general_operand" ""))]
276 /* One of the ops has to be in a register */
277 if (!register_operand (operand1, DImode)
278 && !register_operand (operand0, DImode))
279 operands[1] = copy_to_mode_reg (DImode, operand1);
283 [(set (match_operand:DI 0 "general_operand"
284 "=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax")
285 (match_operand:DI 1 "general_operand"
286 "0,0,I,I,dx,ax,dx,ax,dxim,axim,dxim,axim"))]
287 "register_operand (operands[0], DImode)
288 || register_operand (operands[1], DImode)"
294 switch (which_alternative)
301 return \"clr %L0\;clr %H0\";
304 if (rtx_equal_p (operands[0], operands[1]))
305 return \"sub %L1,%L0\;mov %L0,%H0\";
307 return \"mov %1,%L0\;mov %L0,%H0\";
316 if (GET_CODE (operands[1]) == CONST_INT)
318 val[0] = INTVAL (operands[1]);
319 val[1] = val[0] < 0 ? -1 : 0;
321 if (GET_CODE (operands[1]) == CONST_DOUBLE)
323 if (GET_MODE (operands[1]) == DFmode)
325 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
326 REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
328 else if (GET_MODE (operands[1]) == VOIDmode
329 || GET_MODE (operands[1]) == DImode)
331 val[0] = CONST_DOUBLE_LOW (operands[1]);
332 val[1] = CONST_DOUBLE_HIGH (operands[1]);
336 if (GET_CODE (operands[1]) == MEM
337 && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
339 rtx temp = operands[0];
341 while (GET_CODE (temp) == SUBREG)
342 temp = SUBREG_REG (temp);
344 if (GET_CODE (temp) != REG)
347 if (reg_overlap_mentioned_p (gen_rtx (REG, SImode, REGNO (temp)),
348 XEXP (operands[1], 0)))
349 return \"mov %H1,%H0\;mov %L1,%L0\";
351 return \"mov %L1,%L0\;mov %H1,%H0\";
354 else if (GET_CODE (operands[1]) == MEM
355 && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
356 && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
360 xoperands[0] = operands[0];
361 xoperands[1] = XEXP (operands[1], 0);
363 output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\",
369 if ((GET_CODE (operands[1]) == CONST_INT
370 || GET_CODE (operands[1]) == CONST_DOUBLE)
373 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
374 output_asm_insn (\"clr %L0\", operands);
376 output_asm_insn (\"mov %L1,%L0\", operands);
379 output_asm_insn (\"mov %L1,%L0\", operands);
381 if ((GET_CODE (operands[1]) == CONST_INT
382 || GET_CODE (operands[1]) == CONST_DOUBLE)
385 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
386 output_asm_insn (\"clr %H0\", operands);
388 output_asm_insn (\"mov %H1,%H0\", operands);
390 else if ((GET_CODE (operands[1]) == CONST_INT
391 || GET_CODE (operands[1]) == CONST_DOUBLE)
393 output_asm_insn (\"mov %L0,%H0\", operands);
395 output_asm_insn (\"mov %H1,%H0\", operands);
400 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
402 (define_expand "movdf"
403 [(set (match_operand:DF 0 "general_operand" "")
404 (match_operand:DF 1 "general_operand" ""))]
408 /* One of the ops has to be in a register */
409 if (!register_operand (operand1, DFmode)
410 && !register_operand (operand0, DFmode))
411 operands[1] = copy_to_mode_reg (DFmode, operand1);
415 [(set (match_operand:DF 0 "general_operand"
416 "=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax")
417 (match_operand:DF 1 "general_operand"
418 "0,0,G,G,dx,ax,dx,ax,dxim,axim,dxim,axim"))]
419 "register_operand (operands[0], DFmode)
420 || register_operand (operands[1], DFmode)"
426 switch (which_alternative)
433 return \"clr %L0\;clr %H0\";
436 if (rtx_equal_p (operands[0], operands[1]))
437 return \"sub %L1,%L0\;mov %L0,%H0\";
439 return \"mov %1,%L0\;mov %L0,%H0\";
448 if (GET_CODE (operands[1]) == CONST_INT)
450 val[0] = INTVAL (operands[1]);
451 val[1] = val[0] < 0 ? -1 : 0;
453 if (GET_CODE (operands[1]) == CONST_DOUBLE)
455 if (GET_MODE (operands[1]) == DFmode)
457 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
458 REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
460 else if (GET_MODE (operands[1]) == VOIDmode
461 || GET_MODE (operands[1]) == DImode)
463 val[0] = CONST_DOUBLE_LOW (operands[1]);
464 val[1] = CONST_DOUBLE_HIGH (operands[1]);
468 if (GET_CODE (operands[1]) == MEM
469 && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
471 rtx temp = operands[0];
473 while (GET_CODE (temp) == SUBREG)
474 temp = SUBREG_REG (temp);
476 if (GET_CODE (temp) != REG)
479 if (reg_overlap_mentioned_p (gen_rtx (REG, SImode, REGNO (temp)),
480 XEXP (operands[1], 0)))
481 return \"mov %H1,%H0\;mov %L1,%L0\";
483 return \"mov %L1,%L0\;mov %H1,%H0\";
486 else if (GET_CODE (operands[1]) == MEM
487 && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
488 && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
492 xoperands[0] = operands[0];
493 xoperands[1] = XEXP (operands[1], 0);
495 output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\",
501 if ((GET_CODE (operands[1]) == CONST_INT
502 || GET_CODE (operands[1]) == CONST_DOUBLE)
505 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
506 output_asm_insn (\"clr %L0\", operands);
508 output_asm_insn (\"mov %L1,%L0\", operands);
511 output_asm_insn (\"mov %L1,%L0\", operands);
513 if ((GET_CODE (operands[1]) == CONST_INT
514 || GET_CODE (operands[1]) == CONST_DOUBLE)
517 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
518 output_asm_insn (\"clr %H0\", operands);
520 output_asm_insn (\"mov %H1,%H0\", operands);
522 else if ((GET_CODE (operands[1]) == CONST_INT
523 || GET_CODE (operands[1]) == CONST_DOUBLE)
525 output_asm_insn (\"mov %L0,%H0\", operands);
527 output_asm_insn (\"mov %H1,%H0\", operands);
532 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
536 ;; ----------------------------------------------------------------------
538 ;; ----------------------------------------------------------------------
540 ;; Go ahead and define tstsi so we can eliminate redundant tst insns
541 ;; when we start trying to optimize this port.
543 [(set (cc0) (match_operand:SI 0 "register_operand" "dax"))]
545 "* return output_tst (operands[0], insn);"
546 [(set_attr "cc" "set_znv")])
549 [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "dx")))]
551 "* return output_tst (operands[0], insn);"
552 [(set_attr "cc" "set_znv")])
555 [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "dx")))]
557 "* return output_tst (operands[0], insn);"
558 [(set_attr "cc" "set_znv")])
563 (compare (match_operand:SI 0 "register_operand" "!*d*a*x,dax")
564 (match_operand:SI 1 "nonmemory_operand" "!*0,daxi")))]
569 [(set_attr "cc" "invert,compare")])
571 ;; ----------------------------------------------------------------------
573 ;; ----------------------------------------------------------------------
575 (define_expand "addsi3"
576 [(set (match_operand:SI 0 "register_operand" "")
577 (plus:SI (match_operand:SI 1 "register_operand" "")
578 (match_operand:SI 2 "nonmemory_operand" "")))]
582 /* We can't add a variable amount directly to the stack pointer;
583 so do so via a temporary register. */
584 if (operands[0] == stack_pointer_rtx
585 && GET_CODE (operands[1]) != CONST_INT
586 && GET_CODE (operands[2]) != CONST_INT)
588 rtx temp = gen_reg_rtx (SImode);
589 emit_move_insn (temp, gen_rtx (PLUS, SImode, operands[1], operands[2]));
590 emit_move_insn (operands[0], temp);
596 [(set (match_operand:SI 0 "register_operand" "=dx,ax,ax,dax,xy,!dax")
597 (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,dax")
598 (match_operand:SI 2 "nonmemory_operand" "J,J,L,daxi,i,dax")))]
602 switch (which_alternative)
611 return \"add %2,%0\";
613 /* I'm not sure if this can happen or not. Might as well be prepared
614 and generate the best possible code if it does happen. */
615 if (true_regnum (operands[0]) == true_regnum (operands[1]))
616 return \"add %2,%0\";
617 if (true_regnum (operands[0]) == true_regnum (operands[2]))
618 return \"add %1,%0\";
620 /* We have to copy one of the sources into the destination, then add
621 the other source to the destination.
623 Carefully select which source to copy to the destination; a naive
624 implementation will waste a byte when the source classes are different
625 and the destination is an address register. Selecting the lowest
626 cost register copy will optimize this sequence. */
627 if (REGNO_REG_CLASS (true_regnum (operands[1]))
628 == REGNO_REG_CLASS (true_regnum (operands[0])))
629 return \"mov %1,%0\;add %2,%0\";
630 return \"mov %2,%0\;add %1,%0\";
633 [(set_attr "cc" "set_zn,none_0hit,none_0hit,set_zn,none_0hit,set_zn")])
635 ;; ----------------------------------------------------------------------
636 ;; SUBTRACT INSTRUCTIONS
637 ;; ----------------------------------------------------------------------
639 (define_expand "subsi3"
640 [(set (match_operand:SI 0 "register_operand" "")
641 (minus:SI (match_operand:SI 1 "register_operand" "")
642 (match_operand:SI 2 "nonmemory_operand" "")))]
647 [(set (match_operand:SI 0 "register_operand" "=dax")
648 (minus:SI (match_operand:SI 1 "register_operand" "0")
649 (match_operand:SI 2 "nonmemory_operand" "daxi")))]
652 [(set_attr "cc" "set_zn")])
654 (define_expand "negsi2"
655 [(set (match_operand:SI 0 "register_operand" "")
656 (neg:SI (match_operand:SI 1 "register_operand" "")))]
660 rtx target = gen_reg_rtx (SImode);
662 emit_move_insn (target, GEN_INT (0));
663 emit_insn (gen_subsi3 (target, target, operands[1]));
664 emit_move_insn (operands[0], target);
668 ;; ----------------------------------------------------------------------
669 ;; MULTIPLY INSTRUCTIONS
670 ;; ----------------------------------------------------------------------
672 (define_expand "mulsi3"
673 [(set (match_operand:SI 0 "register_operand" "")
674 (mult:SI (match_operand:SI 1 "register_operand" "")
675 (match_operand:SI 2 "register_operand" "")))]
680 [(set (match_operand:SI 0 "register_operand" "=dx")
681 (mult:SI (match_operand:SI 1 "register_operand" "%0")
682 (match_operand:SI 2 "register_operand" "dx")))]
687 return \"nop\;nop\;mul %2,%0\";
689 return \"mul %2,%0\";
691 [(set_attr "cc" "set_zn")])
693 (define_insn "udivmodsi4"
694 [(set (match_operand:SI 0 "general_operand" "=dx")
695 (udiv:SI (match_operand:SI 1 "general_operand" "0")
696 (match_operand:SI 2 "general_operand" "dx")))
697 (set (match_operand:SI 3 "general_operand" "=&d")
698 (umod:SI (match_dup 1) (match_dup 2)))]
702 output_asm_insn (\"sub %3,%3\;mov %3,mdr\", operands);
704 if (find_reg_note (insn, REG_UNUSED, operands[3]))
705 return \"divu %2,%0\";
707 return \"divu %2,%0\;mov mdr,%3\";
709 [(set_attr "cc" "set_zn")])
711 (define_insn "divmodsi4"
712 [(set (match_operand:SI 0 "general_operand" "=dx")
713 (div:SI (match_operand:SI 1 "general_operand" "0")
714 (match_operand:SI 2 "general_operand" "dx")))
715 (set (match_operand:SI 3 "general_operand" "=d")
716 (mod:SI (match_dup 1) (match_dup 2)))]
720 if (find_reg_note (insn, REG_UNUSED, operands[3]))
721 return \"ext %0\;div %2,%0\";
723 return \"ext %0\;div %2,%0\;mov mdr,%3\";
725 [(set_attr "cc" "set_zn")])
728 ;; ----------------------------------------------------------------------
730 ;; ----------------------------------------------------------------------
732 (define_expand "andsi3"
733 [(set (match_operand:SI 0 "register_operand" "")
734 (and:SI (match_operand:SI 1 "register_operand" "")
735 (match_operand:SI 2 "nonmemory_operand" "")))]
740 [(set (match_operand:SI 0 "register_operand" "=dx,dx")
741 (and:SI (match_operand:SI 1 "register_operand" "%0,0")
742 (match_operand:SI 2 "nonmemory_operand" "N,dxi")))]
746 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff)
748 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xffff)
750 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x7fffffff)
751 return \"add %0,%0\;lsr 1,%0\";
752 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x3fffffff)
753 return \"asl2 %0\;lsr 2,%0\";
754 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x1fffffff)
755 return \"add %0,%0\;asl2 %0\;lsr 3,%0\";
756 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x0fffffff)
757 return \"asl2 %0\;asl2 %0\;lsr 4,%0\";
758 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffe)
759 return \"lsr 1,%0\;add %0,%0\";
760 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffc)
761 return \"lsr 2,%0\;asl2 %0\";
762 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff8)
763 return \"lsr 3,%0\;add %0,%0\;asl2 %0\";
764 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff0)
765 return \"lsr 4,%0\;asl2 %0\;asl2 %0\";
766 return \"and %2,%0\";
768 [(set_attr "cc" "none_0hit,set_znv")])
770 ;; ----------------------------------------------------------------------
772 ;; ----------------------------------------------------------------------
774 (define_expand "iorsi3"
775 [(set (match_operand:SI 0 "register_operand" "")
776 (ior:SI (match_operand:SI 1 "register_operand" "")
777 (match_operand:SI 2 "nonmemory_operand" "")))]
782 [(set (match_operand:SI 0 "register_operand" "=dx")
783 (ior:SI (match_operand:SI 1 "register_operand" "%0")
784 (match_operand:SI 2 "nonmemory_operand" "dxi")))]
787 [(set_attr "cc" "set_znv")])
789 ;; ----------------------------------------------------------------------
791 ;; ----------------------------------------------------------------------
793 (define_expand "xorsi3"
794 [(set (match_operand:SI 0 "register_operand" "")
795 (xor:SI (match_operand:SI 1 "register_operand" "")
796 (match_operand:SI 2 "nonmemory_operand" "")))]
801 [(set (match_operand:SI 0 "register_operand" "=dx")
802 (xor:SI (match_operand:SI 1 "register_operand" "%0")
803 (match_operand:SI 2 "nonmemory_operand" "dxi")))]
806 [(set_attr "cc" "set_znv")])
808 ;; ----------------------------------------------------------------------
810 ;; ----------------------------------------------------------------------
812 (define_expand "one_cmplsi2"
813 [(set (match_operand:SI 0 "register_operand" "")
814 (not:SI (match_operand:SI 1 "register_operand" "")))]
819 [(set (match_operand:SI 0 "register_operand" "=dx")
820 (not:SI (match_operand:SI 1 "register_operand" "0")))]
823 [(set_attr "cc" "set_znv")])
825 ;; -----------------------------------------------------------------
827 ;; -----------------------------------------------------------------
830 ;; These set/clear memory in byte sized chunks.
832 ;; They are no smaller/faster than loading the value into a register
833 ;; and storing the register, but they don't need a scratch register
834 ;; which may allow for better code generation.
836 [(set (match_operand:QI 0 "general_operand" "=R,d") (const_int 0))]
841 [(set_attr "cc" "clobber")])
844 [(set (match_operand:QI 0 "general_operand" "=R,d") (const_int -1))]
849 [(set_attr "cc" "clobber,none_0hit")])
852 [(set (match_operand:QI 0 "general_operand" "=R,d")
854 (and:SI (subreg:SI (match_dup 0) 0)
855 (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
860 [(set_attr "cc" "clobber,set_znv")])
863 [(set (match_operand:QI 0 "general_operand" "=R,d")
865 (ior:SI (subreg:SI (match_dup 0) 0)
866 (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
871 [(set_attr "cc" "clobber,set_znv")])
875 (zero_extract:SI (match_operand:SI 0 "register_operand" "dx")
876 (match_operand 1 "const_int_operand" "")
877 (match_operand 2 "const_int_operand" "")))]
881 int len = INTVAL (operands[1]);
882 int bit = INTVAL (operands[2]);
893 xoperands[0] = operands[0];
894 xoperands[1] = GEN_INT (mask);
895 output_asm_insn (\"btst %1,%0\", xoperands);
898 [(set_attr "cc" "set_znv")])
902 (zero_extract:SI (match_operand:QI 0 "general_operand" "R,dx")
903 (match_operand 1 "const_int_operand" "")
904 (match_operand 2 "const_int_operand" "")))]
905 "mask_ok_for_mem_btst (INTVAL (operands[1]), INTVAL (operands[2]))"
908 int len = INTVAL (operands[1]);
909 int bit = INTVAL (operands[2]);
920 /* If the source operand is not a reg (ie it is memory), then extract the
921 bits from mask that we actually want to test. Note that the mask will
922 never cross a byte boundary. */
923 if (!REG_P (operands[0]))
927 else if (mask & 0xff00)
928 mask = (mask >> 8) & 0xff;
929 else if (mask & 0xff0000)
930 mask = (mask >> 16) & 0xff;
931 else if (mask & 0xff000000)
932 mask = (mask >> 24) & 0xff;
935 xoperands[0] = operands[0];
936 xoperands[1] = GEN_INT (mask);
937 if (GET_CODE (operands[0]) == REG)
938 output_asm_insn (\"btst %1,%0\", xoperands);
940 output_asm_insn (\"btst %1,%A0\", xoperands);
943 [(set_attr "cc" "set_znv")])
946 [(set (cc0) (and:SI (match_operand:SI 0 "register_operand" "dx")
947 (match_operand:SI 1 "const_int_operand" "")))]
950 [(set_attr "cc" "set_znv")])
955 (subreg:SI (match_operand:QI 0 "general_operand" "R,dx") 0)
956 (match_operand:SI 1 "const_8bit_operand" "")))]
961 [(set_attr "cc" "set_znv")])
964 ;; ----------------------------------------------------------------------
966 ;; ----------------------------------------------------------------------
968 ;; Conditional jump instructions
972 (if_then_else (le (cc0)
974 (label_ref (match_operand 0 "" ""))
979 (define_expand "bleu"
981 (if_then_else (leu (cc0)
983 (label_ref (match_operand 0 "" ""))
990 (if_then_else (ge (cc0)
992 (label_ref (match_operand 0 "" ""))
997 (define_expand "bgeu"
999 (if_then_else (geu (cc0)
1001 (label_ref (match_operand 0 "" ""))
1006 (define_expand "blt"
1008 (if_then_else (lt (cc0)
1010 (label_ref (match_operand 0 "" ""))
1015 (define_expand "bltu"
1017 (if_then_else (ltu (cc0)
1019 (label_ref (match_operand 0 "" ""))
1024 (define_expand "bgt"
1026 (if_then_else (gt (cc0)
1028 (label_ref (match_operand 0 "" ""))
1033 (define_expand "bgtu"
1035 (if_then_else (gtu (cc0)
1037 (label_ref (match_operand 0 "" ""))
1042 (define_expand "beq"
1044 (if_then_else (eq (cc0)
1046 (label_ref (match_operand 0 "" ""))
1051 (define_expand "bne"
1053 (if_then_else (ne (cc0)
1055 (label_ref (match_operand 0 "" ""))
1062 (if_then_else (match_operator 1 "comparison_operator"
1063 [(cc0) (const_int 0)])
1064 (label_ref (match_operand 0 "" ""))
1069 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1070 && (GET_CODE (operands[1]) == GT
1071 || GET_CODE (operands[1]) == GE
1072 || GET_CODE (operands[1]) == LE
1073 || GET_CODE (operands[1]) == LT))
1077 [(set_attr "cc" "none")])
1081 (if_then_else (match_operator 1 "comparison_operator"
1082 [(cc0) (const_int 0)])
1084 (label_ref (match_operand 0 "" ""))))]
1088 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1089 && (GET_CODE (operands[1]) == GT
1090 || GET_CODE (operands[1]) == GE
1091 || GET_CODE (operands[1]) == LE
1092 || GET_CODE (operands[1]) == LT))
1096 [(set_attr "cc" "none")])
1098 ;; Unconditional and other jump instructions.
1102 (label_ref (match_operand 0 "" "")))]
1105 [(set_attr "cc" "none")])
1107 (define_insn "indirect_jump"
1108 [(set (pc) (match_operand:SI 0 "register_operand" "a"))]
1111 [(set_attr "cc" "none")])
1113 (define_insn "tablejump"
1114 [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1115 (use (label_ref (match_operand 1 "" "")))]
1118 [(set_attr "cc" "none")])
1120 ;; Call subroutine with no return value.
1122 (define_expand "call"
1123 [(call (match_operand:QI 0 "general_operand" "")
1124 (match_operand:SI 1 "general_operand" ""))]
1128 if (! call_address_operand (XEXP (operands[0], 0)))
1129 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
1130 emit_call_insn (gen_call_internal (XEXP (operands[0], 0), operands[1]));
1134 (define_insn "call_internal"
1135 [(call (mem:QI (match_operand:SI 0 "call_address_operand" "aS"))
1136 (match_operand:SI 1 "general_operand" "g"))]
1140 if (REG_P (operands[0]))
1141 return \"calls %C0\";
1143 return \"call %C0,[],0\";
1145 [(set_attr "cc" "clobber")])
1147 ;; Call subroutine, returning value in operand 0
1148 ;; (which must be a hard register).
1150 (define_expand "call_value"
1151 [(set (match_operand 0 "" "")
1152 (call (match_operand:QI 1 "general_operand" "")
1153 (match_operand:SI 2 "general_operand" "")))]
1157 if (! call_address_operand (XEXP (operands[1], 0)))
1158 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
1159 emit_call_insn (gen_call_value_internal (operands[0],
1160 XEXP (operands[1], 0),
1165 (define_insn "call_value_internal"
1166 [(set (match_operand 0 "" "=dax")
1167 (call (mem:QI (match_operand:SI 1 "call_address_operand" "aS"))
1168 (match_operand:SI 2 "general_operand" "g")))]
1172 if (REG_P (operands[1]))
1173 return \"calls %C1\";
1175 return \"call %C1,[],0\";
1177 [(set_attr "cc" "clobber")])
1179 (define_expand "untyped_call"
1180 [(parallel [(call (match_operand 0 "" "")
1182 (match_operand 1 "" "")
1183 (match_operand 2 "" "")])]
1189 emit_call_insn (gen_call (operands[0], const0_rtx));
1191 for (i = 0; i < XVECLEN (operands[2], 0); i++)
1193 rtx set = XVECEXP (operands[2], 0, i);
1194 emit_move_insn (SET_DEST (set), SET_SRC (set));
1203 [(set_attr "cc" "none")])
1205 ;; ----------------------------------------------------------------------
1206 ;; EXTEND INSTRUCTIONS
1207 ;; ----------------------------------------------------------------------
1209 (define_expand "zero_extendqisi2"
1210 [(set (match_operand:SI 0 "general_operand" "")
1212 (match_operand:QI 1 "general_operand" "")))]
1217 [(set (match_operand:SI 0 "general_operand" "=dx,dx,dx")
1219 (match_operand:QI 1 "general_operand" "0,d,m")))]
1225 [(set_attr "cc" "none_0hit")])
1227 (define_expand "zero_extendhisi2"
1228 [(set (match_operand:SI 0 "general_operand" "")
1230 (match_operand:HI 1 "general_operand" "")))]
1235 [(set (match_operand:SI 0 "general_operand" "=dx,dx,dx")
1237 (match_operand:HI 1 "general_operand" "0,dx,m")))]
1243 [(set_attr "cc" "none_0hit")])
1245 ;;- sign extension instructions
1247 (define_expand "extendqisi2"
1248 [(set (match_operand:SI 0 "general_operand" "")
1250 (match_operand:QI 1 "general_operand" "")))]
1255 [(set (match_operand:SI 0 "general_operand" "=dx,dx")
1257 (match_operand:QI 1 "general_operand" "0,dx")))]
1262 [(set_attr "cc" "none_0hit")])
1264 (define_expand "extendhisi2"
1265 [(set (match_operand:SI 0 "general_operand" "")
1267 (match_operand:HI 1 "general_operand" "")))]
1272 [(set (match_operand:SI 0 "general_operand" "=dx,dx")
1274 (match_operand:HI 1 "general_operand" "0,dx")))]
1279 [(set_attr "cc" "none_0hit")])
1281 ;; ----------------------------------------------------------------------
1283 ;; ----------------------------------------------------------------------
1285 (define_expand "ashlsi3"
1286 [(set (match_operand:SI 0 "register_operand" "")
1288 (match_operand:SI 1 "register_operand" "")
1289 (match_operand:QI 2 "nonmemory_operand" "")))]
1294 [(set (match_operand:SI 0 "register_operand" "=dax,dx,dx,dx,dx")
1296 (match_operand:SI 1 "register_operand" "0,0,0,0,0")
1297 (match_operand:QI 2 "nonmemory_operand" "J,K,M,L,dxi")))]
1305 [(set_attr "cc" "set_zn")])
1307 (define_expand "lshrsi3"
1308 [(set (match_operand:SI 0 "register_operand" "")
1310 (match_operand:SI 1 "register_operand" "")
1311 (match_operand:QI 2 "nonmemory_operand" "")))]
1316 [(set (match_operand:SI 0 "register_operand" "=dx")
1318 (match_operand:SI 1 "register_operand" "0")
1319 (match_operand:QI 2 "nonmemory_operand" "dxi")))]
1322 [(set_attr "cc" "set_zn")])
1324 (define_expand "ashrsi3"
1325 [(set (match_operand:SI 0 "register_operand" "")
1327 (match_operand:SI 1 "register_operand" "")
1328 (match_operand:QI 2 "nonmemory_operand" "")))]
1333 [(set (match_operand:SI 0 "register_operand" "=dx")
1335 (match_operand:SI 1 "register_operand" "0")
1336 (match_operand:QI 2 "nonmemory_operand" "dxi")))]
1339 [(set_attr "cc" "set_zn")])
1341 ;; ----------------------------------------------------------------------
1342 ;; PROLOGUE/EPILOGUE
1343 ;; ----------------------------------------------------------------------
1344 (define_expand "prologue"
1347 "expand_prologue (); DONE;")
1349 (define_expand "epilogue"
1358 (define_insn "return_internal"
1362 [(set_attr "cc" "clobber")])
1364 ;; This insn restores the callee saved registers and does a return, it
1365 ;; can also deallocate stack space.
1366 (define_insn "return_internal_regs"
1368 (match_operand:SI 0 "const_int_operand" "i")
1377 fputs (\"\\tret [\", asm_out_file);
1378 if (regs_ever_live[2])
1380 fputs (\"d2\", asm_out_file);
1383 if (regs_ever_live[3])
1386 fputc (',', asm_out_file);
1387 fputs (\"d3\", asm_out_file);
1390 if (regs_ever_live[6])
1393 fputc (',', asm_out_file);
1394 fputs (\"a2\", asm_out_file);
1397 if (regs_ever_live[7])
1400 fputc (',', asm_out_file);
1401 fputs (\"a3\", asm_out_file);
1404 fprintf (asm_out_file, \"],%d\\n\", INTVAL (operands[0]));
1407 [(set_attr "cc" "clobber")])
1409 (define_insn "store_movm"
1418 fputs (\"\\tmovm [\", asm_out_file);
1419 if (regs_ever_live[2])
1421 fputs (\"d2\", asm_out_file);
1424 if (regs_ever_live[3])
1427 fputc (',', asm_out_file);
1428 fputs (\"d3\", asm_out_file);
1431 if (regs_ever_live[6])
1434 fputc (',', asm_out_file);
1435 fputs (\"a2\", asm_out_file);
1438 if (regs_ever_live[7])
1441 fputc (',', asm_out_file);
1442 fputs (\"a3\", asm_out_file);
1445 fputs (\"],(sp)\\n\", asm_out_file);
1448 [(set_attr "cc" "clobber")])
1450 (define_insn "return"
1452 "can_use_return_insn ()"
1455 rtx next = next_active_insn (insn);
1458 && GET_CODE (next) == JUMP_INSN
1459 && GET_CODE (PATTERN (next)) == RETURN)
1464 [(set_attr "cc" "clobber")])
1466 ;; Try to combine consecutive updates of the stack pointer (or any
1467 ;; other register for that matter).
1469 [(set (match_operand:SI 0 "register_operand" "=dxay")
1470 (plus:SI (match_dup 0)
1471 (match_operand 1 "const_int_operand" "")))
1473 (plus:SI (match_dup 0)
1474 (match_operand 2 "const_int_operand" "")))]
1478 operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]));
1479 return \"add %1,%0\";
1481 [(set_attr "cc" "clobber")])
1484 ;; We had patterns to check eq/ne, but the they don't work because
1485 ;; 0x80000000 + 0x80000000 = 0x0 with a carry out.
1487 ;; The Z flag and C flag would be set, and we have no way to
1488 ;; check for the Z flag set and C flag clear.
1490 ;; This will work on the mn10200 because we can check the ZX flag
1491 ;; if the comparison is in HImode.
1493 [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
1494 (set (pc) (if_then_else (ge (cc0) (const_int 0))
1495 (match_operand 1 "" "")
1497 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1499 [(set_attr "cc" "clobber")])
1502 [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
1503 (set (pc) (if_then_else (lt (cc0) (const_int 0))
1504 (match_operand 1 "" "")
1506 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1508 [(set_attr "cc" "clobber")])
1511 [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
1512 (set (pc) (if_then_else (ge (cc0) (const_int 0))
1514 (match_operand 1 "" "")))]
1515 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1517 [(set_attr "cc" "clobber")])
1520 [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
1521 (set (pc) (if_then_else (lt (cc0) (const_int 0))
1523 (match_operand 1 "" "")))]
1524 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1526 [(set_attr "cc" "clobber")])