From: Kong Lingling <lingling.k...@intel.com> gcc/ChangeLog:
* config/i386/i386.md: (addsi_1_zext): Add new alternatives for NDD and adjust output templates. (*add<mode>_2): Likewise. (*addsi_2_zext): Likewise. (*add<mode>_3): Likewise. (*addsi_3_zext): Likewise. (*adddi_4): Likewise. (*add<mode>_4): Likewise. (*add<mode>_5): Likewise. (*addv<mode>4): Likewise. (*addv<mode>4_1): Likewise. (*add<mode>3_cconly_overflow_1): Likewise. (*add<mode>3_cc_overflow_1): Likewise. (*addsi3_zext_cc_overflow_1): Likewise. (*add<mode>3_cconly_overflow_2): Likewise. (*add<mode>3_cc_overflow_2): Likewise. (*addsi3_zext_cc_overflow_2): Likewise. gcc/testsuite/ChangeLog: * gcc.target/i386/apx-ndd.c: Add more test. --- gcc/config/i386/i386.md | 310 +++++++++++++++--------- gcc/testsuite/gcc.target/i386/apx-ndd.c | 53 ++-- 2 files changed, 232 insertions(+), 131 deletions(-) diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index cb227d19f40..2a73f6dcaec 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -6476,13 +6476,15 @@ (define_insn "*add<mode>_1" ;; patterns constructed from addsi_1 to match. (define_insn "addsi_1_zext" - [(set (match_operand:DI 0 "register_operand" "=r,r,r") + [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r") (zero_extend:DI - (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r") - (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,le")))) + (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r,r,rm") + (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,le,rBMe,re")))) (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" + "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands, + TARGET_APX_NDD)" { + bool use_ndd = (which_alternative == 3 || which_alternative == 4); switch (get_attr_type (insn)) { case TYPE_LEA: @@ -6490,11 +6492,13 @@ (define_insn "addsi_1_zext" case TYPE_INCDEC: if (operands[2] == const1_rtx) - return "inc{l}\t%k0"; + return use_ndd ? "inc{l}\t{%1, %k0|%k0, %1}" + : "inc{l}\t%k0"; else { gcc_assert (operands[2] == constm1_rtx); - return "dec{l}\t%k0"; + return use_ndd ? "dec{l}\t{%1, %k0|%k0, %1}" + : "dec{l}\t%k0"; } default: @@ -6504,12 +6508,15 @@ (define_insn "addsi_1_zext" std::swap (operands[1], operands[2]); if (x86_maybe_negate_const_int (&operands[2], SImode)) - return "sub{l}\t{%2, %k0|%k0, %2}"; + return use_ndd ? "sub{l}\t{%2 ,%1, %k0|%k0, %1, %2}" + : "sub{l}\t{%2, %k0|%k0, %2}"; - return "add{l}\t{%2, %k0|%k0, %2}"; + return use_ndd ? "add{l}\t{%2 ,%1, %k0|%k0, %1, %2}" + : "add{l}\t{%2, %k0|%k0, %2}"; } } - [(set (attr "type") + [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd") + (set (attr "type") (cond [(eq_attr "alternative" "2") (const_string "lea") (match_operand:SI 2 "incdec_operand") @@ -6811,37 +6818,42 @@ (define_insn "*add<mode>_2" [(set (reg FLAGS_REG) (compare (plus:SWI - (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>") - (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,0")) + (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>,rm,r") + (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,0,r<i>,<m>")) (const_int 0))) - (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,<r>") + (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,<r>,r,r") (plus:SWI (match_dup 1) (match_dup 2)))] "ix86_match_ccmode (insn, CCGOCmode) - && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" + && ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)" { + bool use_ndd = (which_alternative == 3 || which_alternative == 4); switch (get_attr_type (insn)) { case TYPE_INCDEC: if (operands[2] == const1_rtx) - return "inc{<imodesuffix>}\t%0"; + return use_ndd ? "inc{<imodesuffix>}\t{%1, %0|%0, %1}" + : "inc{<imodesuffix>}\t%0"; else { gcc_assert (operands[2] == constm1_rtx); - return "dec{<imodesuffix>}\t%0"; + return use_ndd ? "dec{<imodesuffix>}\t{%1, %0|%0, %1}" + : "dec{<imodesuffix>}\t%0"; } default: if (which_alternative == 2) std::swap (operands[1], operands[2]); - gcc_assert (rtx_equal_p (operands[0], operands[1])); if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) - return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; + return use_ndd ? "sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}" + : "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; - return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; + return use_ndd ? "add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}" + : "add{<imodesuffix>}\t{%2, %0|%0, %2}"; } } - [(set (attr "type") + [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd") + (set (attr "type") (if_then_else (match_operand:SWI 2 "incdec_operand") (const_string "incdec") (const_string "alu"))) @@ -6856,23 +6868,26 @@ (define_insn "*add<mode>_2" (define_insn "*addsi_2_zext" [(set (reg FLAGS_REG) (compare - (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r") - (match_operand:SI 2 "x86_64_general_operand" "rBMe,0")) + (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r,rm") + (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,rBMe,re")) (const_int 0))) - (set (match_operand:DI 0 "register_operand" "=r,r") + (set (match_operand:DI 0 "register_operand" "=r,r,r,r") (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) - && ix86_binary_operator_ok (PLUS, SImode, operands)" + && ix86_binary_operator_ok (PLUS, SImode, operands, TARGET_APX_NDD)" { + bool use_ndd = (which_alternative == 2 || which_alternative == 3); switch (get_attr_type (insn)) { case TYPE_INCDEC: if (operands[2] == const1_rtx) - return "inc{l}\t%k0"; + return use_ndd ? "inc{l}\t{%1, %k0|%k0, %1}" + : "inc{l}\t%k0"; else { gcc_assert (operands[2] == constm1_rtx); - return "dec{l}\t%k0"; + return use_ndd ? "dec{l}\t{%1, %k0|%k0, %1}" + : "dec{l}\t%k0"; } default: @@ -6880,12 +6895,15 @@ (define_insn "*addsi_2_zext" std::swap (operands[1], operands[2]); if (x86_maybe_negate_const_int (&operands[2], SImode)) - return "sub{l}\t{%2, %k0|%k0, %2}"; + return use_ndd ? "sub{l}\t{%2, %1, %k0|%k0, %1, %2}" + : "sub{l}\t{%2, %k0|%k0, %2}"; - return "add{l}\t{%2, %k0|%k0, %2}"; + return use_ndd ? "add{l}\t{%2, %1, %k0|%k0, %1, %2}" + : "add{l}\t{%2, %k0|%k0, %2}"; } } - [(set (attr "type") + [(set_attr "isa" "*,*,apx_ndd,apx_ndd") + (set (attr "type") (if_then_else (match_operand:SI 2 "incdec_operand") (const_string "incdec") (const_string "alu"))) @@ -6899,35 +6917,40 @@ (define_insn "*addsi_2_zext" (define_insn "*add<mode>_3" [(set (reg FLAGS_REG) (compare - (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0")) - (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>"))) - (clobber (match_scratch:SWI 0 "=<r>,<r>"))] + (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0,<g>,re")) + (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>,r,rm"))) + (clobber (match_scratch:SWI 0 "=<r>,<r>,r,r"))] "ix86_match_ccmode (insn, CCZmode) && !(MEM_P (operands[1]) && MEM_P (operands[2]))" { + bool use_ndd = (which_alternative == 2 || which_alternative == 3); switch (get_attr_type (insn)) { case TYPE_INCDEC: if (operands[2] == const1_rtx) - return "inc{<imodesuffix>}\t%0"; + return use_ndd ? "inc{<imodesuffix>}\t{%1, %0|%0, %1}" + : "inc{<imodesuffix>}\t%0"; else { gcc_assert (operands[2] == constm1_rtx); - return "dec{<imodesuffix>}\t%0"; + return use_ndd ? "dec{<imodesuffix>}\t{%1, %0|%0, %1}" + : "dec{<imodesuffix>}\t%0"; } default: if (which_alternative == 1) std::swap (operands[1], operands[2]); - gcc_assert (rtx_equal_p (operands[0], operands[1])); if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) - return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; + return use_ndd ? "sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}" + : "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; - return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; + return use_ndd ? "add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}" + : "add{<imodesuffix>}\t{%2, %0|%0, %2}"; } } - [(set (attr "type") + [(set_attr "isa" "*,*,apx_ndd,apx_ndd") + (set (attr "type") (if_then_else (match_operand:SWI 2 "incdec_operand") (const_string "incdec") (const_string "alu"))) @@ -6942,22 +6965,23 @@ (define_insn "*add<mode>_3" (define_insn "*addsi_3_zext" [(set (reg FLAGS_REG) (compare - (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rBMe,0")) - (match_operand:SI 1 "nonimmediate_operand" "%0,r"))) - (set (match_operand:DI 0 "register_operand" "=r,r") + (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,rBMe,re")) + (match_operand:SI 1 "nonimmediate_operand" "%0,r,r,rm"))) + (set (match_operand:DI 0 "register_operand" "=r,r,r,r") (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode) - && ix86_binary_operator_ok (PLUS, SImode, operands)" + && ix86_binary_operator_ok (PLUS, SImode, operands, TARGET_APX_NDD)" { + bool use_ndd = (which_alternative == 2 || which_alternative == 3); switch (get_attr_type (insn)) { case TYPE_INCDEC: if (operands[2] == const1_rtx) - return "inc{l}\t%k0"; + return use_ndd ? "inc{l}\t{%1, %k0|%k0, %1}" : "inc{l}\t%k0"; else { gcc_assert (operands[2] == constm1_rtx); - return "dec{l}\t%k0"; + return use_ndd ? "dec{l}\t{%1, %k0|%k0, %1}" : "dec{l}\t%k0"; } default: @@ -6965,12 +6989,15 @@ (define_insn "*addsi_3_zext" std::swap (operands[1], operands[2]); if (x86_maybe_negate_const_int (&operands[2], SImode)) - return "sub{l}\t{%2, %k0|%k0, %2}"; + return use_ndd ? "sub{l}\t{%2, %1, %k0|%k0, %1, %2}" + : "sub{l}\t{%2, %k0|%k0, %2}"; - return "add{l}\t{%2, %k0|%k0, %2}"; + return use_ndd ? "add{l}\t{%2, %1, %k0|%k0, %1, %2}" + : "add{l}\t{%2, %k0|%k0, %2}"; } } - [(set (attr "type") + [(set_attr "isa" "*,*,apx_ndd,apx_ndd") + (set (attr "type") (if_then_else (match_operand:SI 2 "incdec_operand") (const_string "incdec") (const_string "alu"))) @@ -6991,31 +7018,35 @@ (define_insn "*addsi_3_zext" (define_insn "*adddi_4" [(set (reg FLAGS_REG) (compare - (match_operand:DI 1 "nonimmediate_operand" "0") - (match_operand:DI 2 "x86_64_immediate_operand" "e"))) - (clobber (match_scratch:DI 0 "=r"))] + (match_operand:DI 1 "nonimmediate_operand" "0,rm") + (match_operand:DI 2 "x86_64_immediate_operand" "e,e"))) + (clobber (match_scratch:DI 0 "=r,r"))] "TARGET_64BIT && ix86_match_ccmode (insn, CCGCmode)" { + bool use_ndd = (which_alternative == 1); switch (get_attr_type (insn)) { case TYPE_INCDEC: if (operands[2] == constm1_rtx) - return "inc{q}\t%0"; + return use_ndd ? "inc{q}\t{%1, %0|%0, %1}" : "inc{q}\t%0"; else { gcc_assert (operands[2] == const1_rtx); - return "dec{q}\t%0"; + return use_ndd ? "dec{q}\t{%1, %0|%0, %1}" : "dec{q}\t%0"; } default: if (x86_maybe_negate_const_int (&operands[2], DImode)) - return "add{q}\t{%2, %0|%0, %2}"; + return use_ndd ? "add{q}\t{%2, %1, %0|%0, %1, %2}" + : "add{q}\t{%2, %0|%0, %2}"; - return "sub{q}\t{%2, %0|%0, %2}"; + return use_ndd ? "sub{q}\t{%2, %1, %0|%0, %1, %2}" + : "sub{q}\t{%2, %0|%0, %2}"; } } - [(set (attr "type") + [(set_attr "isa" "*,apx_ndd") + (set (attr "type") (if_then_else (match_operand:DI 2 "incdec_operand") (const_string "incdec") (const_string "alu"))) @@ -7036,30 +7067,36 @@ (define_insn "*adddi_4" (define_insn "*add<mode>_4" [(set (reg FLAGS_REG) (compare - (match_operand:SWI124 1 "nonimmediate_operand" "0") + (match_operand:SWI124 1 "nonimmediate_operand" "0,rm") (match_operand:SWI124 2 "const_int_operand"))) - (clobber (match_scratch:SWI124 0 "=<r>"))] + (clobber (match_scratch:SWI124 0 "=<r>,r"))] "ix86_match_ccmode (insn, CCGCmode)" { + bool use_ndd = (which_alternative == 1); switch (get_attr_type (insn)) { case TYPE_INCDEC: if (operands[2] == constm1_rtx) - return "inc{<imodesuffix>}\t%0"; + return use_ndd ? "inc{<imodesuffix>}\t{%1, %0|%0, %1}" + : "inc{<imodesuffix>}\t%0"; else { gcc_assert (operands[2] == const1_rtx); - return "dec{<imodesuffix>}\t%0"; + return use_ndd ? "dec{<imodesuffix>}\t{%1, %0|%0, %1}" + : "dec{<imodesuffix>}\t%0"; } default: if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) - return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; + return use_ndd ? "add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}" + : "add{<imodesuffix>}\t{%2, %0|%0, %2}"; - return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; + return use_ndd ? "sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}" + : "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; } } - [(set (attr "type") + [(set_attr "isa" "*,apx_ndd") + (set (attr "type") (if_then_else (match_operand:<MODE> 2 "incdec_operand") (const_string "incdec") (const_string "alu"))) @@ -7074,36 +7111,41 @@ (define_insn "*add<mode>_5" [(set (reg FLAGS_REG) (compare (plus:SWI - (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>") - (match_operand:SWI 2 "<general_operand>" "<g>,0")) + (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>,r,rm") + (match_operand:SWI 2 "<general_operand>" "<g>,0,<g>,re")) (const_int 0))) - (clobber (match_scratch:SWI 0 "=<r>,<r>"))] + (clobber (match_scratch:SWI 0 "=<r>,<r>,r,r"))] "ix86_match_ccmode (insn, CCGOCmode) && !(MEM_P (operands[1]) && MEM_P (operands[2]))" { + bool use_ndd = (which_alternative == 2 || which_alternative == 3); switch (get_attr_type (insn)) { case TYPE_INCDEC: if (operands[2] == const1_rtx) - return "inc{<imodesuffix>}\t%0"; + return use_ndd ? "inc{<imodesuffix>}\t{%1, %0|%0, %1}" + : "inc{<imodesuffix>}\t%0"; else { gcc_assert (operands[2] == constm1_rtx); - return "dec{<imodesuffix>}\t%0"; + return use_ndd ? "dec{<imodesuffix>}\t{%1, %0|%0, %1}" + : "dec{<imodesuffix>}\t%0"; } default: if (which_alternative == 1) std::swap (operands[1], operands[2]); - gcc_assert (rtx_equal_p (operands[0], operands[1])); if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) - return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; + return use_ndd ? "sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}" + : "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; - return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; + return use_ndd ? "add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}" + : "add{<imodesuffix>}\t{%2, %0|%0, %2}"; } } - [(set (attr "type") + [(set_attr "isa" "*,*,apx_ndd,apx_ndd") + (set (attr "type") (if_then_else (match_operand:SWI 2 "incdec_operand") (const_string "incdec") (const_string "alu"))) @@ -7316,35 +7358,43 @@ (define_insn "*addv<mode>4" [(set (reg:CCO FLAGS_REG) (eq:CCO (plus:<DWI> (sign_extend:<DWI> - (match_operand:SWI 1 "nonimmediate_operand" "%0,0")) + (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,r")) (sign_extend:<DWI> - (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m"))) + (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m,rWe,m"))) (sign_extend:<DWI> (plus:SWI (match_dup 1) (match_dup 2))))) - (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") + (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r") (plus:SWI (match_dup 1) (match_dup 2)))] - "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" - "add{<imodesuffix>}\t{%2, %0|%0, %2}" - [(set_attr "type" "alu") + "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)" + "@ + add{<imodesuffix>}\t{%2, %0|%0, %2} + add{<imodesuffix>}\t{%2, %0|%0, %2} + add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2} + add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "isa" "*,*,apx_ndd,apx_ndd") + (set_attr "type" "alu") (set_attr "mode" "<MODE>")]) (define_insn "addv<mode>4_1" [(set (reg:CCO FLAGS_REG) (eq:CCO (plus:<DWI> (sign_extend:<DWI> - (match_operand:SWI 1 "nonimmediate_operand" "0")) + (match_operand:SWI 1 "nonimmediate_operand" "0,rm")) (match_operand:<DWI> 3 "const_int_operand")) (sign_extend:<DWI> (plus:SWI (match_dup 1) - (match_operand:SWI 2 "x86_64_immediate_operand" "<i>"))))) - (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") + (match_operand:SWI 2 "x86_64_immediate_operand" "<i>,<i>"))))) + (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r") (plus:SWI (match_dup 1) (match_dup 2)))] - "ix86_binary_operator_ok (PLUS, <MODE>mode, operands) + "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD) && CONST_INT_P (operands[2]) && INTVAL (operands[2]) == INTVAL (operands[3])" - "add{<imodesuffix>}\t{%2, %0|%0, %2}" - [(set_attr "type" "alu") + "@ + add{<imodesuffix>}\t{%2, %0|%0, %2} + add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "isa" "*,apx_ndd") + (set_attr "type" "alu") (set_attr "mode" "<MODE>") (set (attr "length_immediate") (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)") @@ -9187,27 +9237,36 @@ (define_insn "*add<mode>3_cconly_overflow_1" [(set (reg:CCC FLAGS_REG) (compare:CCC (plus:SWI - (match_operand:SWI 1 "nonimmediate_operand" "%0") - (match_operand:SWI 2 "<general_operand>" "<g>")) + (match_operand:SWI 1 "nonimmediate_operand" "%0,r,rm") + (match_operand:SWI 2 "<general_operand>" "<g>,<g>,re")) (match_dup 1))) - (clobber (match_scratch:SWI 0 "=<r>"))] + (clobber (match_scratch:SWI 0 "=<r>,r,r"))] "!(MEM_P (operands[1]) && MEM_P (operands[2]))" - "add{<imodesuffix>}\t{%2, %0|%0, %2}" - [(set_attr "type" "alu") + "@ + add{<imodesuffix>}\t{%2, %0|%0, %2} + add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2} + add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "isa" "*,apx_ndd,apx_ndd") + (set_attr "type" "alu") (set_attr "mode" "<MODE>")]) (define_insn "@add<mode>3_cc_overflow_1" [(set (reg:CCC FLAGS_REG) (compare:CCC (plus:SWI - (match_operand:SWI 1 "nonimmediate_operand" "%0,0") - (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")) + (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,r") + (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>")) (match_dup 1))) - (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") + (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r") (plus:SWI (match_dup 1) (match_dup 2)))] - "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" - "add{<imodesuffix>}\t{%2, %0|%0, %2}" - [(set_attr "type" "alu") + "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)" + "@ + add{<imodesuffix>}\t{%2, %0|%0, %2} + add{<imodesuffix>}\t{%2, %0|%0, %2} + add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2} + add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "isa" "*,*,apx_ndd,apx_ndd") + (set_attr "type" "alu") (set_attr "mode" "<MODE>")]) (define_peephole2 @@ -9252,55 +9311,74 @@ (define_insn "*addsi3_zext_cc_overflow_1" [(set (reg:CCC FLAGS_REG) (compare:CCC (plus:SI - (match_operand:SI 1 "nonimmediate_operand" "%0") - (match_operand:SI 2 "x86_64_general_operand" "rBMe")) + (match_operand:SI 1 "nonimmediate_operand" "%0,r,rm") + (match_operand:SI 2 "x86_64_general_operand" "rBMe,rBMe,re")) (match_dup 1))) - (set (match_operand:DI 0 "register_operand" "=r") + (set (match_operand:DI 0 "register_operand" "=r,r,r") (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] - "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" - "add{l}\t{%2, %k0|%k0, %2}" - [(set_attr "type" "alu") + "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands, + TARGET_APX_NDD)" + "@ + add{l}\t{%2, %k0|%k0, %2} + add{l}\t{%2, %1, %k0|%k0, %1, %2} + add{l}\t{%2, %1, %k0|%k0, %1, %2}" + [(set_attr "isa" "*,apx_ndd,apx_ndd") + (set_attr "type" "alu") (set_attr "mode" "SI")]) (define_insn "*add<mode>3_cconly_overflow_2" [(set (reg:CCC FLAGS_REG) (compare:CCC (plus:SWI - (match_operand:SWI 1 "nonimmediate_operand" "%0") - (match_operand:SWI 2 "<general_operand>" "<g>")) + (match_operand:SWI 1 "nonimmediate_operand" "%0,r,rm") + (match_operand:SWI 2 "<general_operand>" "<g>,<g>,re")) (match_dup 2))) - (clobber (match_scratch:SWI 0 "=<r>"))] + (clobber (match_scratch:SWI 0 "=<r>,r,r"))] "!(MEM_P (operands[1]) && MEM_P (operands[2]))" - "add{<imodesuffix>}\t{%2, %0|%0, %2}" - [(set_attr "type" "alu") + "@ + add{<imodesuffix>}\t{%2, %0|%0, %2} + add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2} + add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "isa" "*,apx_ndd,apx_ndd") + (set_attr "type" "alu") (set_attr "mode" "<MODE>")]) (define_insn "*add<mode>3_cc_overflow_2" [(set (reg:CCC FLAGS_REG) (compare:CCC (plus:SWI - (match_operand:SWI 1 "nonimmediate_operand" "%0,0") - (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")) + (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,r") + (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>")) (match_dup 2))) - (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") + (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r") (plus:SWI (match_dup 1) (match_dup 2)))] - "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" - "add{<imodesuffix>}\t{%2, %0|%0, %2}" - [(set_attr "type" "alu") + "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)" + "@ + add{<imodesuffix>}\t{%2, %0|%0, %2} + add{<imodesuffix>}\t{%2, %0|%0, %2} + add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2} + add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "isa" "*,*,apx_ndd,apx_ndd") + (set_attr "type" "alu") (set_attr "mode" "<MODE>")]) (define_insn "*addsi3_zext_cc_overflow_2" [(set (reg:CCC FLAGS_REG) (compare:CCC (plus:SI - (match_operand:SI 1 "nonimmediate_operand" "%0") - (match_operand:SI 2 "x86_64_general_operand" "rBMe")) + (match_operand:SI 1 "nonimmediate_operand" "%0,r,rm") + (match_operand:SI 2 "x86_64_general_operand" "rBMe,rBMe,re")) (match_dup 2))) - (set (match_operand:DI 0 "register_operand" "=r") + (set (match_operand:DI 0 "register_operand" "=r,r,r") (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] - "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" - "add{l}\t{%2, %k0|%k0, %2}" - [(set_attr "type" "alu") + "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands, + TARGET_APX_NDD)" + "@ + add{l}\t{%2, %k0|%k0, %2} + add{l}\t{%2, %1, %k0|%k0, %1, %2} + add{l}\t{%2, %1, %k0|%k0, %1, %2}" + [(set_attr "isa" "*,apx_ndd,apx_ndd") + (set_attr "type" "alu") (set_attr "mode" "SI")]) (define_insn_and_split "*add<dwi>3_doubleword_cc_overflow_1" diff --git a/gcc/testsuite/gcc.target/i386/apx-ndd.c b/gcc/testsuite/gcc.target/i386/apx-ndd.c index 056a323a647..c1049022f2a 100644 --- a/gcc/testsuite/gcc.target/i386/apx-ndd.c +++ b/gcc/testsuite/gcc.target/i386/apx-ndd.c @@ -2,20 +2,43 @@ /* { dg-options "-mapxf -march=x86-64 -O2" } */ /* { dg-final { scan-assembler-not "movl"} } */ -int foo (int *a) -{ - int b = *a - 1; - return b; -} +#define FOO(TYPE, OP_NAME, OP) \ +TYPE \ +__attribute__ ((noipa)) \ +foo_##OP_NAME##_##TYPE (TYPE *a) \ +{ \ + TYPE b = *a OP 1; \ + return b; \ +} -int foo2 (int a, int b) -{ - int c = a + b; - return c; -} +#define FOO1(TYPE, OP_NAME, OP) \ +TYPE \ +__attribute__ ((noipa)) \ +foo1_##OP_NAME##_##TYPE (TYPE a, TYPE b) \ +{ \ + TYPE c = a OP b; \ + return c; \ +} + +#define FOO2(TYPE, OP_NAME, OP) \ +TYPE \ +__attribute__ ((noipa)) \ +foo2_##OP_NAME##_##TYPE (TYPE *a, TYPE b) \ +{ \ + TYPE c = *a OP b; \ + return c; \ +} + +FOO (char, add, +) +FOO1 (char, add, +) +FOO2 (char, add, +) +FOO (short, add, +) +FOO1 (short, add, +) +FOO2 (short, add, +) +FOO (int, add, +) +FOO1 (int, add, +) +FOO2 (int, add, +) +FOO (long, add, +) +FOO1 (long, add, +) +FOO2 (long, add, +) -int foo3 (int *a, int b) -{ - int c = *a + b; - return c; -} -- 2.31.1