diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index dca7bb61464..ccd4583cb69 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -2928,10 +2928,10 @@ ;; Bit complement. See comments on previous pattern. ;; ??? Is this really worthwhile? (define_insn "" - [(set (match_operand:SI 0 "general_operand" "+rm") + [(set (match_operand:SI 0 "general_operand" "=rm") (xor:SI (ashift:SI (const_int 1) (match_operand:SI 1 "general_operand" "r")) - (match_dup 0)))] + (match_operand:SI 2 "general_operand" "0")))] "! TARGET_486 && GET_CODE (operands[1]) != CONST_INT" "* { @@ -2940,22 +2940,18 @@ return AS2 (btc%L0,%1,%0); }") -/* ??? This works, but that SUBREG looks dangerous. (define_insn "" - [(set (match_operand:HI 0 "general_operand" "+rm") - (xor:HI (subreg:HI - (ashift:SI (const_int 1) - (sign_extend:SI - (match_operand:HI 1 "nonimmediate_operand" "r"))) 0) - (match_dup 0)))] - "! TARGET_486" + [(set (match_operand:SI 0 "general_operand" "=rm") + (xor:SI (match_operand:SI 1 "general_operand" "0") + (ashift:SI (const_int 1) + (match_operand:SI 2 "general_operand" "r"))))] + "! TARGET_486 && GET_CODE (operands[2]) != CONST_INT" "* { CC_STATUS_INIT; - return AS2 (btc%W0,%1,%0); + return AS2 (btc%L0,%2,%0); }") -*/ ;; Recognizers for bit-test instructions. @@ -2967,16 +2963,56 @@ ;; don't allow a MEM in the operand predicate without allowing it in the ;; constraint. -;; ??? All bets are off if operand 0 is a volatile MEM reference. - -/* (define_insn "" - [(set (cc0) (zero_extract (match_operand 0 "general_operand" "rm") + [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r") + (const_int 1) + (match_operand:SI 1 "general_operand" "r")))] + "GET_CODE (operands[1]) != CONST_INT" + "* +{ + cc_status.flags |= CC_Z_IN_NOT_C; + return AS2 (bt%L0,%1,%0); +}") + +(define_insn "" + [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r") (match_operand:SI 1 "const_int_operand" "n") (match_operand:SI 2 "const_int_operand" "n")))] - "GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT - && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4 - && (GET_CODE (operands[0]) != MEM || ! MEM_VOLATILE_P (operands[0]))" + "" + "* +{ + unsigned int mask; + + mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]); + operands[1] = GEN_INT (mask); + + if (QI_REG_P (operands[0])) + { + if ((mask & ~0xff) == 0) + { + cc_status.flags |= CC_NOT_NEGATIVE; + return AS2 (test%B0,%1,%b0); + } + + if ((mask & ~0xff00) == 0) + { + cc_status.flags |= CC_NOT_NEGATIVE; + operands[1] = GEN_INT (mask >> 8); + return AS2 (test%B0,%1,%h0); + } + } + + return AS2 (test%L0,%1,%0); +}") + +;; ??? All bets are off if operand 0 is a volatile MEM reference. +;; The CPU may access unspecified bytes around the actual target byte. + +(define_insn "" + [(set (cc0) (zero_extract (match_operand:QI 0 "general_operand" "rm") + (match_operand:SI 1 "const_int_operand" "n") + (match_operand:SI 2 "const_int_operand" "n")))] + "GET_CODE (operands[0]) != MEM || ! MEM_VOLATILE_P (operands[0])" "* { unsigned int mask; @@ -3028,17 +3064,6 @@ return AS2 (test%L1,%0,%1); }") -*/ -(define_insn "" - [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r") - (const_int 1) - (match_operand:SI 1 "general_operand" "r")))] - "GET_CODE (operands[1]) != CONST_INT" - "* -{ - cc_status.flags |= CC_Z_IN_NOT_C; - return AS2 (bt%L0,%1,%0); -}") ;; Store-flag instructions.