📄 vax.md
字号:
;; Machine description for GNU compiler, VAX Version;; Copyright (C) 1987, 1988, 1991, 1994, 1995, 1996, 1998, 1999, 2000, 2001,;; 2002, 2004, 2005 Free Software Foundation, Inc.;; This file is part of GCC.;; 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);; any later version.;; 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 GCC; see the file COPYING. If not, write to;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,;; Boston, MA 02110-1301, 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 (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 ]);; Integer modes supported on VAX, with a mapping from machine mode;; to mnemonic suffix. DImode is always a special case.(define_mode_macro VAXint [QI HI SI])(define_mode_attr isfx [(QI "b") (HI "w") (SI "l")]);; Similar for float modes supported on VAX.(define_mode_macro VAXfp [SF DF])(define_mode_attr fsfx [(SF "f") (DF "%#")]);; Some output patterns want integer immediates with a prefix...(define_mode_attr iprefx [(QI "B") (HI "H") (SI "N")]);; 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 "tst<mode>" [(set (cc0) (match_operand:VAXint 0 "nonimmediate_operand" "g"))] "" "tst<VAXint:isfx> %0")(define_insn "tst<mode>" [(set (cc0) (match_operand:VAXfp 0 "general_operand" "gF"))] "" "tst<VAXfp:fsfx> %0")(define_insn "cmp<mode>" [(set (cc0) (compare (match_operand:VAXint 0 "nonimmediate_operand" "g") (match_operand:VAXint 1 "general_operand" "g")))] "" "cmp<VAXint:isfx> %0,%1")(define_insn "cmp<mode>" [(set (cc0) (compare (match_operand:VAXfp 0 "general_operand" "gF,gF") (match_operand:VAXfp 1 "general_operand" "G,gF")))] "" "@ tst<VAXfp:fsfx> %0 cmp<VAXfp:fsfx> %0,%1")(define_insn "*bit<mode>" [(set (cc0) (and:VAXint (match_operand:VAXint 0 "general_operand" "g") (match_operand:VAXint 1 "general_operand" "g")))] "" "bit<VAXint:isfx> %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 "mov<mode>" [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g") (match_operand:VAXfp 1 "general_operand" "G,gF"))] "" "@ clr<VAXfp:fsfx> %0 mov<VAXfp:fsfx> %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 "mov<mode>" [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g") (match_operand:VAXint 1 "general_operand" "g"))] "" "* return vax_output_int_move (insn, operands, <MODE>mode);")(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 "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 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_movmemhi1 (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 "movmemhi1" [(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 "float<VAXint:mode><VAXfp:mode>2" [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g") (float:VAXfp (match_operand:VAXint 1 "nonimmediate_operand" "g")))] "" "cvt<VAXint:isfx><VAXfp:fsfx> %1,%0");; Float-to-fix conversion insns.(define_insn "fix_trunc<VAXfp:mode><VAXint:mode>2" [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g") (fix:VAXint (fix:VAXfp (match_operand:VAXfp 1 "general_operand" "gF"))))] "" "cvt<VAXfp:fsfx><VAXint:isfx> %1,%0");;- All kinds of add instructions.(define_insn "add<mode>3" [(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<VAXfp:fsfx>2 %2,%0 add<VAXfp:fsfx>2 %1,%0 add<VAXfp:fsfx>3 %1,%2,%0")(define_insn "add<mode>3" [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g") (plus:VAXint (match_operand:VAXint 1 "general_operand" "g") (match_operand:VAXint 2 "general_operand" "g")))] "" "* return vax_output_int_add (insn, operands, <MODE>mode);");; The add-with-carry (adwc) instruction only accepts two operands.(define_insn "adddi3" [(set (match_operand:DI 0 "nonimmediate_operand" "=ro>,ro>") (plus:DI (match_operand:DI 1 "general_operand" "%0,ro>") (match_operand:DI 2 "general_operand" "Fro,F")))] "" "*{ rtx low[3]; const char *pattern; int carry = 1; split_quadword_operands (operands, low, 3); /* Add low parts. */ if (rtx_equal_p (operands[0], operands[1])) { if (low[2] == const0_rtx) /* Should examine operand, punt if not POST_INC. */ pattern = \"tstl %0\", carry = 0; else if (low[2] == const1_rtx) pattern = \"incl %0\"; else pattern = \"addl2 %2,%0\"; } else { if (low[2] == const0_rtx) pattern = \"movl %1,%0\", carry = 0; else pattern = \"addl3 %2,%1,%0\"; } if (pattern) output_asm_insn (pattern, low); if (!carry) /* If CARRY is 0, we don't have any carry value to worry about. */ return get_insn_template (CODE_FOR_addsi3, insn); /* %0 = C + %1 + %2 */ if (!rtx_equal_p (operands[0], operands[1])) output_asm_insn ((operands[1] == const0_rtx ? \"clrl %0\" : \"movl %1,%0\"), operands); return \"adwc %2,%0\";}");;- All kinds of subtract instructions.(define_insn "sub<mode>3" [(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")))] "" "@ sub<VAXfp:fsfx>2 %2,%0 sub<VAXfp:fsfx>3 %2,%1,%0")(define_insn "sub<mode>3" [(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")))] "" "@ sub<VAXint:isfx>2 %2,%0 sub<VAXint:isfx>3 %2,%1,%0");; The subtract-with-carry (sbwc) instruction only takes two operands.(define_insn "subdi3" [(set (match_operand:DI 0 "nonimmediate_operand" "=or>,or>") (minus:DI (match_operand:DI 1 "general_operand" "0,or>") (match_operand:DI 2 "general_operand" "For,F")))] ""
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -