diff options
Diffstat (limited to 'gcc/config/i386/i386.md')
-rw-r--r-- | gcc/config/i386/i386.md | 99 |
1 files changed, 97 insertions, 2 deletions
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 738061d7048..886c1267824 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -13821,7 +13821,7 @@ (zero_extract:DI (match_operand:DI 0 "register_operand" "r") (const_int 1) - (match_operand:DI 1 "register_operand" "r")) + (match_operand:DI 1 "nonmemory_operand" "rN")) (const_int 0)))] "TARGET_64BIT && (TARGET_USE_BT || optimize_size)" "bt{q}\t{%1, %0|%0, %1}" @@ -13833,7 +13833,7 @@ (zero_extract:SI (match_operand:SI 0 "register_operand" "r") (const_int 1) - (match_operand:SI 1 "register_operand" "r")) + (match_operand:SI 1 "nonmemory_operand" "rN")) (const_int 0)))] "TARGET_USE_BT || optimize_size" "bt{l}\t{%1, %0|%0, %1}" @@ -14119,6 +14119,39 @@ PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); }) +;; avoid useless masking of bit offset operand +(define_insn_and_split "*jcc_btdi_mask_rex64" + [(set (pc) + (if_then_else (match_operator 0 "bt_comparison_operator" + [(zero_extract:DI + (match_operand:DI 1 "register_operand" "r") + (const_int 1) + (and:SI + (match_operand:SI 2 "register_operand" "r") + (match_operand:SI 3 "const_int_operand" "n")))]) + (label_ref (match_operand 4 "" "")) + (pc)))] + "TARGET_64BIT && (TARGET_USE_BT || optimize_size) + && (INTVAL (operands[3]) & 0x3f) == 0x3f" + "#" + "&& 1" + [(set (reg:CCC FLAGS_REG) + (compare:CCC + (zero_extract:DI + (match_dup 1) + (const_int 1) + (match_dup 2)) + (const_int 0))) + (set (pc) + (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) + (label_ref (match_dup 4)) + (pc)))] +{ + operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0); + + PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); +}) + (define_insn_and_split "*jcc_btsi" [(set (pc) (if_then_else (match_operator 0 "bt_comparison_operator" @@ -14150,6 +14183,35 @@ PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); }) +;; avoid useless masking of bit offset operand +(define_insn_and_split "*jcc_btsi_mask" + [(set (pc) + (if_then_else (match_operator 0 "bt_comparison_operator" + [(zero_extract:SI + (match_operand:SI 1 "register_operand" "r") + (const_int 1) + (and:SI + (match_operand:SI 2 "register_operand" "r") + (match_operand:SI 3 "const_int_operand" "n")))]) + (label_ref (match_operand 4 "" "")) + (pc)))] + "(TARGET_USE_BT || optimize_size) + && (INTVAL (operands[3]) & 0x1f) == 0x1f" + "#" + "&& 1" + [(set (reg:CCC FLAGS_REG) + (compare:CCC + (zero_extract:SI + (match_dup 1) + (const_int 1) + (match_dup 2)) + (const_int 0))) + (set (pc) + (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) + (label_ref (match_dup 4)) + (pc)))] + "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));") + (define_insn_and_split "*jcc_btsi_1" [(set (pc) (if_then_else (match_operator 0 "bt_comparison_operator" @@ -14181,6 +14243,39 @@ PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); }) +;; avoid useless masking of bit offset operand +(define_insn_and_split "*jcc_btsi_mask_1" + [(set (pc) + (if_then_else + (match_operator 0 "bt_comparison_operator" + [(and:SI + (lshiftrt:SI + (match_operand:SI 1 "register_operand" "r") + (subreg:QI + (and:SI + (match_operand:SI 2 "register_operand" "r") + (match_operand:SI 3 "const_int_operand" "n")) 0)) + (const_int 1)) + (const_int 0)]) + (label_ref (match_operand 4 "" "")) + (pc)))] + "(TARGET_USE_BT || optimize_size) + && (INTVAL (operands[3]) & 0x1f) == 0x1f" + "#" + "&& 1" + [(set (reg:CCC FLAGS_REG) + (compare:CCC + (zero_extract:SI + (match_dup 1) + (const_int 1) + (match_dup 2)) + (const_int 0))) + (set (pc) + (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) + (label_ref (match_dup 4)) + (pc)))] + "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));") + ;; Define combination compare-and-branch fp compare instructions to use ;; during early optimization. Splitting the operation apart early makes ;; for bad code when we want to reverse the operation. |