📄 vax.md
字号:
;;- Machine description for GNU compiler, Vax Version;; Copyright (C) 1987, 88, 91, 94-96, 1998 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.;; 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 sltu or sgeu patterns, but does have two-operand;; add/subtract with carry. This is still better than the alternative.;; Since the cc0-using insn cannot be separated from the cc0-setting insn,;; and the two are created independently, we can't just use a define_expand;; to try to optimize this. (The "movl" and "clrl" insns alter the cc0;; flags, but leave the carry flag alone, but that can't easily be expressed.);;;; Several two-operator combinations could be added to make slightly more;; optimal code, but they'd have to cover all combinations of plus and minus;; using match_dup. If you want to do this, I'd suggest changing the "sgeu";; pattern to something like (minus (const_int 1) (ltu ...)), so fewer;; patterns need to be recognized.;; -- Ken Raeburn (Raeburn@Watch.COM) 24 August 1991.(define_insn "sltu" [(set (match_operand:SI 0 "general_operand" "=ro") (ltu (cc0) (const_int 0)))] "" "clrl %0\;adwc $0,%0")(define_insn "sgeu" [(set (match_operand:SI 0 "general_operand" "=ro") (geu (cc0) (const_int 0)))] "" "movl $1,%0\;sbwc $0,%0")(define_insn "movdf" [(set (match_operand:DF 0 "general_operand" "=g,g") (match_operand:DF 1 "general_operand" "G,gF"))] "" "@ clr%# %0 mov%# %1,%0")(define_insn "movsf" [(set (match_operand:SF 0 "general_operand" "=g,g") (match_operand:SF 1 "general_operand" "G,gF"))] "" "@ clrf %0 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,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 "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. */ && ! INSN_DELETED_P (XEXP (link, 0)) && GET_CODE (XEXP (link, 0)) != NOTE /* Make sure cross jumping didn't happen here. */ && no_labels_between_p (XEXP (link, 0), insn) /* Make sure the reg hasn't been clobbered. */ && ! reg_set_between_p (operands[0], XEXP (link, 0), insn)) 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 "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. */ && ! INSN_DELETED_P (XEXP (link, 0)) && GET_CODE (XEXP (link, 0)) != NOTE /* Make sure cross jumping didn't happen here. */ && no_labels_between_p (XEXP (link, 0), insn) /* Make sure the reg hasn't been clobbered. */ && ! reg_set_between_p (operands[0], XEXP (link, 0), insn)) 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 "general_operand" "=g") (match_operand:QI 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. */ && ! INSN_DELETED_P (XEXP (link, 0)) && GET_CODE (XEXP (link, 0)) != NOTE /* Make sure cross jumping didn't happen here. */ && no_labels_between_p (XEXP (link, 0), insn) /* Make sure the reg hasn't been clobbered. */ && ! reg_set_between_p (operands[0], XEXP (link, 0), insn)) 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 "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");; Extension and truncation insns.(define_insn "truncsiqi2" [(set (match_operand:QI 0 "general_operand" "=g") (truncate:QI (match_operand:SI 1 "nonimmediate_operand" "g")))] "" "cvtlb %1,%0")(define_insn "truncsihi2" [(set (match_operand:HI 0 "general_operand" "=g") (truncate:HI (match_operand:SI 1 "nonimmediate_operand" "g")))] "" "cvtlw %1,%0")(define_insn "trunchiqi2" [(set (match_operand:QI 0 "general_operand" "=g") (truncate:QI (match_operand:HI 1 "nonimmediate_operand" "g")))] "" "cvtwb %1,%0")(define_insn "extendhisi2" [(set (match_operand:SI 0 "general_operand" "=g") (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "g")))] "" "cvtwl %1,%0")(define_insn "extendqihi2" [(set (match_operand:HI 0 "general_operand" "=g") (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "g")))] "" "cvtbw %1,%0")(define_insn "extendqisi2" [(set (match_operand:SI 0 "general_operand" "=g") (sign_extend:SI (match_operand:QI 1 "nonimmediate_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 "nonimmediate_operand" "g")))] "" "movzwl %1,%0")(define_insn "zero_extendqihi2" [(set (match_operand:HI 0 "general_operand" "=g") (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "g")))] "" "movzbw %1,%0")(define_insn "zero_extendqisi2" [(set (match_operand:SI 0 "general_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 "general_operand" "=g") (float:SF (match_operand:SI 1 "nonimmediate_operand" "g")))] "" "cvtlf %1,%0")(define_insn "floatsidf2" [(set (match_operand:DF 0 "general_operand" "=g") (float:DF (match_operand:SI 1 "nonimmediate_operand" "g")))] "" "cvtl%# %1,%0")(define_insn "floathisf2" [(set (match_operand:SF 0 "general_operand" "=g") (float:SF (match_operand:HI 1 "nonimmediate_operand" "g")))] "" "cvtwf %1,%0")(define_insn "floathidf2" [(set (match_operand:DF 0 "general_operand" "=g") (float:DF (match_operand:HI 1 "nonimmediate_operand" "g")))] "" "cvtw%# %1,%0")(define_insn "floatqisf2" [(set (match_operand:SF 0 "general_operand" "=g") (float:SF (match_operand:QI 1 "nonimmediate_operand" "g")))] "" "cvtbf %1,%0")(define_insn "floatqidf2" [(set (match_operand:DF 0 "general_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 "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");;- All kinds of add instructions.(define_insn "adddf3" [(set (match_operand:DF 0 "general_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 "general_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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -