diff options
Diffstat (limited to 'gcc/config/mn10300/mn10300.md')
-rwxr-xr-x | gcc/config/mn10300/mn10300.md | 2169 |
1 files changed, 0 insertions, 2169 deletions
diff --git a/gcc/config/mn10300/mn10300.md b/gcc/config/mn10300/mn10300.md deleted file mode 100755 index 61baf62..0000000 --- a/gcc/config/mn10300/mn10300.md +++ /dev/null @@ -1,2169 +0,0 @@ -;; GCC machine description for Matsushita MN10300 -;; Copyright (C) 1996, 1997 Free Software Foundation, Inc. - -;; Contributed by Jeff Law (law@cygnus.com). - -;; This file is part of GNU CC. - -;; GNU CC is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU CC is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU CC; see the file COPYING. If not, write to -;; the Free Software Foundation, 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;; The original PO technology requires these to be ordered by speed, -;; so that assigner will pick the fastest. - -;; See file "rtl.def" for documentation on define_insn, match_*, et. al. - -;; Condition code settings. -;; none - insn does not affect cc -;; none_0hit - insn does not affect cc but it does modify operand 0 -;; This attribute is used to keep track of when operand 0 changes. -;; See the description of NOTICE_UPDATE_CC for more info. -;; set_znv - insn sets z,n,v to usable values; c is unusable. -;; set_zn - insn sets z,n to usable values; v,c are unusable. -;; compare - compare instruction -;; invert -- like compare, but flags are inverted. -;; clobber - value of cc is unknown -(define_attr "cc" "none,none_0hit,set_znv,set_zn,compare,clobber,invert" - (const_string "clobber")) - -;; ---------------------------------------------------------------------- -;; MOVE INSTRUCTIONS -;; ---------------------------------------------------------------------- - -;; movqi - -(define_expand "movqi" - [(set (match_operand:QI 0 "general_operand" "") - (match_operand:QI 1 "general_operand" ""))] - "" - " -{ - /* One of the ops has to be in a register */ - if (!register_operand (operand0, QImode) - && !register_operand (operand1, QImode)) - operands[1] = copy_to_mode_reg (QImode, operand1); -}") - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=dx,a,dx,a,dx,a,dx,a,dxa,m") - (match_operand:QI 1 "general_operand" "0,0,I,I,a,dx,dxi,ia,m,dxa"))] - "TARGET_AM33 - && (register_operand (operands[0], QImode) - || register_operand (operands[1], QImode))" - "* -{ - switch (which_alternative) - { - case 0: - case 1: - return \"nop\"; - case 2: - return \"clr %0\"; - case 3: - case 4: - case 5: - case 6: - case 7: - if (GET_CODE (operands[1]) == CONST_DOUBLE) - { - rtx xoperands[2]; - xoperands[0] = operands[0]; - xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1])); - output_asm_insn (\"mov %1,%0\", xoperands); - return \"\"; - } - - if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS - && GET_CODE (operands[1]) == CONST_INT) - { - HOST_WIDE_INT val = INTVAL (operands[1]); - - if (((val & 0x80) && ! (val & 0xffffff00)) - || ((val & 0x800000) && ! (val & 0xff000000))) - return \"movu %1,%0\"; - } - return \"mov %1,%0\"; - case 8: - case 9: - return \"movbu %1,%0\"; - } -}" - [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")]) - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=dx,*a,dx,*a,dx,*a,dx,*a,dx,m") - (match_operand:QI 1 "general_operand" "0,0,I,I,a,dx,dxi,ia,m,dx"))] - "register_operand (operands[0], QImode) - || register_operand (operands[1], QImode)" - "* -{ - switch (which_alternative) - { - case 0: - case 1: - return \"nop\"; - case 2: - return \"clr %0\"; - case 3: - case 4: - case 5: - case 6: - case 7: - if (GET_CODE (operands[1]) == CONST_DOUBLE) - { - rtx xoperands[2]; - xoperands[0] = operands[0]; - xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1])); - output_asm_insn (\"mov %1,%0\", xoperands); - return \"\"; - } - - return \"mov %1,%0\"; - case 8: - case 9: - return \"movbu %1,%0\"; - } -}" - [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")]) - -;; movhi - -(define_expand "movhi" - [(set (match_operand:HI 0 "general_operand" "") - (match_operand:HI 1 "general_operand" ""))] - "" - " -{ - /* One of the ops has to be in a register */ - if (!register_operand (operand1, HImode) - && !register_operand (operand0, HImode)) - operands[1] = copy_to_mode_reg (HImode, operand1); -}") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=dx,a,dx,a,dx,a,dx,a,dxa,m") - (match_operand:HI 1 "general_operand" "0,0,I,I,a,dx,dxi,ia,m,dxa"))] - "TARGET_AM33 - && (register_operand (operands[0], HImode) - || register_operand (operands[1], HImode))" - "* -{ - switch (which_alternative) - { - case 0: - case 1: - return \"nop\"; - case 2: - return \"clr %0\"; - case 3: - case 4: - case 5: - case 6: - case 7: - if (GET_CODE (operands[1]) == CONST_DOUBLE) - { - rtx xoperands[2]; - xoperands[0] = operands[0]; - xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1])); - output_asm_insn (\"mov %1,%0\", xoperands); - return \"\"; - } - - if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS - && GET_CODE (operands[1]) == CONST_INT) - { - HOST_WIDE_INT val = INTVAL (operands[1]); - - if (((val & 0x80) && ! (val & 0xffffff00)) - || ((val & 0x800000) && ! (val & 0xff000000))) - return \"movu %1,%0\"; - } - return \"mov %1,%0\"; - case 8: - case 9: - return \"movhu %1,%0\"; - } -}" - [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")]) - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=dx,*a,dx,*a,dx,*a,dx,*a,dx,m") - (match_operand:HI 1 "general_operand" "0,0,I,I,a,dx,dxi,ia,m,dx"))] - "register_operand (operands[0], HImode) - || register_operand (operands[1], HImode)" - "* -{ - switch (which_alternative) - { - case 0: - case 1: - return \"nop\"; - case 2: - return \"clr %0\"; - case 3: - case 4: - case 5: - case 6: - case 7: - if (GET_CODE (operands[1]) == CONST_DOUBLE) - { - rtx xoperands[2]; - xoperands[0] = operands[0]; - xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1])); - output_asm_insn (\"mov %1,%0\", xoperands); - return \"\"; - } - return \"mov %1,%0\"; - case 8: - case 9: - return \"movhu %1,%0\"; - } -}" - [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")]) - -;; movsi and helpers - -;; We use this to handle addition of two values when one operand is the -;; stack pointer and the other is a memory reference of some kind. Reload -;; does not handle them correctly without this expander. -(define_expand "reload_insi" - [(set (match_operand:SI 0 "register_operand" "=a") - (match_operand:SI 1 "impossible_plus_operand" "")) - (clobber (match_operand:SI 2 "register_operand" "=&r"))] - "" - " -{ - if (XEXP (operands[1], 0) == stack_pointer_rtx) - { - if (GET_CODE (XEXP (operands[1], 1)) == SUBREG - && (GET_MODE_SIZE (GET_MODE (XEXP (operands[1], 1))) - > GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (operands[1], 1)))))) - emit_move_insn (operands[2], - gen_rtx (ZERO_EXTEND, GET_MODE (XEXP (operands[1], 1)), - SUBREG_REG (XEXP (operands[1], 1)))); - else - emit_move_insn (operands[2], XEXP (operands[1], 1)); - emit_move_insn (operands[0], XEXP (operands[1], 0)); - } - else - { - if (GET_CODE (XEXP (operands[1], 0)) == SUBREG - && (GET_MODE_SIZE (GET_MODE (XEXP (operands[1], 0))) - > GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (operands[1], 0)))))) - emit_move_insn (operands[2], - gen_rtx (ZERO_EXTEND, GET_MODE (XEXP (operands[1], 0)), - SUBREG_REG (XEXP (operands[1], 0)))); - else - emit_move_insn (operands[2], XEXP (operands[1], 0)); - emit_move_insn (operands[0], XEXP (operands[1], 1)); - } - emit_insn (gen_addsi3 (operands[0], operands[0], operands[2])); - DONE; -}") - -(define_expand "movsi" - [(set (match_operand:SI 0 "general_operand" "") - (match_operand:SI 1 "general_operand" ""))] - "" - " -{ - /* One of the ops has to be in a register */ - if (!register_operand (operand1, SImode) - && !register_operand (operand0, SImode)) - operands[1] = copy_to_mode_reg (SImode, operand1); -}") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" - "=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax,axR,y") - (match_operand:SI 1 "general_operand" - "0,0,I,I,dx,ax,dx,ax,dixm,aixm,dixm,aixm,xy,axR"))] - "register_operand (operands[0], SImode) - || register_operand (operands[1], SImode)" - "* -{ - switch (which_alternative) - { - case 0: - case 1: - return \"nop\"; - case 2: - return \"clr %0\"; - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - case 9: - case 10: - case 11: - case 12: - case 13: - if (GET_CODE (operands[1]) == CONST_DOUBLE) - { - rtx xoperands[2]; - xoperands[0] = operands[0]; - xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1])); - output_asm_insn (\"mov %1,%0\", xoperands); - return \"\"; - } - - if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS - && GET_CODE (operands[1]) == CONST_INT) - { - HOST_WIDE_INT val = INTVAL (operands[1]); - - if (((val & 0x80) && ! (val & 0xffffff00)) - || ((val & 0x800000) && ! (val & 0xff000000))) - return \"movu %1,%0\"; - } - return \"mov %1,%0\"; - } -}" - [(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")]) - -(define_expand "movsf" - [(set (match_operand:SF 0 "general_operand" "") - (match_operand:SF 1 "general_operand" ""))] - "" - " -{ - /* One of the ops has to be in a register */ - if (!register_operand (operand1, SFmode) - && !register_operand (operand0, SFmode)) - operands[1] = copy_to_mode_reg (SFmode, operand1); -}") - -(define_insn "" - [(set (match_operand:SF 0 "general_operand" "=dx,ax,dx,a,daxm,dax") - (match_operand:SF 1 "general_operand" "0,0,G,G,dax,daxim"))] - "register_operand (operands[0], SFmode) - || register_operand (operands[1], SFmode)" - "* -{ - switch (which_alternative) - { - case 0: - case 1: - return \"nop\"; - case 2: - return \"clr %0\"; - case 3: - case 4: - case 5: - if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS - && GET_CODE (operands[1]) == CONST_INT) - { - HOST_WIDE_INT val = INTVAL (operands[1]); - - if (((val & 0x80) && ! (val & 0xffffff00)) - || ((val & 0x800000) && ! (val & 0xff000000))) - return \"movu %1,%0\"; - } - return \"mov %1,%0\"; - } -}" - [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit")]) - -(define_expand "movdi" - [(set (match_operand:DI 0 "general_operand" "") - (match_operand:DI 1 "general_operand" ""))] - "" - " -{ - /* One of the ops has to be in a register */ - if (!register_operand (operand1, DImode) - && !register_operand (operand0, DImode)) - operands[1] = copy_to_mode_reg (DImode, operand1); -}") - -(define_insn "" - [(set (match_operand:DI 0 "general_operand" - "=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax") - (match_operand:DI 1 "general_operand" - "0,0,I,I,dx,ax,dx,ax,dxim,axim,dxim,axim"))] - "register_operand (operands[0], DImode) - || register_operand (operands[1], DImode)" - "* -{ - long val[2]; - REAL_VALUE_TYPE rv; - - switch (which_alternative) - { - case 0: - case 1: - return \"nop\"; - - case 2: - return \"clr %L0\;clr %H0\"; - - case 3: - if (rtx_equal_p (operands[0], operands[1])) - return \"sub %L1,%L0\;mov %L0,%H0\"; - else - return \"mov %1,%L0\;mov %L0,%H0\"; - case 4: - case 5: - case 6: - case 7: - case 8: - case 9: - case 10: - case 11: - if (GET_CODE (operands[1]) == CONST_INT) - { - val[0] = INTVAL (operands[1]); - val[1] = val[0] < 0 ? -1 : 0; - } - if (GET_CODE (operands[1]) == CONST_DOUBLE) - { - if (GET_MODE (operands[1]) == DFmode) - { - REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]); - REAL_VALUE_TO_TARGET_DOUBLE (rv, val); - } - else if (GET_MODE (operands[1]) == VOIDmode - || GET_MODE (operands[1]) == DImode) - { - val[0] = CONST_DOUBLE_LOW (operands[1]); - val[1] = CONST_DOUBLE_HIGH (operands[1]); - } - } - - if (GET_CODE (operands[1]) == MEM - && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0))) - { - rtx temp = operands[0]; - - while (GET_CODE (temp) == SUBREG) - temp = SUBREG_REG (temp); - - if (GET_CODE (temp) != REG) - abort (); - - if (reg_overlap_mentioned_p (gen_rtx (REG, SImode, REGNO (temp)), - XEXP (operands[1], 0))) - return \"mov %H1,%H0\;mov %L1,%L0\"; - else - return \"mov %L1,%L0\;mov %H1,%H0\"; - - } - else if (GET_CODE (operands[1]) == MEM - && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)) - && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS) - { - rtx xoperands[2]; - - xoperands[0] = operands[0]; - xoperands[1] = XEXP (operands[1], 0); - - output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\", - xoperands); - return \"\"; - } - else - { - if ((GET_CODE (operands[1]) == CONST_INT - || GET_CODE (operands[1]) == CONST_DOUBLE) - && val[0] == 0) - { - if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS) - output_asm_insn (\"clr %L0\", operands); - else - output_asm_insn (\"mov %L1,%L0\", operands); - } - else if ((REGNO_REG_CLASS (true_regnum (operands[0])) - == EXTENDED_REGS) - && (((val[0] & 0x80) && ! (val[0] & 0xffffff00)) - || ((val[0] & 0x800000) && ! (val[0] & 0xff000000)))) - output_asm_insn (\"movu %1,%0\", operands); - else - output_asm_insn (\"mov %L1,%L0\", operands); - - if ((GET_CODE (operands[1]) == CONST_INT - || GET_CODE (operands[1]) == CONST_DOUBLE) - && val[1] == 0) - { - if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS) - output_asm_insn (\"clr %H0\", operands); - else - output_asm_insn (\"mov %H1,%H0\", operands); - } - else if ((GET_CODE (operands[1]) == CONST_INT - || GET_CODE (operands[1]) == CONST_DOUBLE) - && val[0] == val[1]) - output_asm_insn (\"mov %L0,%H0\", operands); - else if ((REGNO_REG_CLASS (true_regnum (operands[0])) - == EXTENDED_REGS) - && (((val[1] & 0x80) && ! (val[1] & 0xffffff00)) - || ((val[1] & 0x800000) && ! (val[1] & 0xff000000)))) - output_asm_insn (\"movu %1,%0\", operands); - else - output_asm_insn (\"mov %H1,%H0\", operands); - return \"\"; - } - } -}" - [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")]) - -(define_expand "movdf" - [(set (match_operand:DF 0 "general_operand" "") - (match_operand:DF 1 "general_operand" ""))] - "" - " -{ - /* One of the ops has to be in a register */ - if (!register_operand (operand1, DFmode) - && !register_operand (operand0, DFmode)) - operands[1] = copy_to_mode_reg (DFmode, operand1); -}") - -(define_insn "" - [(set (match_operand:DF 0 "general_operand" - "=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax") - (match_operand:DF 1 "general_operand" - "0,0,G,G,dx,ax,dx,ax,dxim,axim,dxim,axim"))] - "register_operand (operands[0], DFmode) - || register_operand (operands[1], DFmode)" - "* -{ - long val[2]; - REAL_VALUE_TYPE rv; - - switch (which_alternative) - { - case 0: - case 1: - return \"nop\"; - - case 2: - return \"clr %L0\;clr %H0\"; - - case 3: - if (rtx_equal_p (operands[0], operands[1])) - return \"sub %L1,%L0\;mov %L0,%H0\"; - else - return \"mov %1,%L0\;mov %L0,%H0\"; - case 4: - case 5: - case 6: - case 7: - case 8: - case 9: - case 10: - case 11: - if (GET_CODE (operands[1]) == CONST_INT) - { - val[0] = INTVAL (operands[1]); - val[1] = val[0] < 0 ? -1 : 0; - } - if (GET_CODE (operands[1]) == CONST_DOUBLE) - { - if (GET_MODE (operands[1]) == DFmode) - { - REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]); - REAL_VALUE_TO_TARGET_DOUBLE (rv, val); - } - else if (GET_MODE (operands[1]) == VOIDmode - || GET_MODE (operands[1]) == DImode) - { - val[0] = CONST_DOUBLE_LOW (operands[1]); - val[1] = CONST_DOUBLE_HIGH (operands[1]); - } - } - - if (GET_CODE (operands[1]) == MEM - && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0))) - { - rtx temp = operands[0]; - - while (GET_CODE (temp) == SUBREG) - temp = SUBREG_REG (temp); - - if (GET_CODE (temp) != REG) - abort (); - - if (reg_overlap_mentioned_p (gen_rtx (REG, SImode, REGNO (temp)), - XEXP (operands[1], 0))) - return \"mov %H1,%H0\;mov %L1,%L0\"; - else - return \"mov %L1,%L0\;mov %H1,%H0\"; - - } - else if (GET_CODE (operands[1]) == MEM - && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)) - && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS) - { - rtx xoperands[2]; - - xoperands[0] = operands[0]; - xoperands[1] = XEXP (operands[1], 0); - - output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\", - xoperands); - return \"\"; - } - else - { - if ((GET_CODE (operands[1]) == CONST_INT - || GET_CODE (operands[1]) == CONST_DOUBLE) - && val[0] == 0) - { - if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS) - output_asm_insn (\"clr %L0\", operands); - else - output_asm_insn (\"mov %L1,%L0\", operands); - } - else if ((REGNO_REG_CLASS (true_regnum (operands[0])) - == EXTENDED_REGS) - && (((val[0] & 0x80) && ! (val[0] & 0xffffff00)) - || ((val[0] & 0x800000) && ! (val[0] & 0xff000000)))) - output_asm_insn (\"movu %1,%0\", operands); - else - output_asm_insn (\"mov %L1,%L0\", operands); - - if ((GET_CODE (operands[1]) == CONST_INT - || GET_CODE (operands[1]) == CONST_DOUBLE) - && val[1] == 0) - { - if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS) - output_asm_insn (\"clr %H0\", operands); - else - output_asm_insn (\"mov %H1,%H0\", operands); - } - else if ((GET_CODE (operands[1]) == CONST_INT - || GET_CODE (operands[1]) == CONST_DOUBLE) - && val[0] == val[1]) - output_asm_insn (\"mov %L0,%H0\", operands); - else if ((REGNO_REG_CLASS (true_regnum (operands[0])) - == EXTENDED_REGS) - && (((val[1] & 0x80) && ! (val[1] & 0xffffff00)) - || ((val[1] & 0x800000) && ! (val[1] & 0xff000000)))) - output_asm_insn (\"movu %1,%0\", operands); - else - output_asm_insn (\"mov %H1,%H0\", operands); - return \"\"; - } - } -}" - [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")]) - - - -;; ---------------------------------------------------------------------- -;; TEST INSTRUCTIONS -;; ---------------------------------------------------------------------- - -;; Go ahead and define tstsi so we can eliminate redundant tst insns -;; when we start trying to optimize this port. -(define_insn "tstsi" - [(set (cc0) (match_operand:SI 0 "register_operand" "dax"))] - "" - "* return output_tst (operands[0], insn);" - [(set_attr "cc" "set_znv")]) - -(define_insn "" - [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "dx,!a")))] - "TARGET_AM33" - "* return output_tst (operands[0], insn);" - [(set_attr "cc" "set_znv")]) - -(define_insn "" - [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "dx")))] - "" - "* return output_tst (operands[0], insn);" - [(set_attr "cc" "set_znv")]) - -(define_insn "" - [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "dx,!a")))] - "TARGET_AM33" - "* return output_tst (operands[0], insn);" - [(set_attr "cc" "set_znv")]) - -(define_insn "" - [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "dx")))] - "" - "* return output_tst (operands[0], insn);" - [(set_attr "cc" "set_znv")]) - -(define_insn "cmpsi" - [(set (cc0) - (compare (match_operand:SI 0 "register_operand" "!*d*a*x,dax") - (match_operand:SI 1 "nonmemory_operand" "!*0,daxi")))] - "" - "@ - add 0,%0 - cmp %1,%0" - [(set_attr "cc" "invert,compare")]) - -;; ---------------------------------------------------------------------- -;; ADD INSTRUCTIONS -;; ---------------------------------------------------------------------- - -(define_expand "addsi3" - [(set (match_operand:SI 0 "register_operand" "") - (plus:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "nonmemory_operand" "")))] - "" - " -{ - /* We can't add a variable amount directly to the stack pointer; - so do so via a temporary register. */ - if (operands[0] == stack_pointer_rtx - && GET_CODE (operands[1]) != CONST_INT - && GET_CODE (operands[2]) != CONST_INT) - { - rtx temp = gen_reg_rtx (SImode); - emit_move_insn (temp, gen_rtx (PLUS, SImode, operands[1], operands[2])); - emit_move_insn (operands[0], temp); - DONE; - } -}") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=dx,ax,ax,dax,xy,!dax") - (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,dax") - (match_operand:SI 2 "nonmemory_operand" "J,J,L,daxi,i,dax")))] - "TARGET_AM33" - "* -{ - switch (which_alternative) - { - case 0: - case 1: - return \"inc %0\"; - case 2: - return \"inc4 %0\"; - case 3: - case 4: - return \"add %2,%0\"; - case 5: - { - enum reg_class src1_class, src2_class, dst_class; - - src1_class = REGNO_REG_CLASS (true_regnum (operands[1])); - src2_class = REGNO_REG_CLASS (true_regnum (operands[2])); - dst_class = REGNO_REG_CLASS (true_regnum (operands[0])); - - /* I'm not sure if this can happen or not. Might as well be prepared - and generate the best possible code if it does happen. */ - if (true_regnum (operands[0]) == true_regnum (operands[1])) - return \"add %2,%0\"; - if (true_regnum (operands[0]) == true_regnum (operands[2])) - return \"add %1,%0\"; - - /* Catch cases where no extended register was used. These should be - handled just like the mn10300. */ - if (src1_class != EXTENDED_REGS - && src2_class != EXTENDED_REGS - && dst_class != EXTENDED_REGS) - { - /* We have to copy one of the sources into the destination, then - add the other source to the destination. - - Carefully select which source to copy to the destination; a naive - implementation will waste a byte when the source classes are - different and the destination is an address register. Selecting - the lowest cost register copy will optimize this sequence. */ - if (REGNO_REG_CLASS (true_regnum (operands[1])) - == REGNO_REG_CLASS (true_regnum (operands[0]))) - return \"mov %1,%0\;add %2,%0\"; - return \"mov %2,%0\;add %1,%0\"; - } - - /* At least one register is an extended register. */ - - /* The three operand add instruction on the am33 is a win iff the - output register is an extended register, or if both source - registers are extended registers. */ - if (dst_class == EXTENDED_REGS - || src1_class == src2_class) - return \"add %2,%1,%0\"; - - /* It is better to copy one of the sources to the destination, then - perform a 2 address add. The destination in this case must be - an address or data register and one of the sources must be an - extended register and the remaining source must not be an extended - register. - - The best code for this case is to copy the extended reg to the - destination, then emit a two address add. */ - if (src1_class == EXTENDED_REGS) - return \"mov %1,%0\;add %2,%0\"; - return \"mov %2,%0\;add %1,%0\"; - } - } -}" - [(set_attr "cc" "set_zn,none_0hit,none_0hit,set_zn,none_0hit,set_zn")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=dx,ax,ax,dax,xy,!dax") - (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,dax") - (match_operand:SI 2 "nonmemory_operand" "J,J,L,daxi,i,dax")))] - "" - "* -{ - switch (which_alternative) - { - case 0: - case 1: - return \"inc %0\"; - case 2: - return \"inc4 %0\"; - case 3: - case 4: - return \"add %2,%0\"; - case 5: - /* I'm not sure if this can happen or not. Might as well be prepared - and generate the best possible code if it does happen. */ - if (true_regnum (operands[0]) == true_regnum (operands[1])) - return \"add %2,%0\"; - if (true_regnum (operands[0]) == true_regnum (operands[2])) - return \"add %1,%0\"; - - /* We have to copy one of the sources into the destination, then add - the other source to the destination. - - Carefully select which source to copy to the destination; a naive - implementation will waste a byte when the source classes are different - and the destination is an address register. Selecting the lowest - cost register copy will optimize this sequence. */ - if (REGNO_REG_CLASS (true_regnum (operands[1])) - == REGNO_REG_CLASS (true_regnum (operands[0]))) - return \"mov %1,%0\;add %2,%0\"; - return \"mov %2,%0\;add %1,%0\"; - } -}" - [(set_attr "cc" "set_zn,none_0hit,none_0hit,set_zn,none_0hit,set_zn")]) - -;; ---------------------------------------------------------------------- -;; SUBTRACT INSTRUCTIONS -;; ---------------------------------------------------------------------- - -(define_expand "subsi3" - [(set (match_operand:SI 0 "register_operand" "") - (minus:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "nonmemory_operand" "")))] - "" - "") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=dax,!dax") - (minus:SI (match_operand:SI 1 "register_operand" "0,dax") - (match_operand:SI 2 "nonmemory_operand" "daxi,dax")))] - "TARGET_AM33" - "* -{ - if (true_regnum (operands[0]) == true_regnum (operands[1])) - return \"sub %2,%0\"; - else - { - enum reg_class src1_class, src2_class, dst_class; - - src1_class = REGNO_REG_CLASS (true_regnum (operands[1])); - src2_class = REGNO_REG_CLASS (true_regnum (operands[2])); - dst_class = REGNO_REG_CLASS (true_regnum (operands[0])); - - /* If no extended registers are used, then the best way to handle - this is to copy the first source operand into the destination - and emit a two address subtraction. */ - if (src1_class != EXTENDED_REGS - && src2_class != EXTENDED_REGS - && dst_class != EXTENDED_REGS - && true_regnum (operands[0]) != true_regnum (operands[2])) - return \"mov %1,%0\;sub %2,%0\"; - return \"sub %2,%1,%0\"; - } -}" - [(set_attr "cc" "set_zn")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=dax") - (minus:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "nonmemory_operand" "daxi")))] - "" - "sub %2,%0" - [(set_attr "cc" "set_zn")]) - -(define_expand "negsi2" - [(set (match_operand:SI 0 "register_operand" "") - (neg:SI (match_operand:SI 1 "register_operand" "")))] - "" - " -{ - rtx target = gen_reg_rtx (SImode); - - emit_move_insn (target, GEN_INT (0)); - emit_insn (gen_subsi3 (target, target, operands[1])); - emit_move_insn (operands[0], target); - DONE; -}") - -;; ---------------------------------------------------------------------- -;; MULTIPLY INSTRUCTIONS -;; ---------------------------------------------------------------------- - -(define_insn "mulsidi3" - [(set (match_operand:DI 0 "register_operand" "=dax") - (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "dax")) - (sign_extend:DI (match_operand:SI 2 "register_operand" "dax"))))] - "TARGET_AM33" - "mul %1,%2,%H0,%L0" - [(set_attr "cc" "set_zn")]) - -(define_insn "umulsidi3" - [(set (match_operand:DI 0 "register_operand" "=dax") - (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "dax")) - (zero_extend:DI (match_operand:SI 2 "register_operand" "dax"))))] - "TARGET_AM33" - "mulu %1,%2,%H0,%L0" - [(set_attr "cc" "set_zn")]) - -(define_expand "mulsi3" - [(set (match_operand:SI 0 "register_operand" "") - (mult:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "register_operand" "")))] - "" - "") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=dx,!dax") - (mult:SI (match_operand:SI 1 "register_operand" "%0,0") - (match_operand:SI 2 "nonmemory_operand" "dx,daxi")))] - "TARGET_AM33" - "* -{ - if (TARGET_MULT_BUG) - return \"nop\;nop\;mul %2,%0\"; - else - return \"mul %2,%0\"; -}" - [(set_attr "cc" "set_zn")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=dx") - (mult:SI (match_operand:SI 1 "register_operand" "%0") - (match_operand:SI 2 "register_operand" "dx")))] - "" - "* -{ - if (TARGET_MULT_BUG) - return \"nop\;nop\;mul %2,%0\"; - else - return \"mul %2,%0\"; -}" - [(set_attr "cc" "set_zn")]) - -(define_insn "udivmodsi4" - [(set (match_operand:SI 0 "general_operand" "=dx") - (udiv:SI (match_operand:SI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "dx"))) - (set (match_operand:SI 3 "general_operand" "=&d") - (umod:SI (match_dup 1) (match_dup 2)))] - "" - "* -{ - output_asm_insn (\"sub %3,%3\;mov %3,mdr\", operands); - - if (find_reg_note (insn, REG_UNUSED, operands[3])) - return \"divu %2,%0\"; - else - return \"divu %2,%0\;mov mdr,%3\"; -}" - [(set_attr "cc" "set_zn")]) - -(define_insn "divmodsi4" - [(set (match_operand:SI 0 "general_operand" "=dx") - (div:SI (match_operand:SI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "dx"))) - (set (match_operand:SI 3 "general_operand" "=d") - (mod:SI (match_dup 1) (match_dup 2)))] - "" - "* -{ - if (find_reg_note (insn, REG_UNUSED, operands[3])) - return \"ext %0\;div %2,%0\"; - else - return \"ext %0\;div %2,%0\;mov mdr,%3\"; -}" - [(set_attr "cc" "set_zn")]) - - -;; ---------------------------------------------------------------------- -;; AND INSTRUCTIONS -;; ---------------------------------------------------------------------- - -(define_expand "andsi3" - [(set (match_operand:SI 0 "register_operand" "") - (and:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "nonmemory_operand" "")))] - "" - "") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=dx,dx,!dax") - (and:SI (match_operand:SI 1 "register_operand" "%0,0,dax") - (match_operand:SI 2 "nonmemory_operand" "N,dxi,dax")))] - "TARGET_AM33" - "* -{ - if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff) - return \"extbu %0\"; - if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xffff) - return \"exthu %0\"; - if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x7fffffff) - return \"add %0,%0\;lsr 1,%0\"; - if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x3fffffff) - return \"asl2 %0\;lsr 2,%0\"; - if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x1fffffff) - return \"add %0,%0\;asl2 %0\;lsr 3,%0\"; - if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x0fffffff) - return \"asl2 %0\;asl2 %0\;lsr 4,%0\"; - if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffe) - return \"lsr 1,%0\;add %0,%0\"; - if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffc) - return \"lsr 2,%0\;asl2 %0\"; - if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff8) - return \"lsr 3,%0\;add %0,%0\;asl2 %0\"; - if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff0) - return \"lsr 4,%0\;asl2 %0\;asl2 %0\"; - if (REG_P (operands[2]) && REG_P (operands[1]) - && true_regnum (operands[0]) != true_regnum (operands[1]) - && true_regnum (operands[0]) != true_regnum (operands[2]) - && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS - && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS - && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS) - return \"mov %1,%0\;and %2,%0\"; - if (REG_P (operands[2]) && REG_P (operands[1]) - && true_regnum (operands[0]) != true_regnum (operands[1]) - && true_regnum (operands[0]) != true_regnum (operands[2])) - return \"and %1,%2,%0\"; - if (REG_P (operands[2]) && REG_P (operands[0]) - && true_regnum (operands[2]) == true_regnum (operands[0])) - return \"and %1,%0\"; - return \"and %2,%0\"; -}" - [(set_attr "cc" "none_0hit,set_znv,set_znv")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=dx,dx") - (and:SI (match_operand:SI 1 "register_operand" "%0,0") - (match_operand:SI 2 "nonmemory_operand" "N,dxi")))] - "" - "* -{ - if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff) - return \"extbu %0\"; - if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xffff) - return \"exthu %0\"; - if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x7fffffff) - return \"add %0,%0\;lsr 1,%0\"; - if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x3fffffff) - return \"asl2 %0\;lsr 2,%0\"; - if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x1fffffff) - return \"add %0,%0\;asl2 %0\;lsr 3,%0\"; - if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x0fffffff) - return \"asl2 %0\;asl2 %0\;lsr 4,%0\"; - if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffe) - return \"lsr 1,%0\;add %0,%0\"; - if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffc) - return \"lsr 2,%0\;asl2 %0\"; - if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff8) - return \"lsr 3,%0\;add %0,%0\;asl2 %0\"; - if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff0) - return \"lsr 4,%0\;asl2 %0\;asl2 %0\"; - return \"and %2,%0\"; -}" - [(set_attr "cc" "none_0hit,set_znv")]) - -;; ---------------------------------------------------------------------- -;; OR INSTRUCTIONS -;; ---------------------------------------------------------------------- - -(define_expand "iorsi3" - [(set (match_operand:SI 0 "register_operand" "") - (ior:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "nonmemory_operand" "")))] - "" - "") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=dx,!dax") - (ior:SI (match_operand:SI 1 "register_operand" "%0,dax") - (match_operand:SI 2 "nonmemory_operand" "dxi,dax")))] - "TARGET_AM33" - "* -{ - if (REG_P (operands[2]) && REG_P (operands[1]) - && true_regnum (operands[0]) != true_regnum (operands[1]) - && true_regnum (operands[0]) != true_regnum (operands[2]) - && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS - && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS - && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS) - return \"mov %1,%0\;or %2,%0\"; - if (REG_P (operands[2]) && REG_P (operands[1]) - && true_regnum (operands[0]) != true_regnum (operands[1]) - && true_regnum (operands[0]) != true_regnum (operands[2])) - return \"or %1,%2,%0\"; - if (REG_P (operands[2]) && REG_P (operands[0]) - && true_regnum (operands[2]) == true_regnum (operands[0])) - return \"or %1,%0\"; - return \"or %2,%0\"; -}" - [(set_attr "cc" "set_znv")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=dx") - (ior:SI (match_operand:SI 1 "register_operand" "%0") - (match_operand:SI 2 "nonmemory_operand" "dxi")))] - "" - "or %2,%0" - [(set_attr "cc" "set_znv")]) - -;; ---------------------------------------------------------------------- -;; XOR INSTRUCTIONS -;; ---------------------------------------------------------------------- - -(define_expand "xorsi3" - [(set (match_operand:SI 0 "register_operand" "") - (xor:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "nonmemory_operand" "")))] - "" - "") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=dx,!dax") - (xor:SI (match_operand:SI 1 "register_operand" "%0,dax") - (match_operand:SI 2 "nonmemory_operand" "dxi,dax")))] - "TARGET_AM33" - "* -{ - if (REG_P (operands[2]) && REG_P (operands[1]) - && true_regnum (operands[0]) != true_regnum (operands[1]) - && true_regnum (operands[0]) != true_regnum (operands[2]) - && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS - && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS - && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS) - return \"mov %1,%0\;xor %2,%0\"; - if (REG_P (operands[2]) && REG_P (operands[1]) - && true_regnum (operands[0]) != true_regnum (operands[1]) - && true_regnum (operands[0]) != true_regnum (operands[2])) - return \"xor %1,%2,%0\"; - if (REG_P (operands[2]) && REG_P (operands[0]) - && true_regnum (operands[2]) == true_regnum (operands[0])) - return \"xor %1,%0\"; - return \"xor %2,%0\"; -}" - [(set_attr "cc" "set_znv")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=dx") - (xor:SI (match_operand:SI 1 "register_operand" "%0") - (match_operand:SI 2 "nonmemory_operand" "dxi")))] - "" - "xor %2,%0" - [(set_attr "cc" "set_znv")]) - -;; ---------------------------------------------------------------------- -;; NOT INSTRUCTIONS -;; ---------------------------------------------------------------------- - -(define_expand "one_cmplsi2" - [(set (match_operand:SI 0 "register_operand" "") - (not:SI (match_operand:SI 1 "register_operand" "")))] - "" - "") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=dx,!dax") - (not:SI (match_operand:SI 1 "register_operand" "0,0")))] - "TARGET_AM33" - "not %0" - [(set_attr "cc" "set_znv")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=dx") - (not:SI (match_operand:SI 1 "register_operand" "0")))] - "" - "not %0" - [(set_attr "cc" "set_znv")]) - -;; ----------------------------------------------------------------- -;; BIT FIELDS -;; ----------------------------------------------------------------- - - -;; These set/clear memory in byte sized chunks. -;; -;; They are no smaller/faster than loading the value into a register -;; and storing the register, but they don't need a scratch register -;; which may allow for better code generation. -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=R,d") (const_int 0))] - "" - "@ - bclr 255,%A0 - clr %0" - [(set_attr "cc" "clobber")]) - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=R,d") (const_int -1))] - "" - "@ - bset 255,%A0 - mov -1,%0" - [(set_attr "cc" "clobber,none_0hit")]) - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "+R,d") - (subreg:QI - (and:SI (subreg:SI (match_dup 0) 0) - (match_operand:SI 1 "const_int_operand" "i,i")) 0))] - "" - "@ - bclr %N1,%A0 - and %1,%0" - [(set_attr "cc" "clobber,set_znv")]) - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "+R,d") - (subreg:QI - (ior:SI (subreg:SI (match_dup 0) 0) - (match_operand:SI 1 "const_int_operand" "i,i")) 0))] - "" - "@ - bset %1,%A0 - or %1,%0" - [(set_attr "cc" "clobber,set_znv")]) - -(define_insn "" - [(set (cc0) - (zero_extract:SI (match_operand:SI 0 "register_operand" "dx") - (match_operand 1 "const_int_operand" "") - (match_operand 2 "const_int_operand" "")))] - "" - "* -{ - int len = INTVAL (operands[1]); - int bit = INTVAL (operands[2]); - int mask = 0; - rtx xoperands[2]; - - while (len > 0) - { - mask |= (1 << bit); - bit++; - len--; - } - - xoperands[0] = operands[0]; - xoperands[1] = GEN_INT (mask); - output_asm_insn (\"btst %1,%0\", xoperands); - return \"\"; -}" - [(set_attr "cc" "set_znv")]) - -(define_insn "" - [(set (cc0) - (zero_extract:SI (match_operand:QI 0 "general_operand" "R,dx") - (match_operand 1 "const_int_operand" "") - (match_operand 2 "const_int_operand" "")))] - "mask_ok_for_mem_btst (INTVAL (operands[1]), INTVAL (operands[2]))" - "* -{ - int len = INTVAL (operands[1]); - int bit = INTVAL (operands[2]); - int mask = 0; - rtx xoperands[2]; - - while (len > 0) - { - mask |= (1 << bit); - bit++; - len--; - } - - /* If the source operand is not a reg (ie it is memory), then extract the - bits from mask that we actually want to test. Note that the mask will - never cross a byte boundary. */ - if (!REG_P (operands[0])) - { - if (mask & 0xff) - mask = mask & 0xff; - else if (mask & 0xff00) - mask = (mask >> 8) & 0xff; - else if (mask & 0xff0000) - mask = (mask >> 16) & 0xff; - else if (mask & 0xff000000) - mask = (mask >> 24) & 0xff; - } - - xoperands[0] = operands[0]; - xoperands[1] = GEN_INT (mask); - if (GET_CODE (operands[0]) == REG) - output_asm_insn (\"btst %1,%0\", xoperands); - else - output_asm_insn (\"btst %1,%A0\", xoperands); - return \"\"; -}" - [(set_attr "cc" "set_znv")]) - -(define_insn "" - [(set (cc0) (and:SI (match_operand:SI 0 "register_operand" "dx") - (match_operand:SI 1 "const_int_operand" "")))] - "" - "btst %1,%0" - [(set_attr "cc" "set_znv")]) - -(define_insn "" - [(set (cc0) - (and:SI - (subreg:SI (match_operand:QI 0 "general_operand" "R,dx") 0) - (match_operand:SI 1 "const_8bit_operand" "")))] - "" - "@ - btst %1,%A0 - btst %1,%0" - [(set_attr "cc" "set_znv")]) - - -;; ---------------------------------------------------------------------- -;; JUMP INSTRUCTIONS -;; ---------------------------------------------------------------------- - -;; Conditional jump instructions - -(define_expand "ble" - [(set (pc) - (if_then_else (le (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "bleu" - [(set (pc) - (if_then_else (leu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "bge" - [(set (pc) - (if_then_else (ge (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "bgeu" - [(set (pc) - (if_then_else (geu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "blt" - [(set (pc) - (if_then_else (lt (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "bltu" - [(set (pc) - (if_then_else (ltu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "bgt" - [(set (pc) - (if_then_else (gt (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "bgtu" - [(set (pc) - (if_then_else (gtu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "beq" - [(set (pc) - (if_then_else (eq (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "bne" - [(set (pc) - (if_then_else (ne (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_insn "" - [(set (pc) - (if_then_else (match_operator 1 "comparison_operator" - [(cc0) (const_int 0)]) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -{ - if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0 - && (GET_CODE (operands[1]) == GT - || GET_CODE (operands[1]) == GE - || GET_CODE (operands[1]) == LE - || GET_CODE (operands[1]) == LT)) - return 0; - return \"b%b1 %0\"; -}" - [(set_attr "cc" "none")]) - -(define_insn "" - [(set (pc) - (if_then_else (match_operator 1 "comparison_operator" - [(cc0) (const_int 0)]) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "* -{ - if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0 - && (GET_CODE (operands[1]) == GT - || GET_CODE (operands[1]) == GE - || GET_CODE (operands[1]) == LE - || GET_CODE (operands[1]) == LT)) - return 0; - return \"b%B1 %0\"; -}" - [(set_attr "cc" "none")]) - -;; Unconditional and other jump instructions. - -(define_insn "jump" - [(set (pc) - (label_ref (match_operand 0 "" "")))] - "" - "jmp %l0" - [(set_attr "cc" "none")]) - -(define_insn "indirect_jump" - [(set (pc) (match_operand:SI 0 "register_operand" "a"))] - "" - "jmp (%0)" - [(set_attr "cc" "none")]) - -(define_insn "tablejump" - [(set (pc) (match_operand:SI 0 "register_operand" "a")) - (use (label_ref (match_operand 1 "" "")))] - "" - "jmp (%0)" - [(set_attr "cc" "none")]) - -;; Call subroutine with no return value. - -(define_expand "call" - [(call (match_operand:QI 0 "general_operand" "") - (match_operand:SI 1 "general_operand" ""))] - "" - " -{ - if (! call_address_operand (XEXP (operands[0], 0))) - XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0)); - emit_call_insn (gen_call_internal (XEXP (operands[0], 0), operands[1])); - DONE; -}") - -(define_insn "call_internal" - [(call (mem:QI (match_operand:SI 0 "call_address_operand" "aS")) - (match_operand:SI 1 "general_operand" "g"))] - "" - "* -{ - if (REG_P (operands[0])) - return \"calls %C0\"; - else - return \"call %C0,[],0\"; -}" - [(set_attr "cc" "clobber")]) - -;; Call subroutine, returning value in operand 0 -;; (which must be a hard register). - -(define_expand "call_value" - [(set (match_operand 0 "" "") - (call (match_operand:QI 1 "general_operand" "") - (match_operand:SI 2 "general_operand" "")))] - "" - " -{ - if (! call_address_operand (XEXP (operands[1], 0))) - XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0)); - emit_call_insn (gen_call_value_internal (operands[0], - XEXP (operands[1], 0), - operands[2])); - DONE; -}") - -(define_insn "call_value_internal" - [(set (match_operand 0 "" "=dax") - (call (mem:QI (match_operand:SI 1 "call_address_operand" "aS")) - (match_operand:SI 2 "general_operand" "g")))] - "" - "* -{ - if (REG_P (operands[1])) - return \"calls %C1\"; - else - return \"call %C1,[],0\"; -}" - [(set_attr "cc" "clobber")]) - -(define_expand "untyped_call" - [(parallel [(call (match_operand 0 "" "") - (const_int 0)) - (match_operand 1 "" "") - (match_operand 2 "" "")])] - "" - " -{ - int i; - - emit_call_insn (gen_call (operands[0], const0_rtx)); - - for (i = 0; i < XVECLEN (operands[2], 0); i++) - { - rtx set = XVECEXP (operands[2], 0, i); - emit_move_insn (SET_DEST (set), SET_SRC (set)); - } - DONE; -}") - -(define_insn "nop" - [(const_int 0)] - "" - "nop" - [(set_attr "cc" "none")]) - -;; ---------------------------------------------------------------------- -;; EXTEND INSTRUCTIONS -;; ---------------------------------------------------------------------- - -(define_expand "zero_extendqisi2" - [(set (match_operand:SI 0 "general_operand" "") - (zero_extend:SI - (match_operand:QI 1 "general_operand" "")))] - "" - "") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=dx,dx,dx,!dax,!dax,!dax") - (zero_extend:SI - (match_operand:QI 1 "general_operand" "0,dax,m,0,dax,m")))] - "TARGET_AM33" - "@ - extbu %0 - mov %1,%0\;extbu %0 - movbu %1,%0 - extbu %0 - mov %1,%0\;extbu %0 - movbu %1,%0" - [(set_attr "cc" "none_0hit")]) - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=dx,dx,dx") - (zero_extend:SI - (match_operand:QI 1 "general_operand" "0,d,m")))] - "" - "@ - extbu %0 - mov %1,%0\;extbu %0 - movbu %1,%0" - [(set_attr "cc" "none_0hit")]) - -(define_expand "zero_extendhisi2" - [(set (match_operand:SI 0 "general_operand" "") - (zero_extend:SI - (match_operand:HI 1 "general_operand" "")))] - "" - "") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=dx,dx,dx,!dax,!dax,!dax") - (zero_extend:SI - (match_operand:HI 1 "general_operand" "0,dax,m,0,dax,m")))] - "TARGET_AM33" - "@ - exthu %0 - mov %1,%0\;exthu %0 - movhu %1,%0 - exthu %0 - mov %1,%0\;exthu %0 - movhu %1,%0" - [(set_attr "cc" "none_0hit")]) - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=dx,dx,dx") - (zero_extend:SI - (match_operand:HI 1 "general_operand" "0,dx,m")))] - "" - "@ - exthu %0 - mov %1,%0\;exthu %0 - movhu %1,%0" - [(set_attr "cc" "none_0hit")]) - -;;- sign extension instructions - -(define_expand "extendqisi2" - [(set (match_operand:SI 0 "general_operand" "") - (sign_extend:SI - (match_operand:QI 1 "general_operand" "")))] - "" - "") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=dx,dx,!dax,!dax") - (sign_extend:SI - (match_operand:QI 1 "general_operand" "0,dx,0,dax")))] - "TARGET_AM33" - "@ - extb %0 - mov %1,%0\;extb %0 - extb %0 - mov %1,%0\;extb %0" - [(set_attr "cc" "none_0hit")]) - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=dx,dx") - (sign_extend:SI - (match_operand:QI 1 "general_operand" "0,dx")))] - "" - "@ - extb %0 - mov %1,%0\;extb %0" - [(set_attr "cc" "none_0hit")]) - -(define_expand "extendhisi2" - [(set (match_operand:SI 0 "general_operand" "") - (sign_extend:SI - (match_operand:HI 1 "general_operand" "")))] - "" - "") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=dx,dx,!dax,!dax") - (sign_extend:SI - (match_operand:HI 1 "general_operand" "0,dax,0,dax")))] - "TARGET_AM33" - "@ - exth %0 - mov %1,%0\;exth %0 - exth %0 - mov %1,%0\;exth %0" - [(set_attr "cc" "none_0hit")]) - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=dx,dx") - (sign_extend:SI - (match_operand:HI 1 "general_operand" "0,dx")))] - "" - "@ - exth %0 - mov %1,%0\;exth %0" - [(set_attr "cc" "none_0hit")]) - -;; ---------------------------------------------------------------------- -;; SHIFTS -;; ---------------------------------------------------------------------- - -(define_expand "ashlsi3" - [(set (match_operand:SI 0 "register_operand" "") - (ashift:SI - (match_operand:SI 1 "register_operand" "") - (match_operand:QI 2 "nonmemory_operand" "")))] - "" - "") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=dax,dx,!dax") - (ashift:SI - (match_operand:SI 1 "register_operand" "0,0,dax") - (match_operand:QI 2 "nonmemory_operand" "J,dxi,dax")))] - "TARGET_AM33" - "* -{ - if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 1) - return \"add %0,%0\"; - - if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 2) - return \"asl2 %0\"; - - if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 3 - && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS) - return \"asl2 %0\;add %0,%0\"; - - if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 4 - && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS) - return \"asl2 %0\;asl2 %0\"; - - if (true_regnum (operands[1]) == true_regnum (operands[0])) - return \"asl %S2,%0\"; - - if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS - && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS - && true_regnum (operands[0]) != true_regnum (operands[2])) - return \"mov %1,%0\;asl %S2,%0\"; - return \"asl %2,%1,%0\"; -}" - [(set_attr "cc" "set_zn")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=dax,dx,dx,dx,dx") - (ashift:SI - (match_operand:SI 1 "register_operand" "0,0,0,0,0") - (match_operand:QI 2 "nonmemory_operand" "J,K,M,L,dxi")))] - "" - "@ - add %0,%0 - asl2 %0 - asl2 %0\;add %0,%0 - asl2 %0\;asl2 %0 - asl %S2,%0" - [(set_attr "cc" "set_zn")]) - -(define_expand "lshrsi3" - [(set (match_operand:SI 0 "register_operand" "") - (lshiftrt:SI - (match_operand:SI 1 "register_operand" "") - (match_operand:QI 2 "nonmemory_operand" "")))] - "" - "") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=dx,!dax") - (lshiftrt:SI - (match_operand:SI 1 "register_operand" "0,dax") - (match_operand:QI 2 "nonmemory_operand" "dxi,dax")))] - "TARGET_AM33" - "* -{ - if (true_regnum (operands[1]) == true_regnum (operands[0])) - return \"lsr %S2,%0\"; - - if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS - && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS - && true_regnum (operands[0]) != true_regnum (operands[2])) - return \"mov %1,%0\;lsr %S2,%0\"; - return \"lsr %2,%1,%0\"; -}" - [(set_attr "cc" "set_zn")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=dx") - (lshiftrt:SI - (match_operand:SI 1 "register_operand" "0") - (match_operand:QI 2 "nonmemory_operand" "dxi")))] - "" - "lsr %S2,%0" - [(set_attr "cc" "set_zn")]) - -(define_expand "ashrsi3" - [(set (match_operand:SI 0 "register_operand" "") - (ashiftrt:SI - (match_operand:SI 1 "register_operand" "") - (match_operand:QI 2 "nonmemory_operand" "")))] - "" - "") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=dx,!dax") - (ashiftrt:SI - (match_operand:SI 1 "register_operand" "0,dax") - (match_operand:QI 2 "nonmemory_operand" "dxi,dax")))] - "TARGET_AM33" - "* -{ - if (true_regnum (operands[1]) == true_regnum (operands[0])) - return \"asr %S2,%0\"; - - if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS - && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS - && true_regnum (operands[0]) != true_regnum (operands[2])) - return \"mov %1,%0\;asr %S2,%0\"; - return \"asr %2,%1,%0\"; -}" - [(set_attr "cc" "set_zn")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=dx") - (ashiftrt:SI - (match_operand:SI 1 "register_operand" "0") - (match_operand:QI 2 "nonmemory_operand" "dxi")))] - "" - "asr %S2,%0" - [(set_attr "cc" "set_zn")]) - -;; ---------------------------------------------------------------------- -;; FP INSTRUCTIONS -;; ---------------------------------------------------------------------- -;; -;; The mn103 series does not have floating point instructions, but since -;; FP values are held in integer regs, we can clear the high bit easily -;; which gives us an efficient inline floating point absolute value. -;; -;; Similarly for negation of a FP value. -;; - -(define_expand "absdf2" - [(set (match_operand:DF 0 "register_operand" "") - (abs:DF (match_operand:DF 1 "register_operand" "")))] - "" - " -{ - rtx target, result, insns; - - start_sequence (); - target = operand_subword (operands[0], 1, 1, DFmode); - result = expand_binop (SImode, and_optab, - operand_subword_force (operands[1], 1, DFmode), - GEN_INT(0x7fffffff), target, 0, OPTAB_WIDEN); - - if (result == 0) - abort (); - - if (result != target) - emit_move_insn (result, target); - - emit_move_insn (operand_subword (operands[0], 0, 1, DFmode), - operand_subword_force (operands[1], 0, DFmode)); - - insns = get_insns (); - end_sequence (); - - emit_no_conflict_block (insns, operands[0], operands[1], 0, 0); - DONE; -}") - -(define_expand "abssf2" - [(set (match_operand:SF 0 "register_operand" "") - (abs:SF (match_operand:SF 1 "register_operand" "")))] - "" - " -{ - rtx result; - rtx target; - - target = operand_subword_force (operands[0], 0, SFmode); - result = expand_binop (SImode, and_optab, - operand_subword_force (operands[1], 0, SFmode), - GEN_INT(0x7fffffff), target, 0, OPTAB_WIDEN); - if (result == 0) - abort (); - - if (result != target) - emit_move_insn (result, target); - - /* Make a place for REG_EQUAL. */ - emit_move_insn (operands[0], operands[0]); - DONE; -}") - - -(define_expand "negdf2" - [(set (match_operand:DF 0 "register_operand" "") - (neg:DF (match_operand:DF 1 "register_operand" "")))] - "" - " -{ - rtx target, result, insns; - - start_sequence (); - target = operand_subword (operands[0], 1, 1, DFmode); - result = expand_binop (SImode, xor_optab, - operand_subword_force (operands[1], 1, DFmode), - GEN_INT(0x80000000), target, 0, OPTAB_WIDEN); - - if (result == 0) - abort (); - - if (result != target) - emit_move_insn (result, target); - - emit_move_insn (operand_subword (operands[0], 0, 1, DFmode), - operand_subword_force (operands[1], 0, DFmode)); - - insns = get_insns (); - end_sequence (); - - emit_no_conflict_block (insns, operands[0], operands[1], 0, 0); - DONE; -}") - -(define_expand "negsf2" - [(set (match_operand:SF 0 "register_operand" "") - (neg:SF (match_operand:SF 1 "register_operand" "")))] - "" - " -{ - rtx result; - rtx target; - - target = operand_subword_force (operands[0], 0, SFmode); - result = expand_binop (SImode, xor_optab, - operand_subword_force (operands[1], 0, SFmode), - GEN_INT(0x80000000), target, 0, OPTAB_WIDEN); - if (result == 0) - abort (); - - if (result != target) - emit_move_insn (result, target); - - /* Make a place for REG_EQUAL. */ - emit_move_insn (operands[0], operands[0]); - DONE; -}") - - -;; ---------------------------------------------------------------------- -;; PROLOGUE/EPILOGUE -;; ---------------------------------------------------------------------- -(define_expand "prologue" - [(const_int 0)] - "" - "expand_prologue (); DONE;") - -(define_expand "epilogue" - [(return)] - "" - " -{ - expand_epilogue (); - DONE; -}") - -(define_insn "return_internal" - [(const_int 2)] - "" - "rets" - [(set_attr "cc" "clobber")]) - -;; This insn restores the callee saved registers and does a return, it -;; can also deallocate stack space. -(define_insn "return_internal_regs" - [(const_int 0) - (match_operand:SI 0 "const_int_operand" "i") - (return)] - "" - "* -{ - int i, need_comma; - int d2, d3, a2, a3; - int exreg1; - - need_comma = 0; - fputs (\"\\tret [\", asm_out_file); - if (regs_ever_live[2]) - { - fputs (\"d2\", asm_out_file); - need_comma = 1; - } - if (regs_ever_live[3]) - { - if (need_comma) - fputc (',', asm_out_file); - fputs (\"d3\", asm_out_file); - need_comma = 1; - } - if (regs_ever_live[6]) - { - if (need_comma) - fputc (',', asm_out_file); - fputs (\"a2\", asm_out_file); - need_comma = 1; - } - if (regs_ever_live[7]) - { - if (need_comma) - fputc (',', asm_out_file); - fputs (\"a3\", asm_out_file); - need_comma = 1; - } - if (regs_ever_live[14] || regs_ever_live[15] - || regs_ever_live[16] || regs_ever_live[17]) - { - if (need_comma) - fputc (',', asm_out_file); - fputs (\"exreg1\", asm_out_file); - need_comma = 1; - } - fprintf (asm_out_file, \"],%d\\n\", INTVAL (operands[0])); - return \"\"; -}" - [(set_attr "cc" "clobber")]) - -(define_insn "store_movm" - [(const_int 1)] - "" - "* -{ - int i, need_comma; - int d2, d3, a2, a3; - int exreg1; - - need_comma = 0; - fputs (\"\\tmovm [\", asm_out_file); - if (regs_ever_live[2]) - { - fputs (\"d2\", asm_out_file); - need_comma = 1; - } - if (regs_ever_live[3]) - { - if (need_comma) - fputc (',', asm_out_file); - fputs (\"d3\", asm_out_file); - need_comma = 1; - } - if (regs_ever_live[6]) - { - if (need_comma) - fputc (',', asm_out_file); - fputs (\"a2\", asm_out_file); - need_comma = 1; - } - if (regs_ever_live[7]) - { - if (need_comma) - fputc (',', asm_out_file); - fputs (\"a3\", asm_out_file); - need_comma = 1; - } - if (regs_ever_live[14] || regs_ever_live[15] - || regs_ever_live[16] || regs_ever_live[17]) - { - if (need_comma) - fputc (',', asm_out_file); - fputs (\"exreg1\", asm_out_file); - need_comma = 1; - } - fputs (\"],(sp)\\n\", asm_out_file); - return \"\"; -}" - [(set_attr "cc" "clobber")]) - -(define_insn "return" - [(return)] - "can_use_return_insn ()" - "* -{ - rtx next = next_active_insn (insn); - - if (next - && GET_CODE (next) == JUMP_INSN - && GET_CODE (PATTERN (next)) == RETURN) - return \"\"; - else - return \"rets\"; -}" - [(set_attr "cc" "clobber")]) - -;; Try to combine consecutive updates of the stack pointer (or any -;; other register for that matter). -(define_peephole - [(set (match_operand:SI 0 "register_operand" "=dxay") - (plus:SI (match_dup 0) - (match_operand 1 "const_int_operand" ""))) - (set (match_dup 0) - (plus:SI (match_dup 0) - (match_operand 2 "const_int_operand" "")))] - "" - "* -{ - operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1])); - return \"add %1,%0\"; -}" - [(set_attr "cc" "clobber")]) - -;; -;; We had patterns to check eq/ne, but the they don't work because -;; 0x80000000 + 0x80000000 = 0x0 with a carry out. -;; -;; The Z flag and C flag would be set, and we have no way to -;; check for the Z flag set and C flag clear. -;; -;; This will work on the mn10200 because we can check the ZX flag -;; if the comparison is in HImode. -(define_peephole - [(set (cc0) (match_operand:SI 0 "register_operand" "dx")) - (set (pc) (if_then_else (ge (cc0) (const_int 0)) - (match_operand 1 "" "") - (pc)))] - "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])" - "add %0,%0\;bcc %1" - [(set_attr "cc" "clobber")]) - -(define_peephole - [(set (cc0) (match_operand:SI 0 "register_operand" "dx")) - (set (pc) (if_then_else (lt (cc0) (const_int 0)) - (match_operand 1 "" "") - (pc)))] - "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])" - "add %0,%0\;bcs %1" - [(set_attr "cc" "clobber")]) - -(define_peephole - [(set (cc0) (match_operand:SI 0 "register_operand" "dx")) - (set (pc) (if_then_else (ge (cc0) (const_int 0)) - (pc) - (match_operand 1 "" "")))] - "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])" - "add %0,%0\;bcs %1" - [(set_attr "cc" "clobber")]) - -(define_peephole - [(set (cc0) (match_operand:SI 0 "register_operand" "dx")) - (set (pc) (if_then_else (lt (cc0) (const_int 0)) - (pc) - (match_operand 1 "" "")))] - "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])" - "add %0,%0\;bcc %1" - [(set_attr "cc" "clobber")]) - |