From: Hongyu Wang <hongyu.wang@intel.com>
To: gcc-patches@gcc.gnu.org
Cc: ubizjak@gmail.com, hongtao.liu@intel.com
Subject: [PATCH 13/16] [APX NDD] Support APX NDD for right shift insns
Date: Wed, 15 Nov 2023 17:47:02 +0800 [thread overview]
Message-ID: <20231115094705.3976553-14-hongyu.wang@intel.com> (raw)
In-Reply-To: <20231115094705.3976553-1-hongyu.wang@intel.com>
Similar to LSHIFT, rshift should also emit $1 for NDD form with CX_REG as
operands[1].
gcc/ChangeLog:
* config/i386/i386-expand.cc (ix86_can_use_ndd_p): Add LSHIFTRT
and RSHIFTRT.
* config/i386/i386.md (ashr<mode>3_cvt): Extend with new
alternatives to support NDD, and adjust output templates.
(*ashrsi3_cvt_zext): Likewise.
(*ashr<mode>3_1): Likewise for SI/DI mode.
(*highpartdisi2): Likewise.
(*lshr<mode>3_1): Likewise.
(*<insn>si3_1_zext): Likewise.
(*ashr<mode>3_1): Likewise for QI/HI mode.
(*lshrqi3_1): Likewise.
(*lshrhi3_1): Likewise.
(<insn><mode>3_cmp): Likewise.
(*<insn>si3_cmp_zext): Likewise.
(*<insn><mode>3_cconly): Likewise.
gcc/testsuite/ChangeLog:
* gcc.target/i386/apx-ndd.c: Add l/ashiftrt tests.
---
gcc/config/i386/i386-expand.cc | 2 +
gcc/config/i386/i386.md | 265 +++++++++++++++---------
gcc/testsuite/gcc.target/i386/apx-ndd.c | 24 +++
3 files changed, 191 insertions(+), 100 deletions(-)
diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
index 7e3080482a6..8e040346fbb 100644
--- a/gcc/config/i386/i386-expand.cc
+++ b/gcc/config/i386/i386-expand.cc
@@ -1277,6 +1277,8 @@ bool ix86_can_use_ndd_p (enum rtx_code code)
case IOR:
case XOR:
case ASHIFT:
+ case ASHIFTRT:
+ case LSHIFTRT:
return true;
default:
return false;
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index a0e81545f17..3ff333d4a41 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -15490,39 +15490,45 @@ (define_mode_attr cvt_mnemonic
[(SI "{cltd|cdq}") (DI "{cqto|cqo}")])
(define_insn "ashr<mode>3_cvt"
- [(set (match_operand:SWI48 0 "nonimmediate_operand" "=*d,rm")
+ [(set (match_operand:SWI48 0 "nonimmediate_operand" "=*d,rm,r")
(ashiftrt:SWI48
- (match_operand:SWI48 1 "nonimmediate_operand" "*a,0")
+ (match_operand:SWI48 1 "nonimmediate_operand" "*a,0,rm")
(match_operand:QI 2 "const_int_operand")))
(clobber (reg:CC FLAGS_REG))]
"INTVAL (operands[2]) == GET_MODE_BITSIZE (<MODE>mode)-1
&& (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
- && ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
+ && ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands,
+ ix86_can_use_ndd_p (ASHIFTRT))"
"@
<cvt_mnemonic>
- sar{<imodesuffix>}\t{%2, %0|%0, %2}"
- [(set_attr "type" "imovx,ishift")
- (set_attr "prefix_0f" "0,*")
- (set_attr "length_immediate" "0,*")
- (set_attr "modrm" "0,1")
+ sar{<imodesuffix>}\t{%2, %0|%0, %2}
+ sar{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+ [(set_attr "isa" "*,*,apx_ndd")
+ (set_attr "type" "imovx,ishift,ishift")
+ (set_attr "prefix_0f" "0,*,*")
+ (set_attr "length_immediate" "0,*,*")
+ (set_attr "modrm" "0,1,1")
(set_attr "mode" "<MODE>")])
(define_insn "*ashrsi3_cvt_zext"
- [(set (match_operand:DI 0 "register_operand" "=*d,r")
+ [(set (match_operand:DI 0 "register_operand" "=*d,r,r")
(zero_extend:DI
- (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
+ (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0,r")
(match_operand:QI 2 "const_int_operand"))))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT && INTVAL (operands[2]) == 31
&& (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
- && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
+ && ix86_binary_operator_ok (ASHIFTRT, SImode, operands,
+ ix86_can_use_ndd_p (ASHIFTRT))"
"@
{cltd|cdq}
- sar{l}\t{%2, %k0|%k0, %2}"
- [(set_attr "type" "imovx,ishift")
- (set_attr "prefix_0f" "0,*")
- (set_attr "length_immediate" "0,*")
- (set_attr "modrm" "0,1")
+ sar{l}\t{%2, %k0|%k0, %2}
+ sar{l}\t{%2, %1, %k0|%k0, %1, %2}"
+ [(set_attr "isa" "*,*,apx_ndd")
+ (set_attr "type" "imovx,ishift,ishift")
+ (set_attr "prefix_0f" "0,*,*")
+ (set_attr "length_immediate" "0,*,*")
+ (set_attr "modrm" "0,1,1")
(set_attr "mode" "SI")])
(define_expand "@x86_shift<mode>_adj_3"
@@ -15564,13 +15570,15 @@ (define_insn "*bmi2_<insn><mode>3_1"
(set_attr "mode" "<MODE>")])
(define_insn "*ashr<mode>3_1"
- [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
+ [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
(ashiftrt:SWI48
- (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
- (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
+ (match_operand:SWI48 1 "nonimmediate_operand" "0,rm,rm")
+ (match_operand:QI 2 "nonmemory_operand" "c<S>,r,c<S>")))
(clobber (reg:CC FLAGS_REG))]
- "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
+ "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands,
+ ix86_can_use_ndd_p (ASHIFTRT))"
{
+ bool use_ndd = (which_alternative == 2);
switch (get_attr_type (insn))
{
case TYPE_ISHIFTX:
@@ -15578,14 +15586,18 @@ (define_insn "*ashr<mode>3_1"
default:
if (operands[2] == const1_rtx
- && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
- return "sar{<imodesuffix>}\t%0";
+ && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
+ && !(use_ndd && REG_P (operands[1])
+ && REGNO (operands[1]) == CX_REG))
+ return use_ndd ? "sar{<imodesuffix>}\t{%1, %0|%0, %1}"
+ : "sar{<imodesuffix>}\t%0";
else
- return "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
+ return use_ndd ? "sar{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+ : "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
}
}
- [(set_attr "isa" "*,bmi2")
- (set_attr "type" "ishift,ishiftx")
+ [(set_attr "isa" "*,bmi2,apx_ndd")
+ (set_attr "type" "ishift,ishiftx,ishift")
(set (attr "length_immediate")
(if_then_else
(and (match_operand 2 "const1_operand")
@@ -15598,8 +15610,8 @@ (define_insn "*ashr<mode>3_1"
;; Specialization of *lshr<mode>3_1 below, extracting the SImode
;; highpart of a DI to be extracted, but allowing it to be clobbered.
(define_insn_and_split "*highpartdisi2"
- [(set (subreg:DI (match_operand:SI 0 "register_operand" "=r,x,?k") 0)
- (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0,k")
+ [(set (subreg:DI (match_operand:SI 0 "register_operand" "=r,x,?k,r") 0)
+ (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0,k,r")
(const_int 32)))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT"
@@ -15618,16 +15630,20 @@ (define_insn_and_split "*highpartdisi2"
DONE;
}
operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
-})
+}
+[(set_attr "isa" "*,*,*,apx_ndd")])
+
(define_insn "*lshr<mode>3_1"
- [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,?k")
+ [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,?k,r")
(lshiftrt:SWI48
- (match_operand:SWI48 1 "nonimmediate_operand" "0,rm,k")
- (match_operand:QI 2 "nonmemory_operand" "c<S>,r,<KS>")))
+ (match_operand:SWI48 1 "nonimmediate_operand" "0,rm,k,rm")
+ (match_operand:QI 2 "nonmemory_operand" "c<S>,r,<KS>,c<S>")))
(clobber (reg:CC FLAGS_REG))]
- "ix86_binary_operator_ok (LSHIFTRT, <MODE>mode, operands)"
+ "ix86_binary_operator_ok (LSHIFTRT, <MODE>mode, operands,
+ ix86_can_use_ndd_p (LSHIFTRT))"
{
+ bool use_ndd = (which_alternative == 3);
switch (get_attr_type (insn))
{
case TYPE_ISHIFTX:
@@ -15636,14 +15652,18 @@ (define_insn "*lshr<mode>3_1"
default:
if (operands[2] == const1_rtx
- && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
- return "shr{<imodesuffix>}\t%0";
+ && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
+ && !(use_ndd && REG_P (operands[1])
+ && REGNO (operands[1]) == CX_REG))
+ return use_ndd ? "shr{<imodesuffix>}\t{%1, %0|%0, %1}"
+ : "shr{<imodesuffix>}\t%0";
else
- return "shr{<imodesuffix>}\t{%2, %0|%0, %2}";
+ return use_ndd ? "shr{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+ : "shr{<imodesuffix>}\t{%2, %0|%0, %2}";
}
}
- [(set_attr "isa" "*,bmi2,<kmov_isa>")
- (set_attr "type" "ishift,ishiftx,msklog")
+ [(set_attr "isa" "*,bmi2,<kmov_isa>,apx_ndd")
+ (set_attr "type" "ishift,ishiftx,msklog,ishift")
(set (attr "length_immediate")
(if_then_else
(and (and (match_operand 2 "const1_operand")
@@ -15676,13 +15696,15 @@ (define_insn "*bmi2_<insn>si3_1_zext"
(set_attr "mode" "SI")])
(define_insn "*<insn>si3_1_zext"
- [(set (match_operand:DI 0 "register_operand" "=r,r")
+ [(set (match_operand:DI 0 "register_operand" "=r,r,r")
(zero_extend:DI
- (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
- (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
+ (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm,rm")
+ (match_operand:QI 2 "nonmemory_operand" "cI,r,cI"))))
(clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
+ "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands,
+ ix86_can_use_ndd_p (<CODE>))"
{
+ bool use_ndd = (which_alternative == 2);
switch (get_attr_type (insn))
{
case TYPE_ISHIFTX:
@@ -15690,14 +15712,18 @@ (define_insn "*<insn>si3_1_zext"
default:
if (operands[2] == const1_rtx
- && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
- return "<shift>{l}\t%k0";
+ && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
+ && !(use_ndd && REG_P (operands[1])
+ && REGNO (operands[1]) == CX_REG))
+ return use_ndd ? "<shift>{l}\t{%1, %k0|%k0, %1}"
+ : "<shift>{l}\t%k0";
else
- return "<shift>{l}\t{%2, %k0|%k0, %2}";
+ return use_ndd ? "<shift>{l}\t{%2, %1, %k0|%k0, %1, %2}"
+ : "<shift>{l}\t{%2, %k0|%k0, %2}";
}
}
- [(set_attr "isa" "*,bmi2")
- (set_attr "type" "ishift,ishiftx")
+ [(set_attr "isa" "*,bmi2,apx_ndd")
+ (set_attr "type" "ishift,ishiftx,ishift")
(set (attr "length_immediate")
(if_then_else
(and (match_operand 2 "const1_operand")
@@ -15720,20 +15746,26 @@ (define_split
"operands[2] = gen_lowpart (SImode, operands[2]);")
(define_insn "*ashr<mode>3_1"
- [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
+ [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m, r")
(ashiftrt:SWI12
- (match_operand:SWI12 1 "nonimmediate_operand" "0")
- (match_operand:QI 2 "nonmemory_operand" "c<S>")))
+ (match_operand:SWI12 1 "nonimmediate_operand" "0, rm")
+ (match_operand:QI 2 "nonmemory_operand" "c<S>, c<S>")))
(clobber (reg:CC FLAGS_REG))]
- "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
+ "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands,
+ ix86_can_use_ndd_p (ASHIFTRT))"
{
if (operands[2] == const1_rtx
- && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
- return "sar{<imodesuffix>}\t%0";
+ && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
+ && !(which_alternative && REG_P (operands[1])
+ && REGNO (operands[1]) == CX_REG))
+ return which_alternative ? "sar{<imodesuffix>}\t{%1, %0|%0, %1}"
+ : "sar{<imodesuffix>}\t%0";
else
- return "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
+ return which_alternative ? "sar{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+ : "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
}
- [(set_attr "type" "ishift")
+ [(set_attr "isa" "*, apx_ndd")
+ (set_attr "type" "ishift")
(set (attr "length_immediate")
(if_then_else
(and (match_operand 2 "const1_operand")
@@ -15744,29 +15776,35 @@ (define_insn "*ashr<mode>3_1"
(set_attr "mode" "<MODE>")])
(define_insn "*lshrqi3_1"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,?k")
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,?k,r")
(lshiftrt:QI
- (match_operand:QI 1 "nonimmediate_operand" "0, k")
- (match_operand:QI 2 "nonmemory_operand" "cI,Wb")))
+ (match_operand:QI 1 "nonimmediate_operand" "0, k, rm")
+ (match_operand:QI 2 "nonmemory_operand" "cI,Wb,cI")))
(clobber (reg:CC FLAGS_REG))]
- "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
+ "ix86_binary_operator_ok (LSHIFTRT, QImode, operands,
+ ix86_can_use_ndd_p (LSHIFTRT))"
{
+ bool use_ndd = (which_alternative == 2);
switch (get_attr_type (insn))
{
case TYPE_ISHIFT:
if (operands[2] == const1_rtx
- && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
- return "shr{b}\t%0";
+ && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
+ && !(use_ndd && REG_P (operands[1])
+ && REGNO (operands[1]) == CX_REG))
+ return use_ndd ? "shr{b}\t{%1, %0|%0, %1}"
+ : "shr{b}\t%0";
else
- return "shr{b}\t{%2, %0|%0, %2}";
+ return use_ndd ? "shr{b}\t{%2, %1, %0|%0, %1, %2}"
+ : "shr{b}\t{%2, %0|%0, %2}";
case TYPE_MSKLOG:
return "#";
default:
gcc_unreachable ();
}
}
- [(set_attr "isa" "*,avx512dq")
- (set_attr "type" "ishift,msklog")
+ [(set_attr "isa" "*,avx512dq,apx_ndd")
+ (set_attr "type" "ishift,msklog,ishift")
(set (attr "length_immediate")
(if_then_else
(and (and (match_operand 2 "const1_operand")
@@ -15778,29 +15816,35 @@ (define_insn "*lshrqi3_1"
(set_attr "mode" "QI")])
(define_insn "*lshrhi3_1"
- [(set (match_operand:HI 0 "nonimmediate_operand" "=rm, ?k")
+ [(set (match_operand:HI 0 "nonimmediate_operand" "=rm, ?k, r")
(lshiftrt:HI
- (match_operand:HI 1 "nonimmediate_operand" "0, k")
- (match_operand:QI 2 "nonmemory_operand" "cI, Ww")))
+ (match_operand:HI 1 "nonimmediate_operand" "0, k, rm")
+ (match_operand:QI 2 "nonmemory_operand" "cI, Ww, cI")))
(clobber (reg:CC FLAGS_REG))]
- "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
+ "ix86_binary_operator_ok (LSHIFTRT, HImode, operands,
+ ix86_can_use_ndd_p (LSHIFTRT))"
{
+ bool use_ndd = (which_alternative == 2);
switch (get_attr_type (insn))
{
case TYPE_ISHIFT:
if (operands[2] == const1_rtx
- && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
- return "shr{w}\t%0";
+ && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
+ && !(use_ndd && REG_P (operands[1])
+ && REGNO (operands[1]) == CX_REG))
+ return use_ndd ? "shr{w}\t{%1, %0|%0, %1}"
+ : "shr{w}\t%0";
else
- return "shr{w}\t{%2, %0|%0, %2}";
+ return use_ndd ? "shr{w}\t{%2, %1, %0|%0, %1, %2}"
+ : "shr{w}\t{%2, %0|%0, %2}";
case TYPE_MSKLOG:
return "#";
default:
gcc_unreachable ();
}
}
- [(set_attr "isa" "*, avx512f")
- (set_attr "type" "ishift,msklog")
+ [(set_attr "isa" "*, avx512f, apx_ndd")
+ (set_attr "type" "ishift,msklog,ishift")
(set (attr "length_immediate")
(if_then_else
(and (and (match_operand 2 "const1_operand")
@@ -15853,25 +15897,31 @@ (define_insn "*<insn><mode>3_cmp"
[(set (reg FLAGS_REG)
(compare
(any_shiftrt:SWI
- (match_operand:SWI 1 "nonimmediate_operand" "0")
- (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
+ (match_operand:SWI 1 "nonimmediate_operand" "0,rm")
+ (match_operand:QI 2 "<shift_immediate_operand>" "<S>,<S>"))
(const_int 0)))
- (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
+ (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
(any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
"(optimize_function_for_size_p (cfun)
|| !TARGET_PARTIAL_FLAG_REG_STALL
|| (operands[2] == const1_rtx
&& TARGET_SHIFT1))
&& ix86_match_ccmode (insn, CCGOCmode)
- && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
+ && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands,
+ ix86_can_use_ndd_p (<CODE>))"
{
if (operands[2] == const1_rtx
- && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
- return "<shift>{<imodesuffix>}\t%0";
+ && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
+ && !(which_alternative && REG_P (operands[1])
+ && REGNO (operands[1]) == CX_REG))
+ return which_alternative ? "<shift>{<imodesuffix>}\t{%1, %0|%0, %1}"
+ : "<shift>{<imodesuffix>}\t%0";
else
- return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
+ return which_alternative ? "<shift>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+ : "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
}
- [(set_attr "type" "ishift")
+ [(set_attr "isa" "*,apx_ndd")
+ (set_attr "type" "ishift")
(set (attr "length_immediate")
(if_then_else
(and (match_operand 2 "const1_operand")
@@ -15884,10 +15934,10 @@ (define_insn "*<insn><mode>3_cmp"
(define_insn "*<insn>si3_cmp_zext"
[(set (reg FLAGS_REG)
(compare
- (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
+ (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0,r")
(match_operand:QI 2 "const_1_to_31_operand"))
(const_int 0)))
- (set (match_operand:DI 0 "register_operand" "=r")
+ (set (match_operand:DI 0 "register_operand" "=r,r")
(zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
"TARGET_64BIT
&& (optimize_function_for_size_p (cfun)
@@ -15895,15 +15945,20 @@ (define_insn "*<insn>si3_cmp_zext"
|| (operands[2] == const1_rtx
&& TARGET_SHIFT1))
&& ix86_match_ccmode (insn, CCGOCmode)
- && ix86_binary_operator_ok (<CODE>, SImode, operands)"
+ && ix86_binary_operator_ok (<CODE>, SImode, operands,
+ ix86_can_use_ndd_p (<CODE>))"
{
if (operands[2] == const1_rtx
- && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
- return "<shift>{l}\t%k0";
+ && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
+ && !(which_alternative && REGNO (operands[1]) == CX_REG))
+ return which_alternative ? "<shift>{l}\t{%1, %k0|%k0, %1}"
+ : "<shift>{l}\t%k0";
else
- return "<shift>{l}\t{%2, %k0|%k0, %2}";
+ return which_alternative ? "<shift>{l}\t{%2, %1, %k0|%k0, %1, %2}"
+ : "<shift>{l}\t{%2, %k0|%k0, %2}";
}
- [(set_attr "type" "ishift")
+ [(set_attr "isa" "*,apx_ndd")
+ (set_attr "type" "ishift")
(set (attr "length_immediate")
(if_then_else
(and (match_operand 2 "const1_operand")
@@ -15917,10 +15972,10 @@ (define_insn "*<insn><mode>3_cconly"
[(set (reg FLAGS_REG)
(compare
(any_shiftrt:SWI
- (match_operand:SWI 1 "register_operand" "0")
- (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
+ (match_operand:SWI 1 "register_operand" "0,r")
+ (match_operand:QI 2 "<shift_immediate_operand>" "<S>,<S>"))
(const_int 0)))
- (clobber (match_scratch:SWI 0 "=<r>"))]
+ (clobber (match_scratch:SWI 0 "=<r>,r"))]
"(optimize_function_for_size_p (cfun)
|| !TARGET_PARTIAL_FLAG_REG_STALL
|| (operands[2] == const1_rtx
@@ -15928,12 +15983,18 @@ (define_insn "*<insn><mode>3_cconly"
&& ix86_match_ccmode (insn, CCGOCmode)"
{
if (operands[2] == const1_rtx
- && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
- return "<shift>{<imodesuffix>}\t%0";
+ && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
+ && !(which_alternative && REGNO (operands[1]) == CX_REG))
+ return which_alternative
+ ? "<shift>{<imodesuffix>}\t{%1, %0|%0, %1}"
+ : "<shift>{<imodesuffix>}\t%0";
else
- return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
+ return which_alternative
+ ? "<shift>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+ : "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
}
- [(set_attr "type" "ishift")
+ [(set_attr "isa" "*,apx_ndd")
+ (set_attr "type" "ishift")
(set (attr "length_immediate")
(if_then_else
(and (match_operand 2 "const1_operand")
@@ -16537,18 +16598,22 @@ (define_insn "rcrdi2"
;; Versions of sar and shr that set the carry flag.
(define_insn "<insn><mode>3_carry"
[(set (reg:CCC FLAGS_REG)
- (unspec:CCC [(and:SWI48 (match_operand:SWI48 1 "register_operand" "0")
+ (unspec:CCC [(and:SWI48 (match_operand:SWI48 1 "register_operand" "0,r")
(const_int 1))
(const_int 0)] UNSPEC_CC_NE))
- (set (match_operand:SWI48 0 "register_operand" "=r")
+ (set (match_operand:SWI48 0 "register_operand" "=r,r")
(any_shiftrt:SWI48 (match_dup 1) (const_int 1)))]
""
{
- if (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
- return "<shift>{<imodesuffix>}\t%0";
- return "<shift>{<imodesuffix>}\t{1, %0|%0, 1}";
+ if ((TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
+ && !(which_alternative && REGNO (operands[1]) == CX_REG))
+ return which_alternative ? "<shift>{<imodesuffix>}\t{%1, %0|%0, %1}"
+ : "<shift>{<imodesuffix>}\t%0";
+ return which_alternative ? "<shift>{<imodesuffix>}\t{$1, %1, %0|%0, %1, 1}"
+ : "<shift>{<imodesuffix>}\t{$1, %0|%0, 1}";
}
- [(set_attr "type" "ishift1")
+ [(set_attr "isa" "*, apx_ndd")
+ (set_attr "type" "ishift1")
(set (attr "length_immediate")
(if_then_else
(ior (match_test "TARGET_SHIFT1")
diff --git a/gcc/testsuite/gcc.target/i386/apx-ndd.c b/gcc/testsuite/gcc.target/i386/apx-ndd.c
index 481ec8b00a8..28c0df72988 100644
--- a/gcc/testsuite/gcc.target/i386/apx-ndd.c
+++ b/gcc/testsuite/gcc.target/i386/apx-ndd.c
@@ -2,6 +2,8 @@
/* { dg-options "-mapxf -O2" } */
/* { dg-final { scan-assembler-not "movl"} } */
+#include <stdint.h>
+
#define FOO(TYPE, OP_NAME, OP) \
TYPE \
__attribute__ ((noipa)) \
@@ -132,6 +134,24 @@ FOO3 (int, shl, <<, 7)
FOO (long, shl, <<)
FOO3 (long, shl, <<, 7)
+FOO (char, sar, >>)
+FOO3 (char, sar, >>, 7)
+FOO (short, sar, >>)
+FOO3 (short, sar, >>, 7)
+FOO (int, sar, >>)
+FOO3 (int, sar, >>, 7)
+FOO (long, sar, >>)
+FOO3 (long, sar, >>, 7)
+
+FOO (uint8_t, shr, >>)
+FOO3 (uint8_t, shr, >>, 7)
+FOO (uint16_t, shr, >>)
+FOO3 (uint16_t, shr, >>, 7)
+FOO (uint32_t, shr, >>)
+FOO3 (uint32_t, shr, >>, 7)
+FOO (uint64_t, shr, >>)
+FOO3 (uint64_t, shr, >>, 7)
+
/* { dg-final { scan-assembler-times "add(?:l|w|q)\[^\n\r]*1, \\(%rdi\\), %(?:|r|e)ax" 4 } } */
/* { dg-final { scan-assembler-times "lea(?:l|q)\[^\n\r]\\(%r(?:d|s)i,%r(?:d|s)i\\), %(?:|r|e)ax" 4 } } */
/* { dg-final { scan-assembler-times "add(?:l|w|q)\[^\n\r]%(?:|r|e)si, \\(%rdi\\), %(?:|r|e)ax" 4 } } */
@@ -156,3 +176,7 @@ FOO3 (long, shl, <<, 7)
/* { dg-final { scan-assembler-times "xor(?:l|w|q)\[^\n\r]%(?:|r|e)si, %(?:|r|e)di, %(?:|r|e)ax" 2 } } */
/* { dg-final { scan-assembler-times "sal(?:l|w|q)\[^\n\r]\\(%rdi\\), %(?:|r|e)ax" 4 } } */
/* { dg-final { scan-assembler-times "sal(?:l|w|q)\[^\n\r]*7, %(?:|r|e)di, %(?:|r|e)ax" 4 } } */
+/* { dg-final { scan-assembler-times "sar(?:b|l|w|q)\[^\n\r]\\(%rdi\\), %(?:|r|e)a(?:x|l)" 4 } } */
+/* { dg-final { scan-assembler-times "sar(?:b|l|w|q)\[^\n\r]*7, %(?:|r|e)di(?:|l), %(?:|r|e)a(?:x|l)" 4 } } */
+/* { dg-final { scan-assembler-times "shr(?:b|l|w|q)\[^\n\r]\\(%rdi\\), %(?:|r|e)a(?:x|l)" 4 } } */
+/* { dg-final { scan-assembler-times "shr(?:b|l|w|q)\[^\n\r]*7, %(?:|r|e)di(?:|l), %(?:|r|e)a(?:x|l)" 4 } } */
--
2.31.1
next prev parent reply other threads:[~2023-11-15 9:47 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-11-15 9:46 [PATCH 00/16] Support Intel APX NDD Hongyu Wang
2023-11-15 9:46 ` [PATCH 01/16] [APX NDD] Support Intel APX NDD for legacy add insn Hongyu Wang
2023-11-15 9:46 ` [PATCH 02/16] [APX NDD] Restrict TImode register usage when NDD enabled Hongyu Wang
2023-11-15 9:46 ` [PATCH 03/16] [APX NDD] Support APX NDD for optimization patterns of add Hongyu Wang
2023-11-15 9:46 ` [PATCH 04/16] [APX NDD] Disable seg_prefixed memory usage for NDD add Hongyu Wang
2023-11-15 9:46 ` [PATCH 05/16] [APX NDD] Support APX NDD for adc insns Hongyu Wang
2023-11-15 9:46 ` [PATCH 06/16] [APX NDD] Support APX NDD for sub insns Hongyu Wang
2023-11-15 9:46 ` [PATCH 07/16] [APX NDD] Support APX NDD for sbb insn Hongyu Wang
2023-11-15 9:46 ` [PATCH 08/16] [APX NDD] Support APX NDD for neg insn Hongyu Wang
2023-11-15 9:46 ` [PATCH 09/16] [APX NDD] Support APX NDD for not insn Hongyu Wang
2023-11-15 9:46 ` [PATCH 10/16] [APX NDD] Support APX NDD for and insn Hongyu Wang
2023-11-15 9:47 ` [PATCH 11/16] [APX NDD] Support APX NDD for or/xor insn Hongyu Wang
2023-11-15 9:47 ` [PATCH 12/16] [APX NDD] Support APX NDD for left shift insns Hongyu Wang
2023-11-15 9:47 ` Hongyu Wang [this message]
2023-11-15 9:47 ` [PATCH 14/16] [APX NDD] Support APX NDD for rotate insns Hongyu Wang
2023-11-15 9:47 ` [PATCH 15/16] [APX NDD] Support APX NDD for shld/shrd insns Hongyu Wang
2023-11-15 9:47 ` [PATCH 16/16] [APX NDD] Support APX NDD for cmove insns Hongyu Wang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20231115094705.3976553-14-hongyu.wang@intel.com \
--to=hongyu.wang@intel.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=hongtao.liu@intel.com \
--cc=ubizjak@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).