📄 vax.md
字号:
;; Machine description for GNU compiler, VAX Version;; Copyright (C) 1987, 1988, 1991, 1994, 1995, 1996, 1998, 1999, 2000, 2001,;; 2002 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 2, or (at your option);; any later version.;; GNU CC is distributed in the hope that it will be useful,;; but WITHOUT ANY WARRANTY; without even the implied warranty of;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the;; GNU General Public License for more details.;; You should have received a copy of the GNU General Public License;; along with GNU CC; see the file COPYING. If not, write to;; the Free Software Foundation, 59 Temple Place - Suite 330,;; Boston, MA 02111-1307, USA.;;- 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.;; UNSPEC_VOLATILE usage:(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 ]);; 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 "tstsi" [(set (cc0) (match_operand:SI 0 "nonimmediate_operand" "g"))] "" "tstl %0")(define_insn "tsthi" [(set (cc0) (match_operand:HI 0 "nonimmediate_operand" "g"))] "" "tstw %0")(define_insn "tstqi" [(set (cc0) (match_operand:QI 0 "nonimmediate_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 "nonimmediate_operand" "g") (match_operand:SI 1 "general_operand" "g")))] "" "cmpl %0,%1")(define_insn "cmphi" [(set (cc0) (compare (match_operand:HI 0 "nonimmediate_operand" "g") (match_operand:HI 1 "general_operand" "g")))] "" "cmpw %0,%1")(define_insn "cmpqi" [(set (cc0) (compare (match_operand:QI 0 "nonimmediate_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,gF") (match_operand:DF 1 "general_operand" "G,gF")))] "" "@ tst%# %0 cmp%# %0,%1")(define_insn "cmpsf" [(set (cc0) (compare (match_operand:SF 0 "general_operand" "gF,gF") (match_operand:SF 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")(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");; 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,;; to do this properly requires a complete rewrite of the compare insns;; to keep them together with the sltu/sgeu insns until after the;; reload pass is complete. The previous implementation didn't do this;; 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"))] "" "@ clrf %0 movf %1,%0");; Some VAXen 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 "nonimmediate_operand" "=g,g") (match_operand:DI 1 "general_operand" "I,g"))] "" "@ clrq %0 movq %D1,%0");; The VAX move instructions have space-time tradeoffs. On a MicroVAX;; register-register mov instructions take 3 bytes and 2 CPU cycles. clrl;; takes 2 bytes and 3 cycles. mov from constant to register takes 2 cycles;; if the constant is smaller than 4 bytes, 3 cycles for a longword;; constant. movz, mneg, and mcom are as fast as mov, so movzwl is faster;; than movl for positive constants that fit in 16 bits but not 6 bits. cvt;; instructions take 4 cycles. inc takes 3 cycles. The machine description;; is willing to trade 1 byte for 1 cycle (clrl instead of movl $0; cvtwl;; instead of movl).;; Cycle counts for other models may vary (on a VAX 750 they are similar,;; but on a VAX 9000 most move and add instructions with one constant;; operand take 1 cycle).;; 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"))] "" "*{ 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\";}")(define_insn "movstricthi" [(set (strict_low_part (match_operand:HI 0 "register_operand" "+g")) (match_operand:HI 1 "general_operand" "g"))] "" "*{ 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\";}")(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) { 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\";}");; 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" [(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])); DONE;");; 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 "movstrhi1" [(set (match_operand:BLK 0 "memory_operand" "=m") (match_operand:BLK 1 "memory_operand" "m")) (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");; Extension and truncation insns.(define_insn "truncsiqi2" [(set (match_operand:QI 0 "nonimmediate_operand" "=g") (truncate:QI (match_operand:SI 1 "nonimmediate_operand" "g")))] "" "cvtlb %1,%0")(define_insn "truncsihi2" [(set (match_operand:HI 0 "nonimmediate_operand" "=g") (truncate:HI (match_operand:SI 1 "nonimmediate_operand" "g")))] "" "cvtlw %1,%0")(define_insn "trunchiqi2" [(set (match_operand:QI 0 "nonimmediate_operand" "=g") (truncate:QI (match_operand:HI 1 "nonimmediate_operand" "g")))] "" "cvtwb %1,%0")(define_insn "extendhisi2" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "g")))] "" "cvtwl %1,%0")(define_insn "extendqihi2" [(set (match_operand:HI 0 "nonimmediate_operand" "=g") (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "g")))] "" "cvtbw %1,%0")(define_insn "extendqisi2" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "g")))] "" "cvtbl %1,%0")(define_insn "extendsfdf2" [(set (match_operand:DF 0 "nonimmediate_operand" "=g") (float_extend:DF (match_operand:SF 1 "general_operand" "gF")))] "" "cvtf%# %1,%0")(define_insn "truncdfsf2" [(set (match_operand:SF 0 "nonimmediate_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 "nonimmediate_operand" "=g") (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "g")))] "" "movzwl %1,%0")(define_insn "zero_extendqihi2" [(set (match_operand:HI 0 "nonimmediate_operand" "=g") (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "g")))] "" "movzbw %1,%0")(define_insn "zero_extendqisi2" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "g")))] "" "movzbl %1,%0");; 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")))] "" "cvtw%# %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"))))] "" "cvt%#l %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")))] "" "@ 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]))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -