📄 vax.md
字号:
"*{ rtx low[3]; const char *pattern; int carry = 1; split_quadword_operands (operands, low, 3); /* Subtract low parts. */ if (rtx_equal_p (operands[0], operands[1])) { if (low[2] == const0_rtx) pattern = 0, carry = 0; else if (low[2] == constm1_rtx) pattern = \"decl %0\"; else pattern = \"subl2 %2,%0\"; } else { if (low[2] == constm1_rtx) pattern = \"decl %0\"; else if (low[2] == const0_rtx) pattern = get_insn_template (CODE_FOR_movsi, insn), carry = 0; else pattern = \"subl3 %2,%1,%0\"; } if (pattern) output_asm_insn (pattern, low); if (carry) { if (!rtx_equal_p (operands[0], operands[1])) return \"movl %1,%0\;sbwc %2,%0\"; return \"sbwc %2,%0\"; /* %0 = %2 - %1 - C */ } return get_insn_template (CODE_FOR_subsi3, insn);}");;- Multiply instructions.(define_insn "mul<mode>3" [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g,g") (mult:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF,gF") (match_operand:VAXfp 2 "general_operand" "gF,0,gF")))] "" "@ mul<VAXfp:fsfx>2 %2,%0 mul<VAXfp:fsfx>2 %1,%0 mul<VAXfp:fsfx>3 %1,%2,%0")(define_insn "mul<mode>3" [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g") (mult:VAXint (match_operand:VAXint 1 "general_operand" "0,g,g") (match_operand:VAXint 2 "general_operand" "g,0,g")))] "" "@ mul<VAXint:isfx>2 %2,%0 mul<VAXint:isfx>2 %1,%0 mul<VAXint:isfx>3 %1,%2,%0")(define_insn "mulsidi3" [(set (match_operand:DI 0 "nonimmediate_operand" "=g") (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "g")) (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "g"))))] "" "emul %1,%2,$0,%0")(define_insn "" [(set (match_operand:DI 0 "nonimmediate_operand" "=g") (plus:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "g")) (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "g"))) (sign_extend:DI (match_operand:SI 3 "nonimmediate_operand" "g"))))] "" "emul %1,%2,%3,%0");; 'F' constraint means type CONST_DOUBLE(define_insn "" [(set (match_operand:DI 0 "nonimmediate_operand" "=g") (plus:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "g")) (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "g"))) (match_operand:DI 3 "immediate_operand" "F")))] "GET_CODE (operands[3]) == CONST_DOUBLE && CONST_DOUBLE_HIGH (operands[3]) == (CONST_DOUBLE_LOW (operands[3]) >> 31)" "*{ if (CONST_DOUBLE_HIGH (operands[3])) operands[3] = GEN_INT (CONST_DOUBLE_LOW (operands[3])); return \"emul %1,%2,%3,%0\";}");;- Divide instructions.(define_insn "div<mode>3" [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g") (div:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF") (match_operand:VAXfp 2 "general_operand" "gF,gF")))] "" "@ div<VAXfp:fsfx>2 %2,%0 div<VAXfp:fsfx>3 %2,%1,%0")(define_insn "div<mode>3" [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g") (div:VAXint (match_operand:VAXint 1 "general_operand" "0,g") (match_operand:VAXint 2 "general_operand" "g,g")))] "" "@ div<VAXint:isfx>2 %2,%0 div<VAXint:isfx>3 %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");; Bit-and on the VAX is done with a clear-bits insn.(define_expand "and<mode>3" [(set (match_operand:VAXint 0 "nonimmediate_operand" "") (and:VAXint (not:VAXint (match_operand:VAXint 1 "general_operand" "")) (match_operand:VAXint 2 "general_operand" "")))] "" "{ rtx op1 = operands[1]; /* If there is a constant argument, complement that one. */ if (GET_CODE (operands[2]) == CONST_INT && GET_CODE (op1) != CONST_INT) { operands[1] = operands[2]; operands[2] = op1; op1 = operands[1]; } if (GET_CODE (op1) == CONST_INT) operands[1] = GEN_INT (~INTVAL (op1)); else operands[1] = expand_unop (<MODE>mode, one_cmpl_optab, op1, 0, 1);}")(define_insn "*and<mode>" [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g") (and:VAXint (not:VAXint (match_operand:VAXint 1 "general_operand" "g,g")) (match_operand:VAXint 2 "general_operand" "0,g")))] "" "@ bic<VAXint:isfx>2 %1,%0 bic<VAXint:isfx>3 %1,%2,%0");; The following used to be needed because constant propagation can;; create them starting from the bic insn patterns above. This is no;; longer a problem. However, having these patterns allows optimization;; opportunities in combine.c.(define_insn "*and<mode>_const_int" [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g") (and:VAXint (match_operand:VAXint 1 "general_operand" "0,g") (match_operand:VAXint 2 "const_int_operand" "n,n")))] "" "@ bic<VAXint:isfx>2 %<VAXint:iprefx>2,%0 bic<VAXint:isfx>3 %<VAXint:iprefx>2,%1,%0");;- Bit set instructions.(define_insn "ior<mode>3" [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g") (ior:VAXint (match_operand:VAXint 1 "general_operand" "0,g,g") (match_operand:VAXint 2 "general_operand" "g,0,g")))] "" "@ bis<VAXint:isfx>2 %2,%0 bis<VAXint:isfx>2 %1,%0 bis<VAXint:isfx>3 %2,%1,%0");;- xor instructions.(define_insn "xor<mode>3" [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g") (xor:VAXint (match_operand:VAXint 1 "general_operand" "0,g,g") (match_operand:VAXint 2 "general_operand" "g,0,g")))] "" "@ xor<VAXint:isfx>2 %2,%0 xor<VAXint:isfx>2 %1,%0 xor<VAXint:isfx>3 %2,%1,%0")(define_insn "neg<mode>2" [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g") (neg:VAXfp (match_operand:VAXfp 1 "general_operand" "gF")))] "" "mneg<VAXfp:fsfx> %1,%0")(define_insn "neg<mode>2" [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g") (neg:VAXint (match_operand:VAXint 1 "general_operand" "g")))] "" "mneg<VAXint:isfx> %1,%0")(define_insn "one_cmpl<mode>2" [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g") (not:VAXint (match_operand:VAXint 1 "general_operand" "g")))] "" "mcom<VAXint:isfx> %1,%0");; Arithmetic right shift on the VAX works by negating the shift count,;; then emitting a right shift with the shift count negated. This means;; that all actual shift counts in the RTL will be positive. This;; prevents converting shifts to ZERO_EXTRACTs with negative positions,;; which isn't valid.(define_expand "ashrsi3" [(set (match_operand:SI 0 "general_operand" "=g") (ashiftrt:SI (match_operand:SI 1 "general_operand" "g") (match_operand:QI 2 "general_operand" "g")))] "" "{ if (GET_CODE (operands[2]) != CONST_INT) operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2]));}")(define_insn "" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (ashiftrt:SI (match_operand:SI 1 "general_operand" "g") (match_operand:QI 2 "const_int_operand" "n")))] "" "ashl $%n2,%1,%0")(define_insn "" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (ashiftrt:SI (match_operand:SI 1 "general_operand" "g") (neg:QI (match_operand:QI 2 "general_operand" "g"))))] "" "ashl %2,%1,%0")(define_insn "ashlsi3" [(set (match_operand:SI 0 "nonimmediate_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") (ashiftrt:DI (match_operand:DI 1 "general_operand" "g") (match_operand:QI 2 "general_operand" "g")))] "" "{ operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2]));}")(define_insn "ashldi3" [(set (match_operand:DI 0 "nonimmediate_operand" "=g") (ashift:DI (match_operand:DI 1 "general_operand" "g") (match_operand:QI 2 "general_operand" "g")))] "" "ashq %2,%1,%0")(define_insn "" [(set (match_operand:DI 0 "nonimmediate_operand" "=g") (ashiftrt:DI (match_operand:DI 1 "general_operand" "g") (neg:QI (match_operand:QI 2 "general_operand" "g"))))] "" "ashq %2,%1,%0");; We used to have expand_shift handle logical right shifts by using extzv,;; but this make it very difficult to do lshrdi3. Since the VAX is the;; only machine with this kludge, it's better to just do this with a;; define_expand and remove that case from expand_shift.(define_expand "lshrsi3" [(set (match_dup 3) (minus:QI (const_int 32) (match_dup 4))) (set (match_operand:SI 0 "general_operand" "=g") (zero_extract:SI (match_operand:SI 1 "register_operand" "r") (match_dup 3) (match_operand:SI 2 "register_operand" "g")))] "" "{ operands[3] = gen_reg_rtx (QImode); operands[4] = gen_lowpart (QImode, operands[2]);}");; Rotate right on the VAX works by negating the shift count.(define_expand "rotrsi3" [(set (match_operand:SI 0 "general_operand" "=g") (rotatert:SI (match_operand:SI 1 "general_operand" "g") (match_operand:QI 2 "general_operand" "g")))] "" "{ if (GET_CODE (operands[2]) != CONST_INT) operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2]));}")(define_insn "rotlsi3" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (rotate:SI (match_operand:SI 1 "general_operand" "g") (match_operand:QI 2 "general_operand" "g")))] "" "rotl %2,%1,%0")(define_insn "" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (rotatert:SI (match_operand:SI 1 "general_operand" "g") (match_operand:QI 2 "const_int_operand" "n")))] "" "rotl %R2,%1,%0")(define_insn "" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (rotatert:SI (match_operand:SI 1 "general_operand" "g") (neg:QI (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");; 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 "register_operand" "+ro") (match_operand:QI 1 "const_int_operand" "n") (match_operand:SI 2 "const_int_operand" "n")) (match_operand:SI 3 "general_operand" "g"))] "(INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16) && INTVAL (operands[2]) % INTVAL (operands[1]) == 0 && (GET_CODE (operands[0]) == REG || ! mode_dependent_address_p (XEXP (operands[0], 0)))" "*{ if (REG_P (operands[0])) { if (INTVAL (operands[2]) != 0) return \"insv %3,%2,%1,%0\"; } else operands[0] = adjust_address (operands[0], INTVAL (operands[1]) == 8 ? QImode : HImode, INTVAL (operands[2]) / 8);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -