From: Jakub Jelinek Date: Tue, 25 Mar 2014 21:47:41 +0000 (+0100) Subject: i386.md (general_sext_operand): New mode attr. X-Git-Tag: releases/gcc-4.9.0~307 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d1873c577e44f13659140c348df7c46c354e3d26;p=thirdparty%2Fgcc.git i386.md (general_sext_operand): New mode attr. * config/i386/i386.md (general_sext_operand): New mode attr. (addv4, subv4, mulv4): If operands[2] is CONST_INT, don't generate (sign_extend (const_int)). (*addv4, *subv4, *mulv4): Disallow CONST_INT_P operands[2]. Use We constraint instead of and predicate instead of . (*addv4_1, *subv4_1, *mulv4_1): New insns. * config/i386/constraints.md (We): New constraint. * config/i386/predicates.md (x86_64_sext_operand, sext_operand): New predicates. From-SVN: r208824 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d3dfb305aa66..596e25d96d22 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2014-03-25 Jakub Jelinek + + * config/i386/i386.md (general_sext_operand): New mode attr. + (addv4, subv4, mulv4): If operands[2] is CONST_INT, + don't generate (sign_extend (const_int)). + (*addv4, *subv4, *mulv4): Disallow CONST_INT_P + operands[2]. Use We constraint instead of and + predicate instead of . + (*addv4_1, *subv4_1, *mulv4_1): New insns. + * config/i386/constraints.md (We): New constraint. + * config/i386/predicates.md (x86_64_sext_operand, + sext_operand): New predicates. + 2014-03-25 Martin Jambor PR ipa/60600 diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md index 65335f128775..567e705646a9 100644 --- a/gcc/config/i386/constraints.md +++ b/gcc/config/i386/constraints.md @@ -220,6 +220,13 @@ ;; We use W prefix to denote any number of ;; constant-or-symbol-reference constraints +(define_constraint "We" + "32-bit signed integer constant, or a symbolic reference known + to fit that range (for sign-extending conversion operations that + require non-VOIDmode immediate operands)." + (and (match_operand 0 "x86_64_immediate_operand") + (match_test "GET_MODE (op) != VOIDmode"))) + (define_constraint "Wz" "32-bit unsigned integer constant, or a symbolic reference known to fit that range (for zero-extending conversion operations that diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 4a8b46388bce..ca16173abbb5 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -971,6 +971,15 @@ (DI "x86_64_general_operand") (TI "x86_64_general_operand")]) +;; General sign extend operand predicate for integer modes, +;; which disallows VOIDmode operands and thus it is suitable +;; for use inside sign_extend. +(define_mode_attr general_sext_operand + [(QI "sext_operand") + (HI "sext_operand") + (SI "x86_64_sext_operand") + (DI "x86_64_sext_operand")]) + ;; General sign/zero extend operand predicate for integer modes. (define_mode_attr general_szext_operand [(QI "general_operand") @@ -5821,10 +5830,11 @@ (eq:CCO (plus: (sign_extend: (match_operand:SWI 1 "nonimmediate_operand")) - (sign_extend: - (match_operand:SWI 2 ""))) + (match_dup 4)) (sign_extend: - (plus:SWI (match_dup 1) (match_dup 2))))) + (plus:SWI (match_dup 1) + (match_operand:SWI 2 + ""))))) (set (match_operand:SWI 0 "register_operand") (plus:SWI (match_dup 1) (match_dup 2)))]) (set (pc) (if_then_else @@ -5832,7 +5842,13 @@ (label_ref (match_operand 3)) (pc)))] "" - "ix86_fixup_binary_operands_no_copy (PLUS, mode, operands);") +{ + ix86_fixup_binary_operands_no_copy (PLUS, mode, operands); + if (CONST_INT_P (operands[2])) + operands[4] = operands[2]; + else + operands[4] = gen_rtx_SIGN_EXTEND (mode, operands[2]); +}) (define_insn "*addv4" [(set (reg:CCO FLAGS_REG) @@ -5840,7 +5856,8 @@ (sign_extend: (match_operand:SWI 1 "nonimmediate_operand" "%0,0")) (sign_extend: - (match_operand:SWI 2 "" ","))) + (match_operand:SWI 2 "" + "mWe,We"))) (sign_extend: (plus:SWI (match_dup 1) (match_dup 2))))) (set (match_operand:SWI 0 "nonimmediate_operand" "=,m") @@ -5850,6 +5867,31 @@ [(set_attr "type" "alu") (set_attr "mode" "")]) +(define_insn "*addv4_1" + [(set (reg:CCO FLAGS_REG) + (eq:CCO (plus: + (sign_extend: + (match_operand:SWI 1 "nonimmediate_operand" "0")) + (match_operand: 3 "const_int_operand" "i")) + (sign_extend: + (plus:SWI (match_dup 1) + (match_operand:SWI 2 "x86_64_immediate_operand" + ""))))) + (set (match_operand:SWI 0 "nonimmediate_operand" "=m") + (plus:SWI (match_dup 1) (match_dup 2)))] + "ix86_binary_operator_ok (PLUS, mode, operands) + && CONST_INT_P (operands[2]) + && INTVAL (operands[2]) == INTVAL (operands[3])" + "add{}\t{%2, %0|%0, %2}" + [(set_attr "type" "alu") + (set_attr "mode" "") + (set (attr "length_immediate") + (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)") + (const_string "1") + (match_test " == 8") + (const_string "4")] + (const_string "")))]) + ;; The lea patterns for modes less than 32 bits need to be matched by ;; several insns converted to real lea by splitters. @@ -6093,10 +6135,11 @@ (eq:CCO (minus: (sign_extend: (match_operand:SWI 1 "nonimmediate_operand")) - (sign_extend: - (match_operand:SWI 2 ""))) + (match_dup 4)) (sign_extend: - (minus:SWI (match_dup 1) (match_dup 2))))) + (minus:SWI (match_dup 1) + (match_operand:SWI 2 + ""))))) (set (match_operand:SWI 0 "register_operand") (minus:SWI (match_dup 1) (match_dup 2)))]) (set (pc) (if_then_else @@ -6104,7 +6147,13 @@ (label_ref (match_operand 3)) (pc)))] "" - "ix86_fixup_binary_operands_no_copy (MINUS, mode, operands);") +{ + ix86_fixup_binary_operands_no_copy (MINUS, mode, operands); + if (CONST_INT_P (operands[2])) + operands[4] = operands[2]; + else + operands[4] = gen_rtx_SIGN_EXTEND (mode, operands[2]); +}) (define_insn "*subv4" [(set (reg:CCO FLAGS_REG) @@ -6112,7 +6161,8 @@ (sign_extend: (match_operand:SWI 1 "nonimmediate_operand" "0,0")) (sign_extend: - (match_operand:SWI 2 "" ",m"))) + (match_operand:SWI 2 "" + "We,m"))) (sign_extend: (minus:SWI (match_dup 1) (match_dup 2))))) (set (match_operand:SWI 0 "nonimmediate_operand" "=m,") @@ -6122,6 +6172,31 @@ [(set_attr "type" "alu") (set_attr "mode" "")]) +(define_insn "*subv4_1" + [(set (reg:CCO FLAGS_REG) + (eq:CCO (minus: + (sign_extend: + (match_operand:SWI 1 "nonimmediate_operand" "0")) + (match_operand: 3 "const_int_operand" "i")) + (sign_extend: + (minus:SWI (match_dup 1) + (match_operand:SWI 2 "x86_64_immediate_operand" + ""))))) + (set (match_operand:SWI 0 "nonimmediate_operand" "=m") + (minus:SWI (match_dup 1) (match_dup 2)))] + "ix86_binary_operator_ok (MINUS, mode, operands) + && CONST_INT_P (operands[2]) + && INTVAL (operands[2]) == INTVAL (operands[3])" + "sub{}\t{%2, %0|%0, %2}" + [(set_attr "type" "alu") + (set_attr "mode" "") + (set (attr "length_immediate") + (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)") + (const_string "1") + (match_test " == 8") + (const_string "4")] + (const_string "")))]) + (define_insn "*sub_3" [(set (reg FLAGS_REG) (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0") @@ -6442,52 +6517,98 @@ (eq:CCO (mult: (sign_extend: (match_operand:SWI48 1 "register_operand")) - (sign_extend: - (match_operand:SWI48 2 ""))) + (match_dup 4)) (sign_extend: - (mult:SWI48 (match_dup 1) (match_dup 2))))) + (mult:SWI48 (match_dup 1) + (match_operand:SWI48 2 + ""))))) (set (match_operand:SWI48 0 "register_operand") (mult:SWI48 (match_dup 1) (match_dup 2)))]) (set (pc) (if_then_else (eq (reg:CCO FLAGS_REG) (const_int 0)) (label_ref (match_operand 3)) - (pc)))]) + (pc)))] + "" +{ + if (CONST_INT_P (operands[2])) + operands[4] = operands[2]; + else + operands[4] = gen_rtx_SIGN_EXTEND (mode, operands[2]); +}) (define_insn "*mulv4" [(set (reg:CCO FLAGS_REG) (eq:CCO (mult: (sign_extend: - (match_operand:SWI 1 "nonimmediate_operand" "%rm,rm,0")) + (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0")) (sign_extend: - (match_operand:SWI 2 "" "K,,mr"))) + (match_operand:SWI48 2 "" + "We,mr"))) (sign_extend: - (mult:SWI (match_dup 1) (match_dup 2))))) - (set (match_operand:SWI 0 "register_operand" "=r,r,r") - (mult:SWI (match_dup 1) (match_dup 2)))] + (mult:SWI48 (match_dup 1) (match_dup 2))))) + (set (match_operand:SWI48 0 "register_operand" "=r,r") + (mult:SWI48 (match_dup 1) (match_dup 2)))] "!(MEM_P (operands[1]) && MEM_P (operands[2]))" "@ - imul{}\t{%2, %1, %0|%0, %1, %2} imul{}\t{%2, %1, %0|%0, %1, %2} imul{}\t{%2, %0|%0, %2}" [(set_attr "type" "imul") - (set_attr "prefix_0f" "0,0,1") + (set_attr "prefix_0f" "0,1") (set (attr "athlon_decode") (cond [(eq_attr "cpu" "athlon") (const_string "vector") - (eq_attr "alternative" "1") + (eq_attr "alternative" "0") (const_string "vector") - (and (eq_attr "alternative" "2") + (and (eq_attr "alternative" "1") (match_operand 1 "memory_operand")) (const_string "vector")] (const_string "direct"))) (set (attr "amdfam10_decode") - (cond [(and (eq_attr "alternative" "0,1") + (cond [(and (eq_attr "alternative" "1") (match_operand 1 "memory_operand")) (const_string "vector")] (const_string "direct"))) (set_attr "bdver1_decode" "direct") (set_attr "mode" "")]) +(define_insn "*mulv4_1" + [(set (reg:CCO FLAGS_REG) + (eq:CCO (mult: + (sign_extend: + (match_operand:SWI48 1 "nonimmediate_operand" "rm,rm")) + (match_operand: 3 "const_int_operand" "K,i")) + (sign_extend: + (mult:SWI48 (match_dup 1) + (match_operand:SWI 2 "x86_64_immediate_operand" + "K,"))))) + (set (match_operand:SWI48 0 "register_operand" "=r,r") + (mult:SWI48 (match_dup 1) (match_dup 2)))] + "!(MEM_P (operands[1]) && MEM_P (operands[2])) + && CONST_INT_P (operands[2]) + && INTVAL (operands[2]) == INTVAL (operands[3])" + "@ + imul{}\t{%2, %1, %0|%0, %1, %2} + imul{}\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "imul") + (set (attr "athlon_decode") + (cond [(eq_attr "cpu" "athlon") + (const_string "vector") + (eq_attr "alternative" "1") + (const_string "vector")] + (const_string "direct"))) + (set (attr "amdfam10_decode") + (cond [(match_operand 1 "memory_operand") + (const_string "vector")] + (const_string "direct"))) + (set_attr "bdver1_decode" "direct") + (set_attr "mode" "") + (set (attr "length_immediate") + (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)") + (const_string "1") + (match_test " == 8") + (const_string "4")] + (const_string "")))]) + (define_expand "mul3" [(parallel [(set (match_operand: 0 "register_operand") (mult: diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index 0492241fd8f8..2ef1384246ee 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -338,6 +338,20 @@ (match_operand 0 "x86_64_immediate_operand")) (match_operand 0 "general_operand"))) +;; Return true if OP is non-VOIDmode general operand representable +;; on x86_64. This predicate is used in sign-extending conversion +;; operations that require non-VOIDmode immediate operands. +(define_predicate "x86_64_sext_operand" + (and (match_test "GET_MODE (op) != VOIDmode") + (match_operand 0 "x86_64_general_operand"))) + +;; Return true if OP is non-VOIDmode general operand. This predicate +;; is used in sign-extending conversion operations that require +;; non-VOIDmode immediate operands. +(define_predicate "sext_operand" + (and (match_test "GET_MODE (op) != VOIDmode") + (match_operand 0 "general_operand"))) + ;; Return true if OP is representable on x86_64 as zero-extended operand. ;; This predicate is used in zero-extending conversion operations that ;; require non-VOIDmode immediate operands.