X-Git-Url: https://oss.titaniummirror.com/gitweb/?a=blobdiff_plain;f=gcc%2Fconfig%2Fvax%2Fvax.md;h=0bc05b461dc7f50eab91536aa533ef55ba233032;hb=6fed43773c9b0ce596dca5686f37ac3fc0fa11c0;hp=5aa3621a4239982762b13b61bd8db189a07044c8;hpb=27b11d56b743098deb193d510b337ba22dc52e5c;p=msp430-gcc.git diff --git a/gcc/config/vax/vax.md b/gcc/config/vax/vax.md index 5aa3621a..0bc05b46 100644 --- a/gcc/config/vax/vax.md +++ b/gcc/config/vax/vax.md @@ -1,126 +1,95 @@ ;; Machine description for GNU compiler, VAX Version ;; Copyright (C) 1987, 1988, 1991, 1994, 1995, 1996, 1998, 1999, 2000, 2001, -;; 2002 Free Software Foundation, Inc. +;; 2002, 2004, 2005, 2007 Free Software Foundation, Inc. -;; This file is part of GNU CC. +;; This file is part of GCC. -;; GNU CC is free software; you can redistribute it and/or modify +;; GCC 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) +;; the Free Software Foundation; either version 3, or (at your option) ;; any later version. -;; GNU CC is distributed in the hope that it will be useful, +;; GCC 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. +;; along with GCC; see the file COPYING3. If not see +;; . ;;- Instruction patterns. When multiple patterns apply, ;;- the first one in the file is chosen. ;;- -;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. +;;- See file "rtl.def" for documentation on define_insn, match_*, et al. ;;- ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code ;;- updates for most instructions. -;; We don't want to allow a constant operand for test insns because -;; (set (cc0) (const_int foo)) has no mode information. Such insns will -;; be folded while optimizing anyway. +;; UNSPEC_VOLATILE usage: -(define_insn "tstsi" - [(set (cc0) - (match_operand:SI 0 "nonimmediate_operand" "g"))] - "" - "tstl %0") +(define_constants + [(VUNSPEC_BLOCKAGE 0) ; `blockage' insn to prevent scheduling across an + ; insn in the code. + (VUNSPEC_SYNC_ISTREAM 1) ; sequence of insns to sync the I-stream + (VAX_AP_REGNUM 12) ; Register 12 contains the argument pointer + (VAX_FP_REGNUM 13) ; Register 13 contains the frame pointer + (VAX_SP_REGNUM 14) ; Register 14 contains the stack pointer + (VAX_PC_REGNUM 15) ; Register 15 contains the program counter + ] +) -(define_insn "tsthi" - [(set (cc0) - (match_operand:HI 0 "nonimmediate_operand" "g"))] - "" - "tstw %0") +;; Integer modes supported on VAX, with a mapping from machine mode +;; to mnemonic suffix. DImode is always a special case. +(define_mode_iterator VAXint [QI HI SI]) +(define_mode_attr isfx [(QI "b") (HI "w") (SI "l")]) -(define_insn "tstqi" - [(set (cc0) - (match_operand:QI 0 "nonimmediate_operand" "g"))] - "" - "tstb %0") +;; Similar for float modes supported on VAX. +(define_mode_iterator VAXfp [SF DF]) +(define_mode_attr fsfx [(SF "f") (DF "%#")]) -(define_insn "tstdf" - [(set (cc0) - (match_operand:DF 0 "general_operand" "gF"))] - "" - "tst%# %0") +;; Some output patterns want integer immediates with a prefix... +(define_mode_attr iprefx [(QI "B") (HI "H") (SI "N")]) -(define_insn "tstsf" - [(set (cc0) - (match_operand:SF 0 "general_operand" "gF"))] - "" - "tstf %0") - -(define_insn "cmpsi" - [(set (cc0) - (compare (match_operand:SI 0 "nonimmediate_operand" "g") - (match_operand:SI 1 "general_operand" "g")))] - "" - "cmpl %0,%1") +;; We don't want to allow a constant operand for test insns because +;; (set (cc0) (const_int foo)) has no mode information. Such insns will +;; be folded while optimizing anyway. -(define_insn "cmphi" +(define_insn "tst" [(set (cc0) - (compare (match_operand:HI 0 "nonimmediate_operand" "g") - (match_operand:HI 1 "general_operand" "g")))] + (match_operand:VAXint 0 "nonimmediate_operand" "g"))] "" - "cmpw %0,%1") + "tst %0") -(define_insn "cmpqi" +(define_insn "tst" [(set (cc0) - (compare (match_operand:QI 0 "nonimmediate_operand" "g") - (match_operand:QI 1 "general_operand" "g")))] + (match_operand:VAXfp 0 "general_operand" "gF"))] "" - "cmpb %0,%1") + "tst %0") -(define_insn "cmpdf" +(define_insn "cmp" [(set (cc0) - (compare (match_operand:DF 0 "general_operand" "gF,gF") - (match_operand:DF 1 "general_operand" "G,gF")))] + (compare (match_operand:VAXint 0 "nonimmediate_operand" "g") + (match_operand:VAXint 1 "general_operand" "g")))] "" - "@ - tst%# %0 - cmp%# %0,%1") + "cmp %0,%1") -(define_insn "cmpsf" +(define_insn "cmp" [(set (cc0) - (compare (match_operand:SF 0 "general_operand" "gF,gF") - (match_operand:SF 1 "general_operand" "G,gF")))] + (compare (match_operand:VAXfp 0 "general_operand" "gF,gF") + (match_operand:VAXfp 1 "general_operand" "G,gF")))] "" "@ - tstf %0 - cmpf %0,%1") - -(define_insn "" - [(set (cc0) - (and:SI (match_operand:SI 0 "general_operand" "g") - (match_operand:SI 1 "general_operand" "g")))] - "" - "bitl %0,%1") + tst %0 + cmp %0,%1") -(define_insn "" +(define_insn "*bit" [(set (cc0) - (and:HI (match_operand:HI 0 "general_operand" "g") - (match_operand:HI 1 "general_operand" "g")))] + (and:VAXint (match_operand:VAXint 0 "general_operand" "g") + (match_operand:VAXint 1 "general_operand" "g")))] "" - "bitw %0,%1") - -(define_insn "" - [(set (cc0) - (and:QI (match_operand:QI 0 "general_operand" "g") - (match_operand:QI 1 "general_operand" "g")))] - "" - "bitb %0,%1") + "bit %0,%1") ;; The VAX has no sCOND insns. It does have add/subtract with carry ;; which could be used to implement the sltu and sgeu patterns. However, @@ -130,21 +99,13 @@ ;; and has been deleted. -(define_insn "movdf" - [(set (match_operand:DF 0 "nonimmediate_operand" "=g,g") - (match_operand:DF 1 "general_operand" "G,gF"))] - "" - "@ - clr%# %0 - mov%# %1,%0") - -(define_insn "movsf" - [(set (match_operand:SF 0 "nonimmediate_operand" "=g,g") - (match_operand:SF 1 "general_operand" "G,gF"))] +(define_insn "mov" + [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g") + (match_operand:VAXfp 1 "general_operand" "G,gF"))] "" "@ - clrf %0 - movf %1,%0") + clr %0 + mov %1,%0") ;; Some VAXen don't support this instruction. ;;(define_insn "movti" @@ -178,66 +139,11 @@ ;; Loads of constants between 64 and 128 used to be done with ;; "addl3 $63,#,dst" but this is slower than movzbl and takes as much space. -(define_insn "movsi" - [(set (match_operand:SI 0 "nonimmediate_operand" "=g") - (match_operand:SI 1 "general_operand" "g"))] - "" - "* -{ - if (operands[1] == const1_rtx && reg_was_0_p (insn, operands[0])) - return \"incl %0\"; - - if (GET_CODE (operands[1]) == SYMBOL_REF || GET_CODE (operands[1]) == CONST) - { - if (push_operand (operands[0], SImode)) - return \"pushab %a1\"; - return \"movab %a1,%0\"; - } - if (operands[1] == const0_rtx) - return \"clrl %0\"; - if (GET_CODE (operands[1]) == CONST_INT - && (unsigned) INTVAL (operands[1]) >= 64) - { - int i = INTVAL (operands[1]); - if ((unsigned)(~i) < 64) - return \"mcoml %N1,%0\"; - if ((unsigned)i < 0x100) - return \"movzbl %1,%0\"; - if (i >= -0x80 && i < 0) - return \"cvtbl %1,%0\"; - if ((unsigned)i < 0x10000) - return \"movzwl %1,%0\"; - if (i >= -0x8000 && i < 0) - return \"cvtwl %1,%0\"; - } - if (push_operand (operands[0], SImode)) - return \"pushl %1\"; - return \"movl %1,%0\"; -}") - -(define_insn "movhi" - [(set (match_operand:HI 0 "nonimmediate_operand" "=g") - (match_operand:HI 1 "general_operand" "g"))] +(define_insn "mov" + [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g") + (match_operand:VAXint 1 "general_operand" "g"))] "" - "* -{ - if (operands[1] == const1_rtx && reg_was_0_p (insn, operands[0])) - return \"incw %0\"; - - if (GET_CODE (operands[1]) == CONST_INT) - { - int i = INTVAL (operands[1]); - if (i == 0) - return \"clrw %0\"; - else if ((unsigned int)i < 64) - return \"movw %1,%0\"; - else if ((unsigned int)~i < 64) - return \"mcomw %H1,%0\"; - else if ((unsigned int)i < 256) - return \"movzbw %1,%0\"; - } - return \"movw %1,%0\"; -}") + "* return vax_output_int_move (insn, operands, mode);") (define_insn "movstricthi" [(set (strict_low_part (match_operand:HI 0 "register_operand" "+g")) @@ -245,7 +151,7 @@ "" "* { - if (GET_CODE (operands[1]) == CONST_INT) + if (CONST_INT_P (operands[1])) { int i = INTVAL (operands[1]); if (i == 0) @@ -260,33 +166,13 @@ return \"movw %1,%0\"; }") -(define_insn "movqi" - [(set (match_operand:QI 0 "nonimmediate_operand" "=g") - (match_operand:QI 1 "general_operand" "g"))] - "" - "* -{ - if (operands[1] == const1_rtx && reg_was_0_p (insn, operands[0])) - return \"incb %0\"; - - if (GET_CODE (operands[1]) == CONST_INT) - { - int i = INTVAL (operands[1]); - if (i == 0) - return \"clrb %0\"; - else if ((unsigned int)~i < 64) - return \"mcomb %B1,%0\"; - } - return \"movb %1,%0\"; -}") - (define_insn "movstrictqi" [(set (strict_low_part (match_operand:QI 0 "register_operand" "+g")) (match_operand:QI 1 "general_operand" "g"))] "" "* { - if (GET_CODE (operands[1]) == CONST_INT) + if (CONST_INT_P (operands[1])) { int i = INTVAL (operands[1]); if (i == 0) @@ -298,15 +184,15 @@ }") ;; This is here to accept 4 arguments and pass the first 3 along -;; to the movstrhi1 pattern that really does the work. -(define_expand "movstrhi" +;; to the movmemhi1 pattern that really does the work. +(define_expand "movmemhi" [(set (match_operand:BLK 0 "general_operand" "=g") (match_operand:BLK 1 "general_operand" "g")) (use (match_operand:HI 2 "general_operand" "g")) (match_operand 3 "" "")] "" " - emit_insn (gen_movstrhi1 (operands[0], operands[1], operands[2])); + emit_insn (gen_movmemhi1 (operands[0], operands[1], operands[2])); DONE; ") @@ -314,7 +200,7 @@ ;; but it should suffice ;; that anything generated as this insn will be recognized as one ;; and that it won't successfully combine with anything. -(define_insn "movstrhi1" +(define_insn "movmemhi1" [(set (match_operand:BLK 0 "memory_operand" "=m") (match_operand:BLK 1 "memory_operand" "m")) (use (match_operand:HI 2 "general_operand" "g")) @@ -397,218 +283,38 @@ ;; Fix-to-float conversion insns. -(define_insn "floatsisf2" - [(set (match_operand:SF 0 "nonimmediate_operand" "=g") - (float:SF (match_operand:SI 1 "nonimmediate_operand" "g")))] - "" - "cvtlf %1,%0") - -(define_insn "floatsidf2" - [(set (match_operand:DF 0 "nonimmediate_operand" "=g") - (float:DF (match_operand:SI 1 "nonimmediate_operand" "g")))] - "" - "cvtl%# %1,%0") - -(define_insn "floathisf2" - [(set (match_operand:SF 0 "nonimmediate_operand" "=g") - (float:SF (match_operand:HI 1 "nonimmediate_operand" "g")))] - "" - "cvtwf %1,%0") - -(define_insn "floathidf2" - [(set (match_operand:DF 0 "nonimmediate_operand" "=g") - (float:DF (match_operand:HI 1 "nonimmediate_operand" "g")))] +(define_insn "float2" + [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g") + (float:VAXfp (match_operand:VAXint 1 "nonimmediate_operand" "g")))] "" - "cvtw%# %1,%0") + "cvt %1,%0") -(define_insn "floatqisf2" - [(set (match_operand:SF 0 "nonimmediate_operand" "=g") - (float:SF (match_operand:QI 1 "nonimmediate_operand" "g")))] - "" - "cvtbf %1,%0") - -(define_insn "floatqidf2" - [(set (match_operand:DF 0 "nonimmediate_operand" "=g") - (float:DF (match_operand:QI 1 "nonimmediate_operand" "g")))] - "" - "cvtb%# %1,%0") - ;; Float-to-fix conversion insns. -(define_insn "fix_truncsfqi2" - [(set (match_operand:QI 0 "nonimmediate_operand" "=g") - (fix:QI (fix:SF (match_operand:SF 1 "general_operand" "gF"))))] - "" - "cvtfb %1,%0") - -(define_insn "fix_truncsfhi2" - [(set (match_operand:HI 0 "nonimmediate_operand" "=g") - (fix:HI (fix:SF (match_operand:SF 1 "general_operand" "gF"))))] - "" - "cvtfw %1,%0") - -(define_insn "fix_truncsfsi2" - [(set (match_operand:SI 0 "nonimmediate_operand" "=g") - (fix:SI (fix:SF (match_operand:SF 1 "general_operand" "gF"))))] - "" - "cvtfl %1,%0") - -(define_insn "fix_truncdfqi2" - [(set (match_operand:QI 0 "nonimmediate_operand" "=g") - (fix:QI (fix:DF (match_operand:DF 1 "general_operand" "gF"))))] - "" - "cvt%#b %1,%0") - -(define_insn "fix_truncdfhi2" - [(set (match_operand:HI 0 "nonimmediate_operand" "=g") - (fix:HI (fix:DF (match_operand:DF 1 "general_operand" "gF"))))] - "" - "cvt%#w %1,%0") - -(define_insn "fix_truncdfsi2" - [(set (match_operand:SI 0 "nonimmediate_operand" "=g") - (fix:SI (fix:DF (match_operand:DF 1 "general_operand" "gF"))))] +(define_insn "fix_trunc2" + [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g") + (fix:VAXint (fix:VAXfp (match_operand:VAXfp 1 "general_operand" "gF"))))] "" - "cvt%#l %1,%0") + "cvt %1,%0") ;;- All kinds of add instructions. -(define_insn "adddf3" - [(set (match_operand:DF 0 "nonimmediate_operand" "=g,g,g") - (plus:DF (match_operand:DF 1 "general_operand" "0,gF,gF") - (match_operand:DF 2 "general_operand" "gF,0,gF")))] +(define_insn "add3" + [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g,g") + (plus:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF,gF") + (match_operand:VAXfp 2 "general_operand" "gF,0,gF")))] "" "@ - add%#2 %2,%0 - add%#2 %1,%0 - add%#3 %1,%2,%0") - -(define_insn "addsf3" - [(set (match_operand:SF 0 "nonimmediate_operand" "=g,g,g") - (plus:SF (match_operand:SF 1 "general_operand" "0,gF,gF") - (match_operand:SF 2 "general_operand" "gF,0,gF")))] - "" - "@ - addf2 %2,%0 - addf2 %1,%0 - addf3 %1,%2,%0") - -/* The space-time-opcode tradeoffs for addition vary by model of VAX. - - On a VAX 3 "movab (r1)[r2],r3" is faster than "addl3 r1,r2,r3", - but it not faster on other models. - - "movab #(r1),r2" is usually shorter than "addl3 #,r1,r2", and is - faster on a VAX 3, but some VAXen (e.g. VAX 9000) will stall if - a register is used in an address too soon after it is set. - Compromise by using movab only when it is shorter than the add - or the base register in the address is one of sp, ap, and fp, - which are not modified very often. */ - - -(define_insn "addsi3" - [(set (match_operand:SI 0 "nonimmediate_operand" "=g") - (plus:SI (match_operand:SI 1 "general_operand" "g") - (match_operand:SI 2 "general_operand" "g")))] - "" - "* -{ - if (rtx_equal_p (operands[0], operands[1])) - { - if (operands[2] == const1_rtx) - return \"incl %0\"; - if (operands[2] == constm1_rtx) - return \"decl %0\"; - if (GET_CODE (operands[2]) == CONST_INT - && (unsigned) (- INTVAL (operands[2])) < 64) - return \"subl2 $%n2,%0\"; - if (GET_CODE (operands[2]) == CONST_INT - && (unsigned) INTVAL (operands[2]) >= 64 - && GET_CODE (operands[1]) == REG - && ((INTVAL (operands[2]) < 32767 && INTVAL (operands[2]) > -32768) - || REGNO (operands[1]) > 11)) - return \"movab %c2(%1),%0\"; - return \"addl2 %2,%0\"; - } - if (rtx_equal_p (operands[0], operands[2])) - return \"addl2 %1,%0\"; - - if (GET_CODE (operands[2]) == CONST_INT - && INTVAL (operands[2]) < 32767 - && INTVAL (operands[2]) > -32768 - && GET_CODE (operands[1]) == REG - && push_operand (operands[0], SImode)) - return \"pushab %c2(%1)\"; - - if (GET_CODE (operands[2]) == CONST_INT - && (unsigned) (- INTVAL (operands[2])) < 64) - return \"subl3 $%n2,%1,%0\"; - - if (GET_CODE (operands[2]) == CONST_INT - && (unsigned) INTVAL (operands[2]) >= 64 - && GET_CODE (operands[1]) == REG - && ((INTVAL (operands[2]) < 32767 && INTVAL (operands[2]) > -32768) - || REGNO (operands[1]) > 11)) - return \"movab %c2(%1),%0\"; - - /* Add this if using gcc on a VAX 3xxx: - if (REG_P (operands[1]) && REG_P (operands[2])) - return \"movab (%1)[%2],%0\"; - */ - return \"addl3 %1,%2,%0\"; -}") + add2 %2,%0 + add2 %1,%0 + add3 %1,%2,%0") -(define_insn "addhi3" - [(set (match_operand:HI 0 "nonimmediate_operand" "=g") - (plus:HI (match_operand:HI 1 "general_operand" "g") - (match_operand:HI 2 "general_operand" "g")))] +(define_insn "add3" + [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g") + (plus:VAXint (match_operand:VAXint 1 "general_operand" "g") + (match_operand:VAXint 2 "general_operand" "g")))] "" - "* -{ - if (rtx_equal_p (operands[0], operands[1])) - { - if (operands[2] == const1_rtx) - return \"incw %0\"; - if (operands[2] == constm1_rtx) - return \"decw %0\"; - if (GET_CODE (operands[2]) == CONST_INT - && (unsigned) (- INTVAL (operands[2])) < 64) - return \"subw2 $%n2,%0\"; - return \"addw2 %2,%0\"; - } - if (rtx_equal_p (operands[0], operands[2])) - return \"addw2 %1,%0\"; - if (GET_CODE (operands[2]) == CONST_INT - && (unsigned) (- INTVAL (operands[2])) < 64) - return \"subw3 $%n2,%1,%0\"; - return \"addw3 %1,%2,%0\"; -}") - -(define_insn "addqi3" - [(set (match_operand:QI 0 "nonimmediate_operand" "=g") - (plus:QI (match_operand:QI 1 "general_operand" "g") - (match_operand:QI 2 "general_operand" "g")))] - "" - "* -{ - if (rtx_equal_p (operands[0], operands[1])) - { - if (operands[2] == const1_rtx) - return \"incb %0\"; - if (operands[2] == constm1_rtx) - return \"decb %0\"; - if (GET_CODE (operands[2]) == CONST_INT - && (unsigned) (- INTVAL (operands[2])) < 64) - return \"subb2 $%n2,%0\"; - return \"addb2 %2,%0\"; - } - if (rtx_equal_p (operands[0], operands[2])) - return \"addb2 %1,%0\"; - if (GET_CODE (operands[2]) == CONST_INT - && (unsigned) (- INTVAL (operands[2])) < 64) - return \"subb3 $%n2,%1,%0\"; - return \"addb3 %1,%2,%0\"; -}") + "* return vax_output_int_add (insn, operands, mode);") ;; The add-with-carry (adwc) instruction only accepts two operands. (define_insn "adddi3" @@ -656,50 +362,23 @@ ;;- All kinds of subtract instructions. -(define_insn "subdf3" - [(set (match_operand:DF 0 "nonimmediate_operand" "=g,g") - (minus:DF (match_operand:DF 1 "general_operand" "0,gF") - (match_operand:DF 2 "general_operand" "gF,gF")))] - "" - "@ - sub%#2 %2,%0 - sub%#3 %2,%1,%0") - -(define_insn "subsf3" - [(set (match_operand:SF 0 "nonimmediate_operand" "=g,g") - (minus:SF (match_operand:SF 1 "general_operand" "0,gF") - (match_operand:SF 2 "general_operand" "gF,gF")))] - "" - "@ - subf2 %2,%0 - subf3 %2,%1,%0") - -(define_insn "subsi3" - [(set (match_operand:SI 0 "nonimmediate_operand" "=g,g") - (minus:SI (match_operand:SI 1 "general_operand" "0,g") - (match_operand:SI 2 "general_operand" "g,g")))] - "" - "@ - subl2 %2,%0 - subl3 %2,%1,%0") - -(define_insn "subhi3" - [(set (match_operand:HI 0 "nonimmediate_operand" "=g,g") - (minus:HI (match_operand:HI 1 "general_operand" "0,g") - (match_operand:HI 2 "general_operand" "g,g")))] +(define_insn "sub3" + [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g") + (minus:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF") + (match_operand:VAXfp 2 "general_operand" "gF,gF")))] "" "@ - subw2 %2,%0 - subw3 %2,%1,%0") + sub2 %2,%0 + sub3 %2,%1,%0") -(define_insn "subqi3" - [(set (match_operand:QI 0 "nonimmediate_operand" "=g,g") - (minus:QI (match_operand:QI 1 "general_operand" "0,g") - (match_operand:QI 2 "general_operand" "g,g")))] +(define_insn "sub3" + [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g") + (minus:VAXint (match_operand:VAXint 1 "general_operand" "0,g") + (match_operand:VAXint 2 "general_operand" "g,g")))] "" "@ - subb2 %2,%0 - subb3 %2,%1,%0") + sub2 %2,%0 + sub3 %2,%1,%0") ;; The subtract-with-carry (sbwc) instruction only takes two operands. (define_insn "subdi3" @@ -747,55 +426,25 @@ ;;- Multiply instructions. -(define_insn "muldf3" - [(set (match_operand:DF 0 "nonimmediate_operand" "=g,g,g") - (mult:DF (match_operand:DF 1 "general_operand" "0,gF,gF") - (match_operand:DF 2 "general_operand" "gF,0,gF")))] - "" - "@ - mul%#2 %2,%0 - mul%#2 %1,%0 - mul%#3 %1,%2,%0") - -(define_insn "mulsf3" - [(set (match_operand:SF 0 "nonimmediate_operand" "=g,g,g") - (mult:SF (match_operand:SF 1 "general_operand" "0,gF,gF") - (match_operand:SF 2 "general_operand" "gF,0,gF")))] - "" - "@ - mulf2 %2,%0 - mulf2 %1,%0 - mulf3 %1,%2,%0") - -(define_insn "mulsi3" - [(set (match_operand:SI 0 "nonimmediate_operand" "=g,g,g") - (mult:SI (match_operand:SI 1 "general_operand" "0,g,g") - (match_operand:SI 2 "general_operand" "g,0,g")))] +(define_insn "mul3" + [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g,g") + (mult:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF,gF") + (match_operand:VAXfp 2 "general_operand" "gF,0,gF")))] "" "@ - mull2 %2,%0 - mull2 %1,%0 - mull3 %1,%2,%0") + mul2 %2,%0 + mul2 %1,%0 + mul3 %1,%2,%0") -(define_insn "mulhi3" - [(set (match_operand:HI 0 "nonimmediate_operand" "=g,g,") - (mult:HI (match_operand:HI 1 "general_operand" "0,g,g") - (match_operand:HI 2 "general_operand" "g,0,g")))] +(define_insn "mul3" + [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g") + (mult:VAXint (match_operand:VAXint 1 "general_operand" "0,g,g") + (match_operand:VAXint 2 "general_operand" "g,0,g")))] "" "@ - mulw2 %2,%0 - mulw2 %1,%0 - mulw3 %1,%2,%0") - -(define_insn "mulqi3" - [(set (match_operand:QI 0 "nonimmediate_operand" "=g,g,g") - (mult:QI (match_operand:QI 1 "general_operand" "0,g,g") - (match_operand:QI 2 "general_operand" "g,0,g")))] - "" - "@ - mulb2 %2,%0 - mulb2 %1,%0 - mulb3 %1,%2,%0") + mul2 %2,%0 + mul2 %1,%0 + mul3 %1,%2,%0") (define_insn "mulsidi3" [(set (match_operand:DI 0 "nonimmediate_operand" "=g") @@ -826,7 +475,7 @@ (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "g"))) (match_operand:DI 3 "immediate_operand" "F")))] - "GET_CODE (operands[3]) == CONST_DOUBLE + "GET_CODE (operands[3]) == CONST_DOUBLE && CONST_DOUBLE_HIGH (operands[3]) == (CONST_DOUBLE_LOW (operands[3]) >> 31)" "* { @@ -837,50 +486,23 @@ ;;- Divide instructions. -(define_insn "divdf3" - [(set (match_operand:DF 0 "nonimmediate_operand" "=g,g") - (div:DF (match_operand:DF 1 "general_operand" "0,gF") - (match_operand:DF 2 "general_operand" "gF,gF")))] - "" - "@ - div%#2 %2,%0 - div%#3 %2,%1,%0") - -(define_insn "divsf3" - [(set (match_operand:SF 0 "nonimmediate_operand" "=g,g") - (div:SF (match_operand:SF 1 "general_operand" "0,gF") - (match_operand:SF 2 "general_operand" "gF,gF")))] - "" - "@ - divf2 %2,%0 - divf3 %2,%1,%0") - -(define_insn "divsi3" - [(set (match_operand:SI 0 "nonimmediate_operand" "=g,g") - (div:SI (match_operand:SI 1 "general_operand" "0,g") - (match_operand:SI 2 "general_operand" "g,g")))] - "" - "@ - divl2 %2,%0 - divl3 %2,%1,%0") - -(define_insn "divhi3" - [(set (match_operand:HI 0 "nonimmediate_operand" "=g,g") - (div:HI (match_operand:HI 1 "general_operand" "0,g") - (match_operand:HI 2 "general_operand" "g,g")))] +(define_insn "div3" + [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g") + (div:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF") + (match_operand:VAXfp 2 "general_operand" "gF,gF")))] "" "@ - divw2 %2,%0 - divw3 %2,%1,%0") + div2 %2,%0 + div3 %2,%1,%0") -(define_insn "divqi3" - [(set (match_operand:QI 0 "nonimmediate_operand" "=g,g") - (div:QI (match_operand:QI 1 "general_operand" "0,g") - (match_operand:QI 2 "general_operand" "g,g")))] +(define_insn "div3" + [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g") + (div:VAXint (match_operand:VAXint 1 "general_operand" "0,g") + (match_operand:VAXint 2 "general_operand" "g,g")))] "" "@ - divb2 %2,%0 - divb3 %2,%1,%0") + div2 %2,%0 + div3 %2,%1,%0") ;This is left out because it is very slow; ;we are better off programming around the "lack" of this insn. @@ -895,247 +517,100 @@ ; "ediv %2,%1,%0,%3") ;; Bit-and on the VAX is done with a clear-bits insn. -(define_expand "andsi3" - [(set (match_operand:SI 0 "nonimmediate_operand" "") - (and:SI (not:SI (match_operand:SI 1 "general_operand" "")) - (match_operand:SI 2 "general_operand" "")))] +(define_expand "and3" + [(set (match_operand:VAXint 0 "nonimmediate_operand" "") + (and:VAXint (not:VAXint (match_operand:VAXint 1 "general_operand" "")) + (match_operand:VAXint 2 "general_operand" "")))] "" " { rtx op1 = operands[1]; /* If there is a constant argument, complement that one. */ - if (GET_CODE (operands[2]) == CONST_INT && GET_CODE (op1) != CONST_INT) + if (CONST_INT_P (operands[2]) && !CONST_INT_P (op1)) { operands[1] = operands[2]; operands[2] = op1; op1 = operands[1]; } - if (GET_CODE (op1) == CONST_INT) - operands[1] = GEN_INT (~INTVAL (op1)); - else - operands[1] = expand_unop (SImode, one_cmpl_optab, op1, 0, 1); -}") - -(define_expand "andhi3" - [(set (match_operand:HI 0 "nonimmediate_operand" "") - (and:HI (not:HI (match_operand:HI 1 "general_operand" "")) - (match_operand:HI 2 "general_operand" "")))] - "" - " -{ - rtx op1 = operands[1]; - - if (GET_CODE (operands[2]) == CONST_INT && GET_CODE (op1) != CONST_INT) - { - operands[1] = operands[2]; - operands[2] = op1; - op1 = operands[1]; - } - - if (GET_CODE (op1) == CONST_INT) - operands[1] = GEN_INT (~INTVAL (op1)); - else - operands[1] = expand_unop (HImode, one_cmpl_optab, op1, 0, 1); -}") - -(define_expand "andqi3" - [(set (match_operand:QI 0 "nonimmediate_operand" "") - (and:QI (not:QI (match_operand:QI 1 "general_operand" "")) - (match_operand:QI 2 "general_operand" "")))] - "" - " -{ - rtx op1 = operands[1]; - - if (GET_CODE (operands[2]) == CONST_INT && GET_CODE (op1) != CONST_INT) - { - operands[1] = operands[2]; - operands[2] = op1; - op1 = operands[1]; - } - - if (GET_CODE (op1) == CONST_INT) + if (CONST_INT_P (op1)) operands[1] = GEN_INT (~INTVAL (op1)); else - operands[1] = expand_unop (QImode, one_cmpl_optab, op1, 0, 1); + operands[1] = expand_unop (mode, one_cmpl_optab, op1, 0, 1); }") -(define_insn "" - [(set (match_operand:SI 0 "nonimmediate_operand" "=g,g") - (and:SI (not:SI (match_operand:SI 1 "general_operand" "g,g")) - (match_operand:SI 2 "general_operand" "0,g")))] +(define_insn "*and" + [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g") + (and:VAXint (not:VAXint (match_operand:VAXint 1 "general_operand" "g,g")) + (match_operand:VAXint 2 "general_operand" "0,g")))] "" "@ - bicl2 %1,%0 - bicl3 %1,%2,%0") - -(define_insn "" - [(set (match_operand:HI 0 "nonimmediate_operand" "=g,g") - (and:HI (not:HI (match_operand:HI 1 "general_operand" "g,g")) - (match_operand:HI 2 "general_operand" "0,g")))] - "" - "@ - bicw2 %1,%0 - bicw3 %1,%2,%0") - -(define_insn "" - [(set (match_operand:QI 0 "nonimmediate_operand" "=g,g") - (and:QI (not:QI (match_operand:QI 1 "general_operand" "g,g")) - (match_operand:QI 2 "general_operand" "0,g")))] - "" - "@ - bicb2 %1,%0 - bicb3 %1,%2,%0") + bic2 %1,%0 + bic3 %1,%2,%0") ;; The following used to be needed because constant propagation can ;; create them starting from the bic insn patterns above. This is no ;; longer a problem. However, having these patterns allows optimization ;; opportunities in combine.c. -(define_insn "" - [(set (match_operand:SI 0 "nonimmediate_operand" "=g,g") - (and:SI (match_operand:SI 1 "general_operand" "0,g") - (match_operand:SI 2 "const_int_operand" "n,n")))] - "" - "@ - bicl2 %N2,%0 - bicl3 %N2,%1,%0") - -(define_insn "" - [(set (match_operand:HI 0 "nonimmediate_operand" "=g,g") - (and:HI (match_operand:HI 1 "general_operand" "0,g") - (match_operand:HI 2 "const_int_operand" "n,n")))] +(define_insn "*and_const_int" + [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g") + (and:VAXint (match_operand:VAXint 1 "general_operand" "0,g") + (match_operand:VAXint 2 "const_int_operand" "n,n")))] "" "@ - bicw2 %H2,%0 - bicw3 %H2,%1,%0") + bic2 %2,%0 + bic3 %2,%1,%0") -(define_insn "" - [(set (match_operand:QI 0 "nonimmediate_operand" "=g,g") - (and:QI (match_operand:QI 1 "general_operand" "0,g") - (match_operand:QI 2 "const_int_operand" "n,n")))] - "" - "@ - bicb2 %B2,%0 - bicb3 %B2,%1,%0") ;;- Bit set instructions. -(define_insn "iorsi3" - [(set (match_operand:SI 0 "nonimmediate_operand" "=g,g,g") - (ior:SI (match_operand:SI 1 "general_operand" "0,g,g") - (match_operand:SI 2 "general_operand" "g,0,g")))] - "" - "@ - bisl2 %2,%0 - bisl2 %1,%0 - bisl3 %2,%1,%0") - -(define_insn "iorhi3" - [(set (match_operand:HI 0 "nonimmediate_operand" "=g,g,g") - (ior:HI (match_operand:HI 1 "general_operand" "0,g,g") - (match_operand:HI 2 "general_operand" "g,0,g")))] +(define_insn "ior3" + [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g") + (ior:VAXint (match_operand:VAXint 1 "general_operand" "0,g,g") + (match_operand:VAXint 2 "general_operand" "g,0,g")))] "" "@ - bisw2 %2,%0 - bisw2 %1,%0 - bisw3 %2,%1,%0") - -(define_insn "iorqi3" - [(set (match_operand:QI 0 "nonimmediate_operand" "=g,g,g") - (ior:QI (match_operand:QI 1 "general_operand" "0,g,g") - (match_operand:QI 2 "general_operand" "g,0,g")))] - "" - "@ - bisb2 %2,%0 - bisb2 %1,%0 - bisb3 %2,%1,%0") + bis2 %2,%0 + bis2 %1,%0 + bis3 %2,%1,%0") ;;- xor instructions. -(define_insn "xorsi3" - [(set (match_operand:SI 0 "nonimmediate_operand" "=g,g,g") - (xor:SI (match_operand:SI 1 "general_operand" "0,g,g") - (match_operand:SI 2 "general_operand" "g,0,g")))] +(define_insn "xor3" + [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g") + (xor:VAXint (match_operand:VAXint 1 "general_operand" "0,g,g") + (match_operand:VAXint 2 "general_operand" "g,0,g")))] "" "@ - xorl2 %2,%0 - xorl2 %1,%0 - xorl3 %2,%1,%0") + xor2 %2,%0 + xor2 %1,%0 + xor3 %2,%1,%0") -(define_insn "xorhi3" - [(set (match_operand:HI 0 "nonimmediate_operand" "=g,g,g") - (xor:HI (match_operand:HI 1 "general_operand" "0,g,g") - (match_operand:HI 2 "general_operand" "g,0,g")))] - "" - "@ - xorw2 %2,%0 - xorw2 %1,%0 - xorw3 %2,%1,%0") - -(define_insn "xorqi3" - [(set (match_operand:QI 0 "nonimmediate_operand" "=g,g,g") - (xor:QI (match_operand:QI 1 "general_operand" "0,g,g") - (match_operand:QI 2 "general_operand" "g,0,g")))] - "" - "@ - xorb2 %2,%0 - xorb2 %1,%0 - xorb3 %2,%1,%0") -(define_insn "negdf2" - [(set (match_operand:DF 0 "nonimmediate_operand" "=g") - (neg:DF (match_operand:DF 1 "general_operand" "gF")))] - "" - "mneg%# %1,%0") - -(define_insn "negsf2" - [(set (match_operand:SF 0 "nonimmediate_operand" "=g") - (neg:SF (match_operand:SF 1 "general_operand" "gF")))] - "" - "mnegf %1,%0") - -(define_insn "negsi2" - [(set (match_operand:SI 0 "nonimmediate_operand" "=g") - (neg:SI (match_operand:SI 1 "general_operand" "g")))] +(define_insn "neg2" + [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g") + (neg:VAXfp (match_operand:VAXfp 1 "general_operand" "gF")))] "" - "mnegl %1,%0") + "mneg %1,%0") -(define_insn "neghi2" - [(set (match_operand:HI 0 "nonimmediate_operand" "=g") - (neg:HI (match_operand:HI 1 "general_operand" "g")))] +(define_insn "neg2" + [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g") + (neg:VAXint (match_operand:VAXint 1 "general_operand" "g")))] "" - "mnegw %1,%0") + "mneg %1,%0") -(define_insn "negqi2" - [(set (match_operand:QI 0 "nonimmediate_operand" "=g") - (neg:QI (match_operand:QI 1 "general_operand" "g")))] - "" - "mnegb %1,%0") - -(define_insn "one_cmplsi2" - [(set (match_operand:SI 0 "nonimmediate_operand" "=g") - (not:SI (match_operand:SI 1 "general_operand" "g")))] +(define_insn "one_cmpl2" + [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g") + (not:VAXint (match_operand:VAXint 1 "general_operand" "g")))] "" - "mcoml %1,%0") + "mcom %1,%0") -(define_insn "one_cmplhi2" - [(set (match_operand:HI 0 "nonimmediate_operand" "=g") - (not:HI (match_operand:HI 1 "general_operand" "g")))] - "" - "mcomw %1,%0") - -(define_insn "one_cmplqi2" - [(set (match_operand:QI 0 "nonimmediate_operand" "=g") - (not:QI (match_operand:QI 1 "general_operand" "g")))] - "" - "mcomb %1,%0") ;; Arithmetic right shift on the VAX works by negating the shift count, ;; then emitting a right shift with the shift count negated. This means -;; that all actual shift counts in the RTL will be positive. This +;; that all actual shift counts in the RTL will be positive. This ;; prevents converting shifts to ZERO_EXTRACTs with negative positions, ;; which isn't valid. (define_expand "ashrsi3" @@ -1145,7 +620,7 @@ "" " { - if (GET_CODE (operands[2]) != CONST_INT) + if (!CONST_INT_P (operands[2])) operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2])); }") @@ -1172,8 +647,8 @@ { if (operands[2] == const1_rtx && rtx_equal_p (operands[0], operands[1])) return \"addl2 %0,%0\"; - if (GET_CODE (operands[1]) == REG - && GET_CODE (operands[2]) == CONST_INT) + if (REG_P (operands[1]) + && CONST_INT_P (operands[2])) { int i = INTVAL (operands[2]); if (i == 1) @@ -1239,7 +714,7 @@ "" " { - if (GET_CODE (operands[2]) != CONST_INT) + if (!CONST_INT_P (operands[2])) operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2])); }") @@ -1285,8 +760,8 @@ (match_operand:SI 3 "general_operand" "g"))] "(INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16) && INTVAL (operands[2]) % INTVAL (operands[1]) == 0 - && (GET_CODE (operands[0]) == REG - || ! mode_dependent_address_p (XEXP (operands[0], 0)))" + && (REG_P (operands[0]) + || !mode_dependent_address_p (XEXP (operands[0], 0)))" "* { if (REG_P (operands[0])) @@ -1313,8 +788,8 @@ (match_operand:SI 3 "const_int_operand" "n")))] "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) && INTVAL (operands[3]) % INTVAL (operands[2]) == 0 - && (GET_CODE (operands[1]) == REG - || ! mode_dependent_address_p (XEXP (operands[1], 0)))" + && (REG_P (operands[1]) + || !mode_dependent_address_p (XEXP (operands[1], 0)))" "* { if (REG_P (operands[1])) @@ -1340,8 +815,8 @@ (match_operand:SI 3 "const_int_operand" "n")))] "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) && INTVAL (operands[3]) % INTVAL (operands[2]) == 0 - && (GET_CODE (operands[1]) == REG - || ! mode_dependent_address_p (XEXP (operands[1], 0)))" + && (REG_P (operands[1]) + || !mode_dependent_address_p (XEXP (operands[1], 0)))" "* { if (REG_P (operands[1])) @@ -1395,8 +870,9 @@ "" "* { - if (GET_CODE (operands[3]) != CONST_INT || GET_CODE (operands[2]) != CONST_INT - || GET_CODE (operands[0]) != REG + if (!CONST_INT_P (operands[3]) + || !CONST_INT_P (operands[2]) + || !REG_P (operands[0]) || (INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16)) return \"extv %3,%2,%1,%0\"; if (INTVAL (operands[2]) == 8) @@ -1412,8 +888,9 @@ "" "* { - if (GET_CODE (operands[3]) != CONST_INT || GET_CODE (operands[2]) != CONST_INT - || GET_CODE (operands[0]) != REG) + if (!CONST_INT_P (operands[3]) + || !CONST_INT_P (operands[2]) + || !REG_P (operands[0])) return \"extzv %3,%2,%1,%0\"; if (INTVAL (operands[2]) == 8) return \"rotl %R3,%1,%0\;movzbl %0,%0\"; @@ -1458,12 +935,13 @@ "" "* { - if (GET_CODE (operands[0]) != REG || GET_CODE (operands[2]) != CONST_INT - || GET_CODE (operands[3]) != CONST_INT + if (!REG_P (operands[0]) + || !CONST_INT_P (operands[2]) + || !CONST_INT_P (operands[3]) || (INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16) || INTVAL (operands[2]) + INTVAL (operands[3]) > 32 || side_effects_p (operands[1]) - || (GET_CODE (operands[1]) == MEM + || (MEM_P (operands[1]) && mode_dependent_address_p (XEXP (operands[1], 0)))) return \"extv %3,%2,%1,%0\"; if (INTVAL (operands[2]) == 8) @@ -1487,11 +965,12 @@ "" "* { - if (GET_CODE (operands[0]) != REG || GET_CODE (operands[2]) != CONST_INT - || GET_CODE (operands[3]) != CONST_INT + if (!REG_P (operands[0]) + || !CONST_INT_P (operands[2]) + || !CONST_INT_P (operands[3]) || INTVAL (operands[2]) + INTVAL (operands[3]) > 32 || side_effects_p (operands[1]) - || (GET_CODE (operands[1]) == MEM + || (MEM_P (operands[1]) && mode_dependent_address_p (XEXP (operands[1], 0)))) return \"extzv %3,%2,%1,%0\"; if (INTVAL (operands[2]) == 8) @@ -1525,101 +1004,24 @@ "" "insv %3,%2,%1,%0") +;; Unconditional jump (define_insn "jump" [(set (pc) (label_ref (match_operand 0 "" "")))] "" "jbr %l0") -(define_insn "beq" - [(set (pc) - (if_then_else (eq (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "jeql %l0") - -(define_insn "bne" - [(set (pc) - (if_then_else (ne (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "jneq %l0") - -(define_insn "bgt" - [(set (pc) - (if_then_else (gt (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "jgtr %l0") - -(define_insn "bgtu" - [(set (pc) - (if_then_else (gtu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "jgtru %l0") - -(define_insn "blt" - [(set (pc) - (if_then_else (lt (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "jlss %l0") - -(define_insn "bltu" - [(set (pc) - (if_then_else (ltu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "jlssu %l0") - -(define_insn "bge" - [(set (pc) - (if_then_else (ge (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "jgeq %l0") - -(define_insn "bgeu" - [(set (pc) - (if_then_else (geu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "jgequ %l0") +;; Conditional jumps +(define_code_iterator any_cond [eq ne gt lt gtu ltu ge le geu leu]) -(define_insn "ble" +(define_insn "b" [(set (pc) - (if_then_else (le (cc0) - (const_int 0)) + (if_then_else (any_cond (cc0) + (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" - "jleq %l0") - -(define_insn "bleu" - [(set (pc) - (if_then_else (leu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "jlequ %l0") + "* return vax_output_conditional_branch ();") ;; Recognize reversed jumps. (define_insn "" @@ -1752,7 +1154,7 @@ (set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))] - "!TARGET_UNIX_ASM && GET_CODE (operands[1]) == CONST_INT" + "!TARGET_UNIX_ASM && CONST_INT_P (operands[1])" "jaoblss %P1,%0,%l2") (define_insn "" @@ -1779,7 +1181,7 @@ (set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))] - "!TARGET_UNIX_ASM && GET_CODE (operands[1]) == CONST_INT" + "!TARGET_UNIX_ASM && CONST_INT_P (operands[1])" "jaobleq %P1,%0,%l2") ;; Something like a sob insn, but compares against -1. @@ -1798,69 +1200,98 @@ "" "decl %0\;jgequ %l1") -;; Note that operand 1 is total size of args, in bytes, -;; and what the call insn wants is the number of words. -;; It is used in the call instruction as a byte, but in the addl2 as -;; a word. Since the only time we actually use it in the call instruction -;; is when it is a constant, SImode (for addl2) is the proper mode. (define_expand "call_pop" [(parallel [(call (match_operand:QI 0 "memory_operand" "") (match_operand:SI 1 "const_int_operand" "")) - (set (reg:SI 14) - (plus:SI (reg:SI 14) + (set (reg:SI VAX_SP_REGNUM) + (plus:SI (reg:SI VAX_SP_REGNUM) (match_operand:SI 3 "immediate_operand" "")))])] "" - " { - if (INTVAL (operands[1]) > 255 * 4) - abort (); - operands[1] = GEN_INT ((INTVAL (operands[1]) + 3)/ 4); -}") + gcc_assert (INTVAL (operands[3]) <= 255 * 4 && INTVAL (operands[3]) % 4 == 0); + + /* Operand 1 is the number of bytes to be popped by DW_CFA_GNU_args_size + during EH unwinding. We must include the argument count pushed by + the calls instruction. */ + operands[1] = GEN_INT (INTVAL (operands[3]) + 4); +}) (define_insn "*call_pop" [(call (match_operand:QI 0 "memory_operand" "m") (match_operand:SI 1 "const_int_operand" "n")) - (set (reg:SI 14) (plus:SI (reg:SI 14) - (match_operand:SI 2 "immediate_operand" "i")))] + (set (reg:SI VAX_SP_REGNUM) (plus:SI (reg:SI VAX_SP_REGNUM) + (match_operand:SI 2 "immediate_operand" "i")))] "" - "calls %1,%0") +{ + operands[1] = GEN_INT ((INTVAL (operands[1]) - 4) / 4); + return "calls %1,%0"; +}) (define_expand "call_value_pop" [(parallel [(set (match_operand 0 "" "") (call (match_operand:QI 1 "memory_operand" "") (match_operand:SI 2 "const_int_operand" ""))) - (set (reg:SI 14) - (plus:SI (reg:SI 14) + (set (reg:SI VAX_SP_REGNUM) + (plus:SI (reg:SI VAX_SP_REGNUM) (match_operand:SI 4 "immediate_operand" "")))])] "" - " { - if (INTVAL (operands[2]) > 255 * 4) - abort (); - operands[2] = GEN_INT ((INTVAL (operands[2]) + 3)/ 4); -}") + gcc_assert (INTVAL (operands[4]) <= 255 * 4 && INTVAL (operands[4]) % 4 == 0); + + /* Operand 2 is the number of bytes to be popped by DW_CFA_GNU_args_size + during EH unwinding. We must include the argument count pushed by + the calls instruction. */ + operands[2] = GEN_INT (INTVAL (operands[4]) + 4); +}) (define_insn "*call_value_pop" [(set (match_operand 0 "" "") (call (match_operand:QI 1 "memory_operand" "m") (match_operand:SI 2 "const_int_operand" "n"))) - (set (reg:SI 14) (plus:SI (reg:SI 14) - (match_operand:SI 3 "immediate_operand" "i")))] + (set (reg:SI VAX_SP_REGNUM) (plus:SI (reg:SI VAX_SP_REGNUM) + (match_operand:SI 3 "immediate_operand" "i")))] + "" + "* +{ + operands[2] = GEN_INT ((INTVAL (operands[2]) - 4) / 4); + return \"calls %2,%1\"; +}") + +(define_expand "call" + [(call (match_operand:QI 0 "memory_operand" "") + (match_operand:SI 1 "const_int_operand" ""))] "" - "calls %2,%1") + " +{ + /* Operand 1 is the number of bytes to be popped by DW_CFA_GNU_args_size + during EH unwinding. We must include the argument count pushed by + the calls instruction. */ + operands[1] = GEN_INT (INTVAL (operands[1]) + 4); +}") -;; Define another set of these for the case of functions with no operands. -;; These will allow the optimizers to do a slightly better job. -(define_insn "call" - [(call (match_operand:QI 0 "memory_operand" "m") - (const_int 0))] +(define_insn "*call" + [(call (match_operand:QI 0 "memory_operand" "m") + (match_operand:SI 1 "const_int_operand" ""))] "" "calls $0,%0") -(define_insn "call_value" +(define_expand "call_value" + [(set (match_operand 0 "" "") + (call (match_operand:QI 1 "memory_operand" "") + (match_operand:SI 2 "const_int_operand" "")))] + "" + " +{ + /* Operand 2 is the number of bytes to be popped by DW_CFA_GNU_args_size + during EH unwinding. We must include the argument count pushed by + the calls instruction. */ + operands[2] = GEN_INT (INTVAL (operands[2]) + 4); +}") + +(define_insn "*call_value" [(set (match_operand 0 "" "") (call (match_operand:QI 1 "memory_operand" "m") - (const_int 0)))] + (match_operand:SI 2 "const_int_operand" "")))] "" "calls $0,%1") @@ -1897,7 +1328,7 @@ ;; all of memory. This blocks insns from being moved across this point. (define_insn "blockage" - [(unspec_volatile [(const_int 0)] 0)] + [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)] "" "") @@ -1929,79 +1360,67 @@ "jmp (%0)") ;; This is here to accept 5 arguments (as passed by expand_end_case) -;; and pass the first 4 along to the casesi1 pattern that really does the work. +;; and pass the first 4 along to the casesi1 pattern that really does +;; the actual casesi work. We emit a jump here to the default label +;; _before_ the casesi so that we can be sure that the casesi never +;; drops through. +;; This is suboptimal perhaps, but so is much of the rest of this +;; machine description. For what it's worth, HPPA uses the same trick. +;; +;; operand 0 is index +;; operand 1 is the minimum bound (a const_int) +;; operand 2 is the maximum bound - minimum bound + 1 (also a const_int) +;; operand 3 is CODE_LABEL for the table; +;; operand 4 is the CODE_LABEL to go to if index out of range (ie. default). +;; +;; We emit: +;; i = index - minimum_bound +;; if (i > (maximum_bound - minimum_bound + 1) goto default; +;; casesi (i, 0, table); +;; (define_expand "casesi" - [(set (pc) - (if_then_else - (leu (minus:SI (match_operand:SI 0 "general_operand" "") - (match_operand:SI 1 "general_operand" "")) - (match_operand:SI 2 "general_operand" "")) - (plus:SI (sign_extend:SI - (mem:HI (plus:SI (mult:SI (minus:SI (match_dup 0) - (match_dup 1)) - (const_int 2)) - (pc)))) - (label_ref:SI (match_operand 3 "" ""))) - (pc))) + [(match_operand:SI 0 "general_operand" "") + (match_operand:SI 1 "general_operand" "") + (match_operand:SI 2 "general_operand" "") + (match_operand 3 "" "") (match_operand 4 "" "")] "" - " - emit_jump_insn (gen_casesi1 (operands[0], operands[1], operands[2], operands[3])); - DONE; -") +{ + /* i = index - minimum_bound; + But only if the lower bound is not already zero. */ + if (operands[1] != const0_rtx) + { + rtx index = gen_reg_rtx (SImode); + emit_insn (gen_addsi3 (index, + operands[0], + GEN_INT (-INTVAL (operands[1])))); + operands[0] = index; + } -(define_insn "casesi1" - [(set (pc) - (if_then_else - (leu (minus:SI (match_operand:SI 0 "general_operand" "g") - (match_operand:SI 1 "general_operand" "g")) - (match_operand:SI 2 "general_operand" "g")) - (plus:SI (sign_extend:SI - (mem:HI (plus:SI (mult:SI (minus:SI (match_dup 0) - (match_dup 1)) - (const_int 2)) - (pc)))) - (label_ref:SI (match_operand 3 "" ""))) - (pc)))] - "" - "casel %0,%1,%2") + /* if (i > (maximum_bound - minimum_bound + 1) goto default; */ + emit_insn (gen_cmpsi (operands[0], operands[2])); + emit_jump_insn (gen_bgtu (operands[4])); -;; This can arise by simplification when operand 1 is a constant int. -(define_insn "" - [(set (pc) - (if_then_else - (leu (plus:SI (match_operand:SI 0 "general_operand" "g") - (match_operand:SI 1 "const_int_operand" "n")) - (match_operand:SI 2 "general_operand" "g")) - (plus:SI (sign_extend:SI - (mem:HI (plus:SI (mult:SI (plus:SI (match_dup 0) - (match_dup 1)) - (const_int 2)) - (pc)))) - (label_ref:SI (match_operand 3 "" ""))) - (pc)))] - "" - "* -{ - operands[1] = GEN_INT (-INTVAL (operands[1])); - return \"casel %0,%1,%2\"; -}") + /* casesi (i, 0, table); */ + emit_jump_insn (gen_casesi1 (operands[0], operands[2], operands[3])); + DONE; +}) -;; This can arise by simplification when the base for the case insn is zero. -(define_insn "" - [(set (pc) - (if_then_else (leu (match_operand:SI 0 "general_operand" "g") - (match_operand:SI 1 "general_operand" "g")) - (plus:SI (sign_extend:SI - (mem:HI (plus:SI (mult:SI (match_dup 0) - (const_int 2)) - (pc)))) - (label_ref:SI (match_operand 2 "" ""))) - (pc)))] +;; This insn is a bit of a lier. It actually falls through if no case +;; matches. But, we prevent that from ever happening by emitting a jump +;; before this, see the define_expand above. +(define_insn "casesi1" + [(match_operand:SI 1 "const_int_operand" "n") + (set (pc) + (plus:SI (sign_extend:SI + (mem:HI (plus:SI (mult:SI (match_operand:SI 0 "general_operand" "g") + (const_int 2)) + (pc)))) + (label_ref:SI (match_operand 2 "" ""))))] "" "casel %0,$0,%1") -;;- load or push effective address +;;- load or push effective address ;; These come after the move and add/sub patterns ;; because we don't want pushl $1 turned into pushad 1. ;; or addl3 r1,r2,r3 turned into movab 0(r1)[r2],r3. @@ -2084,7 +1503,7 @@ ;; These used to be peepholes, but it is more straightforward to do them ;; as single insns. However, we must force the output to be a register ;; if it is not an offsettable address so that we know that we can assign -;; to it twice. +;; to it twice. ;; If we had a good way of evaluating the relative costs, these could be ;; machine-independent. @@ -2128,3 +1547,9 @@ = GEN_INT (INTVAL (operands[3]) & ~((1 << INTVAL (operands[2])) - 1)); return \"rotl %2,%1,%0\;bicl2 %N3,%0\"; }") + +;; Instruction sequence to sync the VAX instruction stream. +(define_insn "sync_istream" + [(unspec_volatile [(const_int 0)] VUNSPEC_SYNC_ISTREAM)] + "" + "movpsl -(%|sp)\;pushal 1(%|pc)\;rei")