|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T v
Length: 56520 (0xdcc8) Types: TextFile Names: »vax.md«
└─⟦a05ed705a⟧ Bits:30007078 DKUUG GNU 2/12/89 └─⟦d53cfc7b2⟧ »./gcc-1.35.tar.Z« └─⟦90f628c1d⟧ └─⟦this⟧ »gcc-1.35/config/vax.md«
;;- Machine description for GNU compiler ;;- Vax Version ;; Copyright (C) 1987, 1988 Free Software Foundation, Inc. ;; 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA. ;;- 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. ;;- ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code ;;- updates for most instructions. ; tstsi is first test insn so that it is the one to match ; a constant argument. (define_insn "tstsi" [(set (cc0) (match_operand:SI 0 "general_operand" "g"))] "" "tstl %0") (define_insn "tsthi" [(set (cc0) (match_operand:HI 0 "general_operand" "g"))] "" "tstw %0") (define_insn "tstqi" [(set (cc0) (match_operand:QI 0 "general_operand" "g"))] "" "tstb %0") (define_insn "tstdf" [(set (cc0) (match_operand:DF 0 "general_operand" "gF"))] "" "tst%# %0") (define_insn "tstsf" [(set (cc0) (match_operand:SF 0 "general_operand" "gF"))] "" "tstf %0") (define_insn "cmpsi" [(set (cc0) (compare (match_operand:SI 0 "general_operand" "g") (match_operand:SI 1 "general_operand" "g")))] "" "cmpl %0,%1") (define_insn "cmphi" [(set (cc0) (compare (match_operand:HI 0 "general_operand" "g") (match_operand:HI 1 "general_operand" "g")))] "" "cmpw %0,%1") (define_insn "cmpqi" [(set (cc0) (compare (match_operand:QI 0 "general_operand" "g") (match_operand:QI 1 "general_operand" "g")))] "" "cmpb %0,%1") (define_insn "cmpdf" [(set (cc0) (compare (match_operand:DF 0 "general_operand" "gF") (match_operand:DF 1 "general_operand" "gF")))] "" "cmp%# %0,%1") (define_insn "cmpsf" [(set (cc0) (compare (match_operand:SF 0 "general_operand" "gF") (match_operand:SF 1 "general_operand" "gF")))] "" "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") (define_insn "" [(set (cc0) (and:HI (match_operand:HI 0 "general_operand" "g") (match_operand:HI 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") \f (define_insn "movdf" [(set (match_operand:DF 0 "general_operand" "=g") (match_operand:DF 1 "general_operand" "gF"))] "" "* { if (operands[1] == dconst0_rtx) return \"clr%# %0\"; return \"mov%# %1,%0\"; }") (define_insn "movsf" [(set (match_operand:SF 0 "general_operand" "=g") (match_operand:SF 1 "general_operand" "gF"))] "" "* { if (operands[1] == fconst0_rtx) return \"clrf %0\"; return \"movf %1,%0\"; }") ;; Some vaxes don't support this instruction. ;;(define_insn "movti" ;; [(set (match_operand:TI 0 "general_operand" "=g") ;; (match_operand:TI 1 "general_operand" "g"))] ;; "" ;; "movh %1,%0") (define_insn "movdi" [(set (match_operand:DI 0 "general_operand" "=g") (match_operand:DI 1 "general_operand" "g"))] "" "movq %1,%0") (define_insn "movsi" [(set (match_operand:SI 0 "general_operand" "=g") (match_operand:SI 1 "general_operand" "g"))] "" "* { rtx link; if (operands[1] == const1_rtx && (link = find_reg_note (insn, REG_WAS_0, 0)) /* Make sure the insn that stored the 0 is still present. */ && ! XEXP (link, 0)->volatil && GET_CODE (XEXP (link, 0)) != NOTE /* Make sure cross jumping didn't happen here. */ && no_labels_between_p (XEXP (link, 0), insn)) /* Fastest way to change a 0 to a 1. */ 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\"; } /* this is slower than a movl, except when pushing an operand */ 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) { operands[1] = gen_rtx (CONST_INT, VOIDmode, ~i); return \"mcoml %1,%0\"; } if ((unsigned)i < 127) { operands[1] = gen_rtx (CONST_INT, VOIDmode, 63); operands[2] = gen_rtx (CONST_INT, VOIDmode, i-63); return \"addl3 %2,%1,%0\"; } /* trading speed for space */ 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 "general_operand" "=g") (match_operand:HI 1 "general_operand" "g"))] "" "* { rtx link; if (operands[1] == const1_rtx && (link = find_reg_note (insn, REG_WAS_0, 0)) /* Make sure the insn that stored the 0 is still present. */ && ! XEXP (link, 0)->volatil && GET_CODE (XEXP (link, 0)) != NOTE /* Make sure cross jumping didn't happen here. */ && no_labels_between_p (XEXP (link, 0), insn)) /* Fastest way to change a 0 to a 1. */ return \"incw %0\"; if (operands[1] == const0_rtx) return \"clrw %0\"; if (GET_CODE (operands[1]) == CONST_INT && (unsigned) INTVAL (operands[1]) >= 64) { int i = INTVAL (operands[1]); if ((unsigned)((~i) & 0xffff) < 64) { operands[1] = gen_rtx (CONST_INT, VOIDmode, (~i) & 0xffff); return \"mcomw %1,%0\"; } if ((unsigned)(i & 0xffff) < 127) { operands[1] = gen_rtx (CONST_INT, VOIDmode, 63); operands[2] = gen_rtx (CONST_INT, VOIDmode, (i-63) & 0xffff); return \"addw3 %2,%1,%0\"; } /* this is a lot slower, and only saves 1 measly byte! */ /* if ((unsigned)i < 0x100) return \"movzbw %1,%0\"; */ /* if (i >= -0x80 && i < 0) return \"cvtbw %1,%0\"; */ } return \"movw %1,%0\"; }") (define_insn "movqi" [(set (match_operand:QI 0 "general_operand" "=g") (match_operand:QI 1 "general_operand" "g"))] "" "* { if (operands[1] == const0_rtx) return \"clrb %0\"; if (GET_CODE (operands[1]) == CONST_INT && (unsigned) INTVAL (operands[1]) >= 64) { int i = INTVAL (operands[1]); if ((unsigned)((~i) & 0xff) < 64) { operands[1] = gen_rtx (CONST_INT, VOIDmode, (~i) & 0xff); return \"mcomb %1,%0\"; } #if 0 /* ASCII alphabetics */ if (((unsigned) INTVAL (operands[1]) &0xff) < 127) { operands[1] = gen_rtx (CONST_INT, VOIDmode, 63); operands[2] = gen_rtx (CONST_INT, VOIDmode, i-63); return \"addb3 %2,%1,%0\"; } #endif } return \"movb %1,%0\"; }") ;; The definition of this insn does not really explain what it does, ;; 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 "movstrhi" [(set (match_operand:BLK 0 "general_operand" "=g") (match_operand:BLK 1 "general_operand" "g")) (use (match_operand:HI 2 "general_operand" "g")) (clobber (reg:SI 0)) (clobber (reg:SI 1)) (clobber (reg:SI 2)) (clobber (reg:SI 3)) (clobber (reg:SI 4)) (clobber (reg:SI 5))] "" "movc3 %2,%1,%0") \f ;; Extension and truncation insns. ;; Those for integer source operand ;; are ordered widest source type first. (define_insn "truncsiqi2" [(set (match_operand:QI 0 "general_operand" "=g") (truncate:QI (match_operand:SI 1 "general_operand" "g")))] "" "cvtlb %1,%0") (define_insn "truncsihi2" [(set (match_operand:HI 0 "general_operand" "=g") (truncate:HI (match_operand:SI 1 "general_operand" "g")))] "" "cvtlw %1,%0") (define_insn "trunchiqi2" [(set (match_operand:QI 0 "general_operand" "=g") (truncate:QI (match_operand:HI 1 "general_operand" "g")))] "" "cvtwb %1,%0") (define_insn "extendhisi2" [(set (match_operand:SI 0 "general_operand" "=g") (sign_extend:SI (match_operand:HI 1 "general_operand" "g")))] "" "cvtwl %1,%0") (define_insn "extendqihi2" [(set (match_operand:HI 0 "general_operand" "=g") (sign_extend:HI (match_operand:QI 1 "general_operand" "g")))] "" "cvtbw %1,%0") (define_insn "extendqisi2" [(set (match_operand:SI 0 "general_operand" "=g") (sign_extend:SI (match_operand:QI 1 "general_operand" "g")))] "" "cvtbl %1,%0") (define_insn "extendsfdf2" [(set (match_operand:DF 0 "general_operand" "=g") (float_extend:DF (match_operand:SF 1 "general_operand" "gF")))] "" "cvtf%# %1,%0") (define_insn "truncdfsf2" [(set (match_operand:SF 0 "general_operand" "=g") (float_truncate:SF (match_operand:DF 1 "general_operand" "gF")))] "" "cvt%#f %1,%0") (define_insn "zero_extendhisi2" [(set (match_operand:SI 0 "general_operand" "=g") (zero_extend:SI (match_operand:HI 1 "general_operand" "g")))] "" "movzwl %1,%0") (define_insn "zero_extendqihi2" [(set (match_operand:HI 0 "general_operand" "=g") (zero_extend:HI (match_operand:QI 1 "general_operand" "g")))] "" "movzbw %1,%0") (define_insn "zero_extendqisi2" [(set (match_operand:SI 0 "general_operand" "=g") (zero_extend:SI (match_operand:QI 1 "general_operand" "g")))] "" "movzbl %1,%0") \f ;; Fix-to-float conversion insns. ;; Note that the ones that start with SImode come first. ;; That is so that an operand that is a CONST_INT ;; (and therefore lacks a specific machine mode). ;; will be recognized as SImode (which is always valid) ;; rather than as QImode or HImode. (define_insn "floatsisf2" [(set (match_operand:SF 0 "general_operand" "=g") (float:SF (match_operand:SI 1 "general_operand" "g")))] "" "cvtlf %1,%0") (define_insn "floatsidf2" [(set (match_operand:DF 0 "general_operand" "=g") (float:DF (match_operand:SI 1 "general_operand" "g")))] "" "cvtl%# %1,%0") (define_insn "floathisf2" [(set (match_operand:SF 0 "general_operand" "=g") (float:SF (match_operand:HI 1 "general_operand" "g")))] "" "cvtwf %1,%0") (define_insn "floathidf2" [(set (match_operand:DF 0 "general_operand" "=g") (float:DF (match_operand:HI 1 "general_operand" "g")))] "" "cvtw%# %1,%0") (define_insn "floatqisf2" [(set (match_operand:SF 0 "general_operand" "=g") (float:SF (match_operand:QI 1 "general_operand" "g")))] "" "cvtbf %1,%0") (define_insn "floatqidf2" [(set (match_operand:DF 0 "general_operand" "=g") (float:DF (match_operand:QI 1 "general_operand" "g")))] "" "cvtb%# %1,%0") \f ;; Float-to-fix conversion insns. (define_insn "fix_truncsfqi2" [(set (match_operand:QI 0 "general_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 "general_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 "general_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 "general_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 "general_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 "general_operand" "=g") (fix:SI (fix:DF (match_operand:DF 1 "general_operand" "gF"))))] "" "cvt%#l %1,%0") \f ;;- All kinds of add instructions. (define_insn "adddf3" [(set (match_operand:DF 0 "general_operand" "=g") (plus:DF (match_operand:DF 1 "general_operand" "gF") (match_operand:DF 2 "general_operand" "gF")))] "" "* { if (rtx_equal_p (operands[0], operands[1])) return \"add%#2 %2,%0\"; if (rtx_equal_p (operands[0], operands[2])) return \"add%#2 %1,%0\"; return \"add%#3 %1,%2,%0\"; }") (define_insn "addsf3" [(set (match_operand:SF 0 "general_operand" "=g") (plus:SF (match_operand:SF 1 "general_operand" "gF") (match_operand:SF 2 "general_operand" "gF")))] "" "* { if (rtx_equal_p (operands[0], operands[1])) return \"addf2 %2,%0\"; if (rtx_equal_p (operands[0], operands[2])) return \"addf2 %1,%0\"; return \"addf3 %1,%2,%0\"; }") (define_insn "addsi3" [(set (match_operand:SI 0 "general_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 (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == -1) 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) 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 && (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) { if (push_operand (operands[0], SImode)) return \"pushab %c2(%1)\"; return \"movab %c2(%1),%0\"; } return \"addl3 %1,%2,%0\"; }") (define_insn "addhi3" [(set (match_operand:HI 0 "general_operand" "=g") (plus:HI (match_operand:HI 1 "general_operand" "g") (match_operand:HI 2 "general_operand" "g")))] "" "* { if (rtx_equal_p (operands[0], operands[1])) { if (operands[2] == const1_rtx) return \"incw %0\"; if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == -1) 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 "general_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 (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == -1) 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\"; }") \f ;;- All kinds of subtract instructions. (define_insn "subdf3" [(set (match_operand:DF 0 "general_operand" "=g") (minus:DF (match_operand:DF 1 "general_operand" "gF") (match_operand:DF 2 "general_operand" "gF")))] "" "* { if (rtx_equal_p (operands[0], operands[1])) return \"sub%#2 %2,%0\"; return \"sub%#3 %2,%1,%0\"; }") (define_insn "subsf3" [(set (match_operand:SF 0 "general_operand" "=g") (minus:SF (match_operand:SF 1 "general_operand" "gF") (match_operand:SF 2 "general_operand" "gF")))] "" "* { if (rtx_equal_p (operands[0], operands[1])) return \"subf2 %2,%0\"; return \"subf3 %2,%1,%0\"; }") (define_insn "subsi3" [(set (match_operand:SI 0 "general_operand" "=g") (minus: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 \"decl %0\"; return \"subl2 %2,%0\"; } return \"subl3 %2,%1,%0\"; }") (define_insn "subhi3" [(set (match_operand:HI 0 "general_operand" "=g") (minus:HI (match_operand:HI 1 "general_operand" "g") (match_operand:HI 2 "general_operand" "g")))] "" "* { if (rtx_equal_p (operands[0], operands[1])) { if (operands[2] == const1_rtx) return \"decw %0\"; return \"subw2 %2,%0\"; } return \"subw3 %2,%1,%0\"; }") (define_insn "subqi3" [(set (match_operand:QI 0 "general_operand" "=g") (minus: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 \"decb %0\"; return \"subb2 %2,%0\"; } return \"subb3 %2,%1,%0\"; }") \f ;;- Multiply instructions. (define_insn "muldf3" [(set (match_operand:DF 0 "general_operand" "=g") (mult:DF (match_operand:DF 1 "general_operand" "gF") (match_operand:DF 2 "general_operand" "gF")))] "" "* { if (rtx_equal_p (operands[0], operands[1])) return \"mul%#2 %2,%0\"; if (rtx_equal_p (operands[0], operands[2])) return \"mul%#2 %1,%0\"; return \"mul%#3 %1,%2,%0\"; }") (define_insn "mulsf3" [(set (match_operand:SF 0 "general_operand" "=g") (mult:SF (match_operand:SF 1 "general_operand" "gF") (match_operand:SF 2 "general_operand" "gF")))] "" "* { if (rtx_equal_p (operands[0], operands[1])) return \"mulf2 %2,%0\"; if (rtx_equal_p (operands[0], operands[2])) return \"mulf2 %1,%0\"; return \"mulf3 %1,%2,%0\"; }") (define_insn "mulsi3" [(set (match_operand:SI 0 "general_operand" "=g") (mult:SI (match_operand:SI 1 "general_operand" "g") (match_operand:SI 2 "general_operand" "g")))] "" "* { if (rtx_equal_p (operands[0], operands[1])) return \"mull2 %2,%0\"; if (rtx_equal_p (operands[0], operands[2])) return \"mull2 %1,%0\"; return \"mull3 %1,%2,%0\"; }") (define_insn "mulhi3" [(set (match_operand:HI 0 "general_operand" "=g") (mult:HI (match_operand:HI 1 "general_operand" "g") (match_operand:HI 2 "general_operand" "g")))] "" "* { if (rtx_equal_p (operands[0], operands[1])) return \"mulw2 %2,%0\"; if (rtx_equal_p (operands[0], operands[2])) return \"mulw2 %1,%0\"; return \"mulw3 %1,%2,%0\"; }") (define_insn "mulqi3" [(set (match_operand:QI 0 "general_operand" "=g") (mult:QI (match_operand:QI 1 "general_operand" "g") (match_operand:QI 2 "general_operand" "g")))] "" "* { if (rtx_equal_p (operands[0], operands[1])) return \"mulb2 %2,%0\"; if (rtx_equal_p (operands[0], operands[2])) return \"mulb2 %1,%0\"; return \"mulb3 %1,%2,%0\"; }") \f ;;- Divide instructions. (define_insn "divdf3" [(set (match_operand:DF 0 "general_operand" "=g") (div:DF (match_operand:DF 1 "general_operand" "gF") (match_operand:DF 2 "general_operand" "gF")))] "" "* { if (rtx_equal_p (operands[0], operands[1])) return \"div%#2 %2,%0\"; return \"div%#3 %2,%1,%0\"; }") (define_insn "divsf3" [(set (match_operand:SF 0 "general_operand" "=g") (div:SF (match_operand:SF 1 "general_operand" "gF") (match_operand:SF 2 "general_operand" "gF")))] "" "* { if (rtx_equal_p (operands[0], operands[1])) return \"divf2 %2,%0\"; return \"divf3 %2,%1,%0\"; }") (define_insn "divsi3" [(set (match_operand:SI 0 "general_operand" "=g") (div:SI (match_operand:SI 1 "general_operand" "g") (match_operand:SI 2 "general_operand" "g")))] "" "* { if (rtx_equal_p (operands[0], operands[1])) return \"divl2 %2,%0\"; return \"divl3 %2,%1,%0\"; }") (define_insn "divhi3" [(set (match_operand:HI 0 "general_operand" "=g") (div:HI (match_operand:HI 1 "general_operand" "g") (match_operand:HI 2 "general_operand" "g")))] "" "* { if (rtx_equal_p (operands[0], operands[1])) return \"divw2 %2,%0\"; return \"divw3 %2,%1,%0\"; }") (define_insn "divqi3" [(set (match_operand:QI 0 "general_operand" "=g") (div:QI (match_operand:QI 1 "general_operand" "g") (match_operand:QI 2 "general_operand" "g")))] "" "* { if (rtx_equal_p (operands[0], operands[1])) return \"divb2 %2,%0\"; return \"divb3 %2,%1,%0\"; }") ;This is left out because it is very slow; ;we are better off programming around the "lack" of this insn. ;(define_insn "divmoddisi4" ; [(set (match_operand:SI 0 "general_operand" "=g") ; (div:SI (match_operand:DI 1 "general_operand" "g") ; (match_operand:SI 2 "general_operand" "g"))) ; (set (match_operand:SI 3 "general_operand" "=g") ; (mod:SI (match_operand:DI 1 "general_operand" "g") ; (match_operand:SI 2 "general_operand" "g")))] ; "" ; "ediv %2,%1,%0,%3") \f ;; Bit-and on the vax is done with a clear-bits insn. (define_expand "andsi3" [(set (match_operand:SI 0 "general_operand" "=g") (and:SI (match_operand:SI 1 "general_operand" "g") (not:SI (match_operand:SI 2 "general_operand" "g"))))] "" " { extern rtx expand_unop (); if (GET_CODE (operands[2]) == CONST_INT) operands[2] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2])); else operands[2] = expand_unop (SImode, one_cmpl_optab, operands[2], 0, 1); }") (define_expand "andhi3" [(set (match_operand:HI 0 "general_operand" "=g") (and:HI (match_operand:HI 1 "general_operand" "g") (not:HI (match_operand:HI 2 "general_operand" "g"))))] "" " { extern rtx expand_unop (); rtx op = operands[2]; if (GET_CODE (op) == CONST_INT) operands[2] = gen_rtx (CONST_INT, VOIDmode, ((1 << 16) - 1) & ~INTVAL (op)); else operands[2] = expand_unop (HImode, one_cmpl_optab, op, 0, 1); }") (define_expand "andqi3" [(set (match_operand:QI 0 "general_operand" "=g") (and:QI (match_operand:QI 1 "general_operand" "g") (not:QI (match_operand:QI 2 "general_operand" "g"))))] "" " { extern rtx expand_unop (); rtx op = operands[2]; if (GET_CODE (op) == CONST_INT) operands[2] = gen_rtx (CONST_INT, VOIDmode, ((1 << 8) - 1) & ~INTVAL (op)); else operands[2] = expand_unop (QImode, one_cmpl_optab, op, 0, 1); }") (define_insn "andcbsi3" [(set (match_operand:SI 0 "general_operand" "=g") (and:SI (match_operand:SI 1 "general_operand" "g") (not:SI (match_operand:SI 2 "general_operand" "g"))))] "" "* { if (rtx_equal_p (operands[0], operands[1])) return \"bicl2 %2,%0\"; return \"bicl3 %2,%1,%0\"; }") (define_insn "andcbhi3" [(set (match_operand:HI 0 "general_operand" "=g") (and:HI (match_operand:HI 1 "general_operand" "g") (not:HI (match_operand:HI 2 "general_operand" "g"))))] "" "* { if (rtx_equal_p (operands[0], operands[1])) return \"bicw2 %2,%0\"; return \"bicw3 %2,%1,%0\"; }") (define_insn "andcbqi3" [(set (match_operand:QI 0 "general_operand" "=g") (and:QI (match_operand:QI 1 "general_operand" "g") (not:QI (match_operand:QI 2 "general_operand" "g"))))] "" "* { if (rtx_equal_p (operands[0], operands[1])) return \"bicb2 %2,%0\"; return \"bicb3 %2,%1,%0\"; }") ;; The following are needed because constant propagation can ;; create them starting from the bic insn patterns above. (define_insn "" [(set (match_operand:SI 0 "general_operand" "=g") (and:SI (match_operand:SI 1 "general_operand" "g") (match_operand:SI 2 "general_operand" "g")))] "GET_CODE (operands[2]) == CONST_INT" "* { operands[2] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2])); if (rtx_equal_p (operands[1], operands[0])) return \"bicl2 %2,%0\"; return \"bicl3 %2,%1,%0\"; }") (define_insn "" [(set (match_operand:HI 0 "general_operand" "=g") (and:HI (match_operand:HI 1 "general_operand" "g") (match_operand:HI 2 "general_operand" "g")))] "GET_CODE (operands[2]) == CONST_INT" "* { operands[2] = gen_rtx (CONST_INT, VOIDmode, 0xffff & ~INTVAL (operands[2])); if (rtx_equal_p (operands[1], operands[0])) return \"bicw2 %2,%0\"; return \"bicw3 %2,%1,%0\"; }") (define_insn "" [(set (match_operand:QI 0 "general_operand" "=g") (and:QI (match_operand:QI 1 "general_operand" "g") (match_operand:QI 2 "general_operand" "g")))] "GET_CODE (operands[2]) == CONST_INT" "* { operands[2] = gen_rtx (CONST_INT, VOIDmode, 0xff & ~INTVAL (operands[2])); if (rtx_equal_p (operands[1], operands[0])) return \"bicb2 %2,%0\"; return \"bicb3 %2,%1,%0\"; }") \f ;;- Bit set instructions. (define_insn "iorsi3" [(set (match_operand:SI 0 "general_operand" "=g") (ior:SI (match_operand:SI 1 "general_operand" "g") (match_operand:SI 2 "general_operand" "g")))] "" "* { if (rtx_equal_p (operands[0], operands[1])) return \"bisl2 %2,%0\"; if (rtx_equal_p (operands[0], operands[2])) return \"bisl2 %1,%0\"; return \"bisl3 %2,%1,%0\"; }") (define_insn "iorhi3" [(set (match_operand:HI 0 "general_operand" "=g") (ior:HI (match_operand:HI 1 "general_operand" "g") (match_operand:HI 2 "general_operand" "g")))] "" "* { if (rtx_equal_p (operands[0], operands[1])) return \"bisw2 %2,%0\"; if (rtx_equal_p (operands[0], operands[2])) return \"bisw2 %1,%0\"; return \"bisw3 %2,%1,%0\"; }") (define_insn "iorqi3" [(set (match_operand:QI 0 "general_operand" "=g") (ior:QI (match_operand:QI 1 "general_operand" "g") (match_operand:QI 2 "general_operand" "g")))] "" "* { if (rtx_equal_p (operands[0], operands[1])) return \"bisb2 %2,%0\"; if (rtx_equal_p (operands[0], operands[2])) return \"bisb2 %1,%0\"; return \"bisb3 %2,%1,%0\"; }") ;;- xor instructions. (define_insn "xorsi3" [(set (match_operand:SI 0 "general_operand" "=g") (xor:SI (match_operand:SI 1 "general_operand" "g") (match_operand:SI 2 "general_operand" "g")))] "" "* { if (rtx_equal_p (operands[0], operands[1])) return \"xorl2 %2,%0\"; if (rtx_equal_p (operands[0], operands[2])) return \"xorl2 %1,%0\"; return \"xorl3 %2,%1,%0\"; }") (define_insn "xorhi3" [(set (match_operand:HI 0 "general_operand" "=g") (xor:HI (match_operand:HI 1 "general_operand" "g") (match_operand:HI 2 "general_operand" "g")))] "" "* { if (rtx_equal_p (operands[0], operands[1])) return \"xorw2 %2,%0\"; if (rtx_equal_p (operands[0], operands[2])) return \"xorw2 %1,%0\"; return \"xorw3 %2,%1,%0\"; }") (define_insn "xorqi3" [(set (match_operand:QI 0 "general_operand" "=g") (xor:QI (match_operand:QI 1 "general_operand" "g") (match_operand:QI 2 "general_operand" "g")))] "" "* { if (rtx_equal_p (operands[0], operands[1])) return \"xorb2 %2,%0\"; if (rtx_equal_p (operands[0], operands[2])) return \"xorb2 %1,%0\"; return \"xorb3 %2,%1,%0\"; }") \f (define_insn "negdf2" [(set (match_operand:DF 0 "general_operand" "=g") (neg:DF (match_operand:DF 1 "general_operand" "gF")))] "" "mneg%# %1,%0") (define_insn "negsf2" [(set (match_operand:SF 0 "general_operand" "=g") (neg:SF (match_operand:SF 1 "general_operand" "gF")))] "" "mnegf %1,%0") (define_insn "negsi2" [(set (match_operand:SI 0 "general_operand" "=g") (neg:SI (match_operand:SI 1 "general_operand" "g")))] "" "mnegl %1,%0") (define_insn "neghi2" [(set (match_operand:HI 0 "general_operand" "=g") (neg:HI (match_operand:HI 1 "general_operand" "g")))] "" "mnegw %1,%0") (define_insn "negqi2" [(set (match_operand:QI 0 "general_operand" "=g") (neg:QI (match_operand:QI 1 "general_operand" "g")))] "" "mnegb %1,%0") \f (define_insn "one_cmplsi2" [(set (match_operand:SI 0 "general_operand" "=g") (not:SI (match_operand:SI 1 "general_operand" "g")))] "" "mcoml %1,%0") (define_insn "one_cmplhi2" [(set (match_operand:HI 0 "general_operand" "=g") (not:HI (match_operand:HI 1 "general_operand" "g")))] "" "mcomw %1,%0") (define_insn "one_cmplqi2" [(set (match_operand:QI 0 "general_operand" "=g") (not:QI (match_operand:QI 1 "general_operand" "g")))] "" "mcomb %1,%0") \f ;; Arithmetic right shift on the vax works by negating the shift count. (define_expand "ashrsi3" [(set (match_operand:SI 0 "general_operand" "=g") (ashift:SI (match_operand:SI 1 "general_operand" "g") (match_operand:QI 2 "general_operand" "g")))] "" " { operands[2] = negate_rtx (QImode, operands[2]); }") (define_insn "ashlsi3" [(set (match_operand:SI 0 "general_operand" "=g") (ashift:SI (match_operand:SI 1 "general_operand" "g") (match_operand:QI 2 "general_operand" "g")))] "" "* { 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) { int i = INTVAL (operands[2]); if (i == 1) return \"addl3 %1,%1,%0\"; if (i == 2) return \"moval 0[%1],%0\"; if (i == 3) return \"movad 0[%1],%0\"; } return \"ashl %2,%1,%0\"; }") ;; Arithmetic right shift on the vax works by negating the shift count. (define_expand "ashrdi3" [(set (match_operand:DI 0 "general_operand" "=g") (ashift:DI (match_operand:DI 1 "general_operand" "g") (match_operand:QI 2 "general_operand" "g")))] "" " { operands[2] = negate_rtx (QImode, operands[2]); }") (define_insn "ashldi3" [(set (match_operand:DI 0 "general_operand" "=g") (ashift:DI (match_operand:DI 1 "general_operand" "g") (match_operand:QI 2 "general_operand" "g")))] "" "ashq %2,%1,%0") ;; Rotate right on the vax works by negating the shift count. (define_expand "rotrsi3" [(set (match_operand:SI 0 "general_operand" "=g") (rotate:SI (match_operand:SI 1 "general_operand" "g") (match_operand:QI 2 "general_operand" "g")))] "" " { operands[2] = negate_rtx (QImode, operands[2]); }") (define_insn "rotlsi3" [(set (match_operand:SI 0 "general_operand" "=g") (rotate:SI (match_operand:SI 1 "general_operand" "g") (match_operand:QI 2 "general_operand" "g")))] "" "rotl %2,%1,%0") ;This insn is probably slower than a multiply and an add. ;(define_insn "" ; [(set (match_operand:SI 0 "general_operand" "=g") ; (mult:SI (plus:SI (match_operand:SI 1 "general_operand" "g") ; (match_operand:SI 2 "general_operand" "g")) ; (match_operand:SI 3 "general_operand" "g")))] ; "" ; "index %1,$0x80000000,$0x7fffffff,%3,%2,%0") \f ;; Special cases of bit-field insns which we should ;; recognize in preference to the general case. ;; These handle aligned 8-bit and 16-bit fields, ;; which can usually be done with move instructions. (define_insn "" [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "+ro") (match_operand:SI 1 "immediate_operand" "i") (match_operand:SI 2 "immediate_operand" "i")) (match_operand:SI 3 "general_operand" "g"))] "GET_CODE (operands[1]) == CONST_INT && (INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16) && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) % INTVAL (operands[1]) == 0 && (GET_CODE (operands[0]) == REG || ! mode_dependent_address_p (XEXP (operands[0], 0)))" "* { if (REG_P (operands[0])) { if (INTVAL (operands[2]) != 0) return \"insv %3,%2,%1,%0\"; } else operands[0] = adj_offsetable_operand (operands[0], INTVAL (operands[2]) / 8); if (INTVAL (operands[1]) == 8) return \"movb %3,%0\"; return \"movw %3,%0\"; }") (define_insn "" [(set (match_operand:SI 0 "general_operand" "=&g") (zero_extract:SI (match_operand:SI 1 "general_operand" "ro") (match_operand:SI 2 "immediate_operand" "i") (match_operand:SI 3 "immediate_operand" "i")))] "GET_CODE (operands[2]) == CONST_INT && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) && GET_CODE (operands[3]) == CONST_INT && INTVAL (operands[3]) % INTVAL (operands[2]) == 0 && (GET_CODE (operands[1]) == REG || ! mode_dependent_address_p (XEXP (operands[1], 0)))" "* { if (REG_P (operands[1])) { if (INTVAL (operands[3]) != 0) return \"extzv %3,%2,%1,%0\"; } else operands[1] = adj_offsetable_operand (operands[1], INTVAL (operands[3]) / 8); if (INTVAL (operands[2]) == 8) return \"movzbl %1,%0\"; return \"movzwl %1,%0\"; }") (define_insn "" [(set (match_operand:SI 0 "general_operand" "=g") (sign_extract:SI (match_operand:SI 1 "general_operand" "ro") (match_operand:SI 2 "immediate_operand" "i") (match_operand:SI 3 "immediate_operand" "i")))] "GET_CODE (operands[2]) == CONST_INT && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) && GET_CODE (operands[3]) == CONST_INT && INTVAL (operands[3]) % INTVAL (operands[2]) == 0 && (GET_CODE (operands[1]) == REG || ! mode_dependent_address_p (XEXP (operands[1], 0)))" "* { if (REG_P (operands[1])) { if (INTVAL (operands[3]) != 0) return \"extv %3,%2,%1,%0\"; } else operands[1] = adj_offsetable_operand (operands[1], INTVAL (operands[3]) / 8); if (INTVAL (operands[2]) == 8) return \"cvtbl %1,%0\"; return \"cvtwl %1,%0\"; }") \f ;; Register-only SImode cases of bit-field insns. (define_insn "" [(set (cc0) (minus (sign_extract:SI (match_operand:SI 0 "general_operand" "r") (match_operand:SI 1 "general_operand" "g") (match_operand:SI 2 "general_operand" "g")) (match_operand:SI 3 "general_operand" "g")))] "" "cmpv %2,%1,%0,%3") (define_insn "" [(set (cc0) (minus (zero_extract:SI (match_operand:SI 0 "general_operand" "r") (match_operand:SI 1 "general_operand" "g") (match_operand:SI 2 "general_operand" "g")) (match_operand:SI 3 "general_operand" "g")))] "" "cmpzv %2,%1,%0,%3") (define_insn "" [(set (match_operand:SI 0 "general_operand" "=g") (sign_extract:SI (match_operand:SI 1 "general_operand" "r") (match_operand:SI 2 "general_operand" "g") (match_operand:SI 3 "general_operand" "g")))] "" "extv %3,%2,%1,%0") (define_insn "" [(set (match_operand:SI 0 "general_operand" "=g") (zero_extract:SI (match_operand:SI 1 "general_operand" "r") (match_operand:SI 2 "general_operand" "g") (match_operand:SI 3 "general_operand" "g")))] "" "extzv %3,%2,%1,%0") ;; Non-register cases. ;; nonimmediate_operand is used to make sure that mode-ambiguous cases ;; don't match these (and therefore match the cases above instead). (define_insn "" [(set (cc0) (minus (sign_extract:SI (match_operand:QI 0 "nonimmediate_operand" "rm") (match_operand:SI 1 "general_operand" "g") (match_operand:SI 2 "general_operand" "g")) (match_operand:SI 3 "general_operand" "g")))] "" "cmpv %2,%1,%0,%3") (define_insn "" [(set (cc0) (minus (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "rm") (match_operand:SI 1 "general_operand" "g") (match_operand:SI 2 "general_operand" "g")) (match_operand:SI 3 "general_operand" "g")))] "" "cmpzv %2,%1,%0,%3") (define_insn "extv" [(set (match_operand:SI 0 "general_operand" "=g") (sign_extract:SI (match_operand:QI 1 "nonimmediate_operand" "rm") (match_operand:SI 2 "general_operand" "g") (match_operand:SI 3 "general_operand" "g")))] "" "extv %3,%2,%1,%0") (define_insn "extzv" [(set (match_operand:SI 0 "general_operand" "=g") (zero_extract:SI (match_operand:QI 1 "nonimmediate_operand" "rm") (match_operand:SI 2 "general_operand" "g") (match_operand:SI 3 "general_operand" "g")))] "" "extzv %3,%2,%1,%0") (define_insn "insv" [(set (zero_extract:SI (match_operand:QI 0 "general_operand" "+g") (match_operand:SI 1 "general_operand" "g") (match_operand:SI 2 "general_operand" "g")) (match_operand:SI 3 "general_operand" "g"))] "" "insv %3,%2,%1,%0") (define_insn "" [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") (match_operand:SI 1 "general_operand" "g") (match_operand:SI 2 "general_operand" "g")) (match_operand:SI 3 "general_operand" "g"))] "" "insv %3,%2,%1,%0") \f (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") (define_insn "ble" [(set (pc) (if_then_else (le (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") \f (define_insn "" [(set (pc) (if_then_else (eq (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "jneq %l0") (define_insn "" [(set (pc) (if_then_else (ne (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "jeql %l0") (define_insn "" [(set (pc) (if_then_else (gt (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "jleq %l0") (define_insn "" [(set (pc) (if_then_else (gtu (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "jlequ %l0") (define_insn "" [(set (pc) (if_then_else (lt (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "jgeq %l0") (define_insn "" [(set (pc) (if_then_else (ltu (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "jgequ %l0") (define_insn "" [(set (pc) (if_then_else (ge (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "jlss %l0") (define_insn "" [(set (pc) (if_then_else (geu (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "jlssu %l0") (define_insn "" [(set (pc) (if_then_else (le (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "jgtr %l0") (define_insn "" [(set (pc) (if_then_else (leu (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "jgtru %l0") \f ;; Recognize jlbs and jlbc insns. ;; These come before the jbc and jbs recognizers so these will be preferred. (define_insn "" [(set (pc) (if_then_else (ne (and:SI (match_operand:SI 0 "general_operand" "g") (const_int 1)) (const_int 0)) (label_ref (match_operand 1 "" "")) (pc)))] "GET_CODE (operands[0]) != MEM || ! mode_dependent_address_p (XEXP (operands[0], 0))" "jlbs %0,%l1") (define_insn "" [(set (pc) (if_then_else (eq (and:SI (match_operand:SI 0 "general_operand" "g") (const_int 1)) (const_int 0)) (label_ref (match_operand 1 "" "")) (pc)))] "GET_CODE (operands[0]) != MEM || ! mode_dependent_address_p (XEXP (operands[0], 0))" "jlbc %0,%l1") (define_insn "" [(set (pc) (if_then_else (ne (and:SI (match_operand:SI 0 "general_operand" "g") (const_int 1)) (const_int 0)) (pc) (label_ref (match_operand 1 "" ""))))] "GET_CODE (operands[0]) != MEM || ! mode_dependent_address_p (XEXP (operands[0], 0))" "jlbc %0,%l1") (define_insn "" [(set (pc) (if_then_else (eq (and:SI (match_operand:SI 0 "general_operand" "g") (const_int 1)) (const_int 0)) (pc) (label_ref (match_operand 1 "" ""))))] "GET_CODE (operands[0]) != MEM || ! mode_dependent_address_p (XEXP (operands[0], 0))" "jlbs %0,%l1") ;; These four entries allow a jlbc or jlbs to be made ;; by combination with a bic. (define_insn "" [(set (pc) (if_then_else (ne (and:SI (match_operand:SI 0 "general_operand" "g") (not:SI (const_int -2))) (const_int 0)) (label_ref (match_operand 1 "" "")) (pc)))] "GET_CODE (operands[0]) != MEM || ! mode_dependent_address_p (XEXP (operands[0], 0))" "jlbs %0,%l1") (define_insn "" [(set (pc) (if_then_else (eq (and:SI (match_operand:SI 0 "general_operand" "g") (not:SI (const_int -2))) (const_int 0)) (label_ref (match_operand 1 "" "")) (pc)))] "GET_CODE (operands[0]) != MEM || ! mode_dependent_address_p (XEXP (operands[0], 0))" "jlbc %0,%l1") (define_insn "" [(set (pc) (if_then_else (ne (and:SI (match_operand:SI 0 "general_operand" "g") (not:SI (const_int -2))) (const_int 0)) (pc) (label_ref (match_operand 1 "" ""))))] "GET_CODE (operands[0]) != MEM || ! mode_dependent_address_p (XEXP (operands[0], 0))" "jlbc %0,%l1") (define_insn "" [(set (pc) (if_then_else (eq (and:SI (match_operand:SI 0 "general_operand" "g") (not:SI (const_int -2))) (const_int 0)) (pc) (label_ref (match_operand 1 "" ""))))] "GET_CODE (operands[0]) != MEM || ! mode_dependent_address_p (XEXP (operands[0], 0))" "jlbs %0,%l1") \f ;; Recognize jbs and jbc instructions. (define_insn "" [(set (pc) (if_then_else (ne (sign_extract:SI (match_operand:QI 0 "general_operand" "g") (const_int 1) (match_operand:SI 1 "general_operand" "g")) (const_int 0)) (label_ref (match_operand 2 "" "")) (pc)))] "" "jbs %1,%0,%l2") (define_insn "" [(set (pc) (if_then_else (eq (sign_extract:SI (match_operand:QI 0 "general_operand" "g") (const_int 1) (match_operand:SI 1 "general_operand" "g")) (const_int 0)) (label_ref (match_operand 2 "" "")) (pc)))] "" "jbc %1,%0,%l2") (define_insn "" [(set (pc) (if_then_else (ne (sign_extract:SI (match_operand:QI 0 "general_operand" "g") (const_int 1) (match_operand:SI 1 "general_operand" "g")) (const_int 0)) (pc) (label_ref (match_operand 2 "" ""))))] "" "jbc %1,%0,%l2") (define_insn "" [(set (pc) (if_then_else (eq (sign_extract:SI (match_operand:QI 0 "general_operand" "g") (const_int 1) (match_operand:SI 1 "general_operand" "g")) (const_int 0)) (pc) (label_ref (match_operand 2 "" ""))))] "" "jbs %1,%0,%l2") (define_insn "" [(set (pc) (if_then_else (ne (sign_extract:SI (match_operand:SI 0 "general_operand" "r") (const_int 1) (match_operand:SI 1 "general_operand" "g")) (const_int 0)) (label_ref (match_operand 2 "" "")) (pc)))] "GET_CODE (operands[0]) != MEM || ! mode_dependent_address_p (XEXP (operands[0], 0))" "jbs %1,%0,%l2") (define_insn "" [(set (pc) (if_then_else (eq (sign_extract:SI (match_operand:SI 0 "general_operand" "r") (const_int 1) (match_operand:SI 1 "general_operand" "g")) (const_int 0)) (label_ref (match_operand 2 "" "")) (pc)))] "GET_CODE (operands[0]) != MEM || ! mode_dependent_address_p (XEXP (operands[0], 0))" "jbc %1,%0,%l2") (define_insn "" [(set (pc) (if_then_else (eq (and:SI (match_operand:SI 0 "general_operand" "g") (match_operand:SI 1 "general_operand" "g")) (const_int 0)) (pc) (label_ref (match_operand 2 "" ""))))] "GET_CODE (operands[1]) == CONST_INT && exact_log2 (INTVAL (operands[1])) >= 0 && (GET_CODE (operands[0]) != MEM || ! mode_dependent_address_p (XEXP (operands[0], 0)))" "* { operands[1] = gen_rtx (CONST_INT, VOIDmode, exact_log2 (INTVAL (operands[1]))); return \"jbs %1,%0,%l2\"; }") (define_insn "" [(set (pc) (if_then_else (eq (and:SI (match_operand:SI 0 "general_operand" "g") (match_operand:SI 1 "general_operand" "g")) (const_int 0)) (label_ref (match_operand 2 "" "")) (pc)))] "GET_CODE (operands[1]) == CONST_INT && exact_log2 (INTVAL (operands[1])) >= 0 && (GET_CODE (operands[0]) != MEM || ! mode_dependent_address_p (XEXP (operands[0], 0)))" "* { operands[1] = gen_rtx (CONST_INT, VOIDmode, exact_log2 (INTVAL (operands[1]))); return \"jbc %1,%0,%l2\"; }") (define_insn "" [(set (pc) (if_then_else (ne (and:SI (match_operand:SI 0 "general_operand" "g") (match_operand:SI 1 "general_operand" "g")) (const_int 0)) (pc) (label_ref (match_operand 2 "" ""))))] "GET_CODE (operands[1]) == CONST_INT && exact_log2 (INTVAL (operands[1])) >= 0 && (GET_CODE (operands[0]) != MEM || ! mode_dependent_address_p (XEXP (operands[0], 0)))" "* { operands[1] = gen_rtx (CONST_INT, VOIDmode, exact_log2 (INTVAL (operands[1]))); return \"jbc %1,%0,%l2\"; }") (define_insn "" [(set (pc) (if_then_else (ne (and:SI (match_operand:SI 0 "general_operand" "g") (match_operand:SI 1 "general_operand" "g")) (const_int 0)) (label_ref (match_operand 2 "" "")) (pc)))] "GET_CODE (operands[1]) == CONST_INT && exact_log2 (INTVAL (operands[1])) >= 0 && (GET_CODE (operands[0]) != MEM || ! mode_dependent_address_p (XEXP (operands[0], 0)))" "* { operands[1] = gen_rtx (CONST_INT, VOIDmode, exact_log2 (INTVAL (operands[1]))); return \"jbs %1,%0,%l2\"; }") (define_insn "" [(set (pc) (if_then_else (ne (sign_extract:SI (match_operand:SI 0 "general_operand" "r") (const_int 1) (match_operand:SI 1 "general_operand" "g")) (const_int 0)) (pc) (label_ref (match_operand 2 "" ""))))] "GET_CODE (operands[0]) != MEM || ! mode_dependent_address_p (XEXP (operands[0], 0))" "jbc %1,%0,%l2") (define_insn "" [(set (pc) (if_then_else (eq (sign_extract:SI (match_operand:SI 0 "general_operand" "r") (const_int 1) (match_operand:SI 1 "general_operand" "g")) (const_int 0)) (pc) (label_ref (match_operand 2 "" ""))))] "GET_CODE (operands[0]) != MEM || ! mode_dependent_address_p (XEXP (operands[0], 0))" "jbs %1,%0,%l2") \f ;; Subtract-and-jump and Add-and-jump insns. ;; These are not used when output is for the Unix assembler ;; because it does not know how to modify them to reach far. ;; Normal sob insns. (define_insn "" [(set (pc) (if_then_else (gt (plus:SI (match_operand:SI 0 "general_operand" "+g") (const_int -1)) (const_int 0)) (label_ref (match_operand 1 "" "")) (pc))) (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))] "!TARGET_UNIX_ASM" "jsobgtr %0,%l1") (define_insn "" [(set (pc) (if_then_else (ge (plus:SI (match_operand:SI 0 "general_operand" "+g") (const_int -1)) (const_int 0)) (label_ref (match_operand 1 "" "")) (pc))) (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))] "!TARGET_UNIX_ASM" "jsobgeq %0,%l1") ;; Reversed sob insns. (define_insn "" [(set (pc) (if_then_else (le (plus:SI (match_operand:SI 0 "general_operand" "+g") (const_int -1)) (const_int 0)) (pc) (label_ref (match_operand 1 "" "")))) (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))] "!TARGET_UNIX_ASM" "jsobgtr %0,%l1") (define_insn "" [(set (pc) (if_then_else (lt (plus:SI (match_operand:SI 0 "general_operand" "+g") (const_int -1)) (const_int 0)) (pc) (label_ref (match_operand 1 "" "")))) (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))] "!TARGET_UNIX_ASM" "jsobgeq %0,%l1") ;; Normal aob insns. (define_insn "" [(set (pc) (if_then_else (lt (compare (plus:SI (match_operand:SI 0 "general_operand" "+g") (const_int 1)) (match_operand:SI 1 "general_operand" "g")) (const_int 0)) (label_ref (match_operand 2 "" "")) (pc))) (set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))] "!TARGET_UNIX_ASM" "jaoblss %1,%0,%l2") (define_insn "" [(set (pc) (if_then_else (le (compare (plus:SI (match_operand:SI 0 "general_operand" "+g") (const_int 1)) (match_operand:SI 1 "general_operand" "g")) (const_int 0)) (label_ref (match_operand 2 "" "")) (pc))) (set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))] "!TARGET_UNIX_ASM" "jaobleq %1,%0,%l2") ;; Reverse aob insns. (define_insn "" [(set (pc) (if_then_else (ge (compare (plus:SI (match_operand:SI 0 "general_operand" "+g") (const_int 1)) (match_operand:SI 1 "general_operand" "g")) (const_int 0)) (pc) (label_ref (match_operand 2 "" "")))) (set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))] "!TARGET_UNIX_ASM" "jaoblss %1,%0,%l2") (define_insn "" [(set (pc) (if_then_else (gt (compare (plus:SI (match_operand:SI 0 "general_operand" "+g") (const_int 1)) (match_operand:SI 1 "general_operand" "g")) (const_int 0)) (pc) (label_ref (match_operand 2 "" "")))) (set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))] "!TARGET_UNIX_ASM" "jaobleq %1,%0,%l2") ;; Something like a sob insn, but compares against -1. ;; This finds `while (foo--)' which was changed to `while (--foo != -1)'. (define_insn "" [(set (pc) (if_then_else (ne (compare (plus:SI (match_operand:SI 0 "general_operand" "g") (const_int -1)) (const_int -1)) (const_int 0)) (label_ref (match_operand 1 "" "")) (pc))) (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))] "" "decl %0\;jgequ %l1") \f ;; Note that operand 1 is total size of args, in bytes, ;; and what the call insn wants is the number of words. (define_insn "call" [(call (match_operand:QI 0 "general_operand" "g") (match_operand:QI 1 "general_operand" "g"))] "" "* if (INTVAL (operands[1]) > 255 * 4) /* Vax `calls' really uses only one byte of #args, so pop explicitly. */ return \"calls $0,%0\;addl2 %1,sp\"; operands[1] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[1]) + 3)/ 4); return \"calls %1,%0\"; ") (define_insn "call_value" [(set (match_operand 0 "" "g") (call (match_operand:QI 1 "general_operand" "g") (match_operand:QI 2 "general_operand" "g")))] "" "* if (INTVAL (operands[2]) > 255 * 4) /* Vax `calls' really uses only one byte of #args, so pop explicitly. */ return \"calls $0,%1\;addl2 %2,sp\"; operands[2] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[2]) + 3)/ 4); return \"calls %2,%1\"; ") (define_insn "return" [(return)] "" "ret") (define_insn "casesi" [(set (pc) (if_then_else (le (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 (pc) (minus:SI (match_dup 0) (match_dup 1))))) (label_ref:SI (match_operand 3 "" ""))) (pc)))] "" "casel %0,%1,%2") ;; This used to arise from the preceding by simplification ;; if operand 1 is zero. Perhaps it is no longer necessary. (define_insn "" [(set (pc) (if_then_else (le (match_operand:SI 0 "general_operand" "g") (match_operand:SI 1 "general_operand" "g")) (plus:SI (sign_extend:SI (mem:HI (plus:SI (pc) (minus:SI (match_dup 0) (const_int 0))))) (label_ref:SI (match_operand 3 "" ""))) (pc)))] "" "casel %0,$0,%1") ;; This arises from the preceding by simplification if operand 1 is zero. (define_insn "" [(set (pc) (if_then_else (le (match_operand:SI 0 "general_operand" "g") (match_operand:SI 1 "general_operand" "g")) (plus:SI (sign_extend:SI (mem:HI (plus:SI (pc) (match_dup 0)))) (label_ref:SI (match_operand 3 "" ""))) (pc)))] "" "casel %0,$0,%1") \f ;;- 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. (define_insn "" [(set (match_operand:SI 0 "general_operand" "=g") (match_operand:QI 1 "address_operand" "p"))] "" "* { if (push_operand (operands[0], SImode)) return \"pushab %a1\"; return \"movab %a1,%0\"; }") (define_insn "" [(set (match_operand:SI 0 "general_operand" "=g") (match_operand:HI 1 "address_operand" "p"))] "" "* { if (push_operand (operands[0], SImode)) return \"pushaw %a1\"; return \"movaw %a1,%0\"; }") (define_insn "" [(set (match_operand:SI 0 "general_operand" "=g") (match_operand:SI 1 "address_operand" "p"))] "" "* { if (push_operand (operands[0], SImode)) return \"pushal %a1\"; return \"moval %a1,%0\"; }") (define_insn "" [(set (match_operand:SI 0 "general_operand" "=g") (match_operand:SF 1 "address_operand" "p"))] "" "* { if (push_operand (operands[0], SImode)) return \"pushaf %a1\"; return \"movaf %a1,%0\"; }") (define_insn "" [(set (match_operand:SI 0 "general_operand" "=g") (match_operand:DF 1 "address_operand" "p"))] "" "* { if (push_operand (operands[0], SImode)) return \"pushad %a1\"; return \"movad %a1,%0\"; }") \f ;; Optimize extzv ...,z; andl2 ...,z ;; with other operands constant. (define_peephole [(set (match_operand:SI 0 "general_operand" "g") (zero_extract:SI (match_operand:SI 1 "general_operand" "g") (match_operand:SI 2 "general_operand" "g") (match_operand:SI 3 "general_operand" "g"))) (set (match_operand:SI 4 "general_operand" "g") (and:SI (match_dup 0) (match_operand:SI 5 "general_operand" "g")))] "GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT && (INTVAL (operands[2]) + INTVAL (operands[3])) == 32 && GET_CODE (operands[5]) == CONST_INT && dead_or_set_p (insn, operands[0])" "* { unsigned long mask = INTVAL (operands[5]); operands[3] = gen_rtx (CONST_INT, VOIDmode, -INTVAL (operands[3])); if ((floor_log2 (mask) + 1) >= INTVAL (operands[2])) mask &= ((1 << INTVAL (operands[2])) - 1); operands[5] = gen_rtx (CONST_INT, VOIDmode, ~mask); if (push_operand (operands[4], SImode)) { output_asm_insn (\"rotl %3,%1,%0\", operands); return \"bicl3 %5,%0,%4\"; } else { output_asm_insn (\"rotl %3,%1,%4\", operands); return \"bicl2 %5,%4\"; } }") ;; Optimize andl3 x,y,z; extzv z,....,z (define_peephole [(set (match_operand:SI 0 "general_operand" "g") (and:SI (match_operand:SI 1 "general_operand" "g") (match_operand:SI 2 "general_operand" "g"))) (set (match_operand 3 "general_operand" "g") (zero_extract:SI (match_dup 0) (match_operand:SI 4 "general_operand" "g") (match_operand:SI 5 "general_operand" "g")))] "GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[4]) == CONST_INT && GET_CODE (operands[5]) == CONST_INT && (INTVAL (operands[4]) + INTVAL (operands[5])) == 32 && dead_or_set_p (insn, operands[0])" "* { unsigned long mask = INTVAL (operands[2]); mask &= ~((1 << INTVAL (operands[5])) - 1); operands[2] = gen_rtx (CONST_INT, VOIDmode, ~mask); operands[5] = gen_rtx (CONST_INT, VOIDmode, -INTVAL (operands[5])); if (rtx_equal_p (operands[0], operands[1])) output_asm_insn (\"bicl2 %2,%0\", operands); else output_asm_insn (\"bicl3 %2,%1,%0\", operands); return \"rotl %5,%0,%3\"; }") \f ;;- Local variables: ;;- mode:emacs-lisp ;;- comment-start: ";;- " ;;- eval: (set-syntax-table (copy-sequence (syntax-table))) ;;- eval: (modify-syntax-entry ?[ "(]") ;;- eval: (modify-syntax-entry ?] ")[") ;;- eval: (modify-syntax-entry ?{ "(}") ;;- eval: (modify-syntax-entry ?} "){") ;;- End: