📄 i386.md
字号:
[(set (match_operand:QI 0 "general_operand" "=qm,q") (plus:QI (match_operand:QI 1 "general_operand" "%0,0") (match_operand:QI 2 "general_operand" "qn,qmn")))] "" "*{ if (operands[2] == const1_rtx) return AS1 (inc%B0,%0); if (operands[2] == constm1_rtx) return AS1 (dec%B0,%0); return AS2 (add%B0,%2,%0);}");Lennart Augustsson <augustss@cs.chalmers.se>;says this pattern just makes slower code:; pushl %ebp; addl $-80,(%esp);instead of; leal -80(%ebp),%eax; pushl %eax;;(define_insn ""; [(set (match_operand:SI 0 "push_operand" "=<"); (plus:SI (match_operand:SI 1 "general_operand" "%r"); (match_operand:SI 2 "general_operand" "ri")))]; ""; "*;{; rtx xops[4];; xops[0] = operands[0];; xops[1] = operands[1];; xops[2] = operands[2];; xops[3] = gen_rtx (MEM, SImode, stack_pointer_rtx);; output_asm_insn (\"push%z1 %1\", xops);; output_asm_insn (AS2 (add%z3,%2,%3), xops);; RET;;}");; addsi3 is faster, so put this after.(define_insn "" [(set (match_operand:SI 0 "register_operand" "=r") (match_operand:QI 1 "address_operand" "p"))] "" "*{ CC_STATUS_INIT; /* Adding a constant to a register is faster with an add. */ /* ??? can this ever happen? */ if (GET_CODE (operands[1]) == PLUS && GET_CODE (XEXP (operands[1], 1)) == CONST_INT && rtx_equal_p (operands[0], XEXP (operands[1], 0))) { operands[1] = XEXP (operands[1], 1); if (operands[1] == const1_rtx) return AS1 (inc%L0,%0); if (operands[1] == constm1_rtx) return AS1 (dec%L0,%0); return AS2 (add%L0,%1,%0); } return AS2 (lea%L0,%a1,%0);}");; The patterns that match these are at the end of this file.(define_expand "adddf3" [(set (match_operand:DF 0 "register_operand" "") (plus:DF (match_operand:DF 1 "nonimmediate_operand" "") (match_operand:DF 2 "nonimmediate_operand" "")))] "TARGET_80387" "")(define_expand "addsf3" [(set (match_operand:SF 0 "register_operand" "") (plus:SF (match_operand:SF 1 "nonimmediate_operand" "") (match_operand:SF 2 "nonimmediate_operand" "")))] "TARGET_80387" "");;- subtract instructions(define_insn "subdi3" [(set (match_operand:DI 0 "general_operand" "=&r,ro") (minus:DI (match_operand:DI 1 "general_operand" "0,0") (match_operand:DI 2 "general_operand" "o,riF")))] "" "*{ rtx low[3], high[3]; CC_STATUS_INIT; split_di (operands, 3, low, high); output_asm_insn (AS2 (sub%L0,%2,%0), low); output_asm_insn (AS2 (sbb%L0,%2,%0), high); RET;}")(define_insn "subsi3" [(set (match_operand:SI 0 "general_operand" "=rm,r") (minus:SI (match_operand:SI 1 "general_operand" "0,0") (match_operand:SI 2 "general_operand" "ri,rm")))] "" "* return AS2 (sub%L0,%2,%0);")(define_insn "subhi3" [(set (match_operand:HI 0 "general_operand" "=rm,r") (minus:HI (match_operand:HI 1 "general_operand" "0,0") (match_operand:HI 2 "general_operand" "ri,rm")))] "" "* return AS2 (sub%W0,%2,%0);")(define_insn "subqi3" [(set (match_operand:QI 0 "general_operand" "=qm,q") (minus:QI (match_operand:QI 1 "general_operand" "0,0") (match_operand:QI 2 "general_operand" "qn,qmn")))] "" "* return AS2 (sub%B0,%2,%0);");; The patterns that match these are at the end of this file.(define_expand "subdf3" [(set (match_operand:DF 0 "register_operand" "") (minus:DF (match_operand:DF 1 "nonimmediate_operand" "") (match_operand:DF 2 "nonimmediate_operand" "")))] "TARGET_80387" "")(define_expand "subsf3" [(set (match_operand:SF 0 "register_operand" "") (minus:SF (match_operand:SF 1 "nonimmediate_operand" "") (match_operand:SF 2 "nonimmediate_operand" "")))] "TARGET_80387" "");;- multiply instructions;(define_insn "mulqi3"; [(set (match_operand:QI 0 "general_operand" "=a"); (mult:QI (match_operand:QI 1 "general_operand" "%0"); (match_operand:QI 2 "general_operand" "qm")))]; ""; "imul%B0 %2,%0")(define_insn "" [(set (match_operand:HI 0 "general_operand" "=r") (mult:SI (match_operand:HI 1 "general_operand" "%0") (match_operand:HI 2 "general_operand" "r")))] "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x80" "* return AS2 (imul%W0,%2,%0);")(define_insn "mulhi3" [(set (match_operand:HI 0 "general_operand" "=r,r") (mult:SI (match_operand:HI 1 "general_operand" "%0,rm") (match_operand:HI 2 "general_operand" "g,i")))] "" "*{ if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]) && (GET_CODE (operands[2]) == MEM || GET_CODE (operands[2]) == REG)) /* Assembler has weird restrictions. */ return AS2 (imul%W0,%2,%0); return AS3 (imul%W0,%2,%1,%0);}")(define_insn "" [(set (match_operand:SI 0 "general_operand" "=r") (mult:SI (match_operand:SI 1 "general_operand" "%0") (match_operand:SI 2 "general_operand" "r")))] "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x80" "* return AS2 (imul%L0,%2,%0);")(define_insn "mulsi3" [(set (match_operand:SI 0 "general_operand" "=r,r") (mult:SI (match_operand:SI 1 "general_operand" "%0,rm") (match_operand:SI 2 "general_operand" "g,i")))] "" "*{ if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]) && (GET_CODE (operands[2]) == MEM || GET_CODE (operands[2]) == REG)) /* Assembler has weird restrictions. */ return AS2 (imul%L0,%2,%0); return AS3 (imul%L0,%2,%1,%0);}")(define_insn "" [(set (match_operand:HI 0 "general_operand" "=a") (mult:SI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0")) (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))] "" "mul%B0 %2");; The patterns that match these are at the end of this file.(define_expand "muldf3" [(set (match_operand:DF 0 "register_operand" "") (mult:DF (match_operand:DF 1 "nonimmediate_operand" "") (match_operand:DF 2 "nonimmediate_operand" "")))] "TARGET_80387" "")(define_expand "mulsf3" [(set (match_operand:SF 0 "register_operand" "") (mult:SF (match_operand:SF 1 "nonimmediate_operand" "") (match_operand:SF 2 "nonimmediate_operand" "")))] "TARGET_80387" "");;- divide instructions(define_insn "divqi3" [(set (match_operand:QI 0 "general_operand" "=a") (div:QI (match_operand:HI 1 "general_operand" "0") (match_operand:QI 2 "general_operand" "qm")))] "" "idiv%B0 %2")(define_insn "udivqi3" [(set (match_operand:QI 0 "general_operand" "=a") (udiv:QI (match_operand:HI 1 "general_operand" "0") (match_operand:QI 2 "general_operand" "qm")))] "" "div%B0 %2");; The patterns that match these are at the end of this file.(define_expand "divdf3" [(set (match_operand:DF 0 "register_operand" "") (div:DF (match_operand:DF 1 "nonimmediate_operand" "") (match_operand:DF 2 "nonimmediate_operand" "")))] "TARGET_80387" "")(define_expand "divsf3" [(set (match_operand:SF 0 "register_operand" "") (div:SF (match_operand:SF 1 "nonimmediate_operand" "") (match_operand:SF 2 "nonimmediate_operand" "")))] "TARGET_80387" "");; Remainder instructions.(define_insn "divmodsi4" [(set (match_operand:SI 0 "register_operand" "=a") (div:SI (match_operand:SI 1 "register_operand" "0") (match_operand:SI 2 "general_operand" "rm"))) (set (match_operand:SI 3 "register_operand" "=&d") (mod:SI (match_dup 1) (match_dup 2)))] "" "*{#ifdef INTEL_SYNTAX output_asm_insn (\"cdq\", operands);#else output_asm_insn (\"cltd\", operands);#endif return AS1 (idiv%L0,%2);}")(define_insn "divmodhi4" [(set (match_operand:HI 0 "register_operand" "=a") (div:HI (match_operand:HI 1 "register_operand" "0") (match_operand:HI 2 "general_operand" "rm"))) (set (match_operand:HI 3 "register_operand" "=&d") (mod:HI (match_dup 1) (match_dup 2)))] "" "cwtd\;idiv%W0 %2");; ??? Can we make gcc zero extend operand[0]?(define_insn "udivmodsi4" [(set (match_operand:SI 0 "register_operand" "=a") (udiv:SI (match_operand:SI 1 "register_operand" "0") (match_operand:SI 2 "general_operand" "rm"))) (set (match_operand:SI 3 "register_operand" "=&d") (umod:SI (match_dup 1) (match_dup 2)))] "" "*{ output_asm_insn (AS2 (xor%L3,%3,%3), operands); return AS1 (div%L0,%2);}");; ??? Can we make gcc zero extend operand[0]?(define_insn "udivmodhi4" [(set (match_operand:HI 0 "register_operand" "=a") (udiv:HI (match_operand:HI 1 "register_operand" "0") (match_operand:HI 2 "general_operand" "rm"))) (set (match_operand:HI 3 "register_operand" "=&d") (umod:HI (match_dup 1) (match_dup 2)))] "" "*{ output_asm_insn (AS2 (xor%W0,%3,%3), operands); return AS1 (div%W0,%2);}")/*;;this should be a valid double division which we may want to add(define_insn "" [(set (match_operand:SI 0 "register_operand" "=a") (udiv:DI (match_operand:DI 1 "register_operand" "a") (match_operand:SI 2 "general_operand" "rm"))) (set (match_operand:SI 3 "register_operand" "=d") (umod:SI (match_dup 1) (match_dup 2)))] "" "div%L0 %2,%0")*/;;- and instructions;; On i386,;; movzbl %bl,%ebx;; is faster than;; andl $255,%ebx;;;; but if the reg is %eax, then the "andl" is faster.;;;; On i486, the "andl" is always faster than the "movzbl".;;;; On both i386 and i486, a three operand AND is as fast with movzbl or;; movzwl as with andl, if operands[0] != operands[1].;; The `r' in `rm' for operand 3 looks redundant, but it causes;; optional reloads to be generated if op 3 is a pseudo in a stack slot.;; ??? What if we only change one byte of an offsettable memory reference?(define_insn "andsi3" [(set (match_operand:SI 0 "general_operand" "=r,r,rm,r") (and:SI (match_operand:SI 1 "general_operand" "%rm,qm,0,0") (match_operand:SI 2 "general_operand" "L,K,ri,rm")))] "" "*{ if (GET_CODE (operands[2]) == CONST_INT && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))) { if (INTVAL (operands[2]) == 0xffff && REG_P (operands[0]) && (! REG_P (operands[1]) || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0) && (! TARGET_486 || ! rtx_equal_p (operands[0], operands[1]))) { /* ??? tege: Should forget CC_STATUS only if we clobber a remembered operand. Fix that later. */ CC_STATUS_INIT;#ifdef INTEL_SYNTAX return AS2 (movzx,%w1,%0);#else return AS2 (movz%W0%L0,%w1,%0);#endif } if (INTVAL (operands[2]) == 0xff && REG_P (operands[0]) && !(REG_P (operands[1]) && NON_QI_REG_P (operands[1])) && (! REG_P (operands[1]) || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0) && (! TARGET_486 || ! rtx_equal_p (operands[0], operands[1]))) { /* ??? tege: Should forget CC_STATUS only if we clobber a remembered operand. Fix that later. */ CC_STATUS_INIT;#ifdef INTEL_SYNTAX return AS2 (movzx,%b1,%0);#else return AS2 (movz%B0%L0,%b1,%0);#endif } if (QI_REG_P (operands[0]) && ~(INTVAL (operands[2]) | 0xff) == 0) { CC_STATUS_INIT; if (INTVAL (operands[2]) == 0xffffff00) { operands[2] = const0_rtx; return AS2 (mov%B0,%2,%b0); } operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff); return AS2 (and%B0,%2,%b0); } if (QI_REG_P (operands[0]) && ~(INTVAL (operands[2]) | 0xff00) == 0) { CC_STATUS_INIT; if (INTVAL (operands[2]) == 0xffff00ff) { operands[2] = const0_rtx; return AS2 (mov%B0,%2,%h0); } operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff); return AS2 (and%B0,%2,%h0); } if (GET_CODE (operands[0]) == MEM && INTVAL (operands[2]) == 0xffff0000) { operands[2] = const0_rtx; return AS2 (mov%W0,%2,%w0); } } return AS2 (and%L0,%2,%0);}")(define_insn "andhi3" [(set (match_operand:HI 0 "general_operand" "=rm,r") (and:HI (match_operand:HI 1 "general_operand" "%0,0") (match_operand:HI 2 "general_operand" "ri,rm")))] "" "*{ if (GET_CODE (operands[2]) == CONST_INT && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))) { /* Can we ignore the upper byte? */ if ((! REG_P (operands[0]) || QI_REG_P (operands[0])) && (INTVAL (operands[2]) & 0xff00) == 0xff00) { CC_STATUS_INIT; if ((INTVAL (operands[2]) & 0xff) == 0) { operands[2] = const0_rtx; return AS2 (mov%B0,%2,%b0); } operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff); return AS2 (and%B0,%2,%b0); } /* Can we ignore the lower byte? */ /* ??? what about offsettable memory references? */ if (QI_REG_P (operands[0]) && (INTVAL (operands[2]) & 0xff) == 0xff) { CC_STATUS_INIT; if ((INTVAL (operands[2]) & 0xff00) == 0) { operands[2] = const0_rtx; return AS2 (mov%B0,%2,%h0); } operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff); return AS2 (and%B0,%2,%h0); } } return AS2 (and%W0,%2,%0);}")(define_insn "andqi3" [(set (match_operand:QI 0 "general_operand" "=qm,q") (and:QI (match_operand:QI 1 "general_operand" "%0,0") (match_operand:QI 2 "general_operand" "qn,qmn")))] "" "* return AS2 (and%B0,%2,%0);")/* I am nervous about these two.. add them later..;I presume this means that we have something in say op0= eax which is small;and we want to and it with memory so we can do this by just an;andb m,%al and have success.(define_insn "" [(set (match_operand:SI 0 "general_operand" "=r") (and:SI (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")) (match_operand:SI 2 "general_operand" "0")))] "GET_CODE (operands[2]) == CONST_INT && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (HImode))" "and%W0 %1,%0")(define_insn "" [(set (match_operand:SI 0 "general_operand" "=q") (and:SI (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -