aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorLingling Kong <lingling.kong@intel.com>2024-06-13 09:18:18 +0800
committerLingling Kong <lingling.kong@intel.com>2024-06-13 09:20:19 +0800
commit8a5d0d72ea8c324bbfa2cff1284fa8e473fc466d (patch)
treec61a35b13d352d940c89e05acbcd629a542e1bca /gcc
parent158ce8ade0a98443b8fc05cbdbed5c49ee8a13b7 (diff)
downloadgcc-8a5d0d72ea8c324bbfa2cff1284fa8e473fc466d.zip
gcc-8a5d0d72ea8c324bbfa2cff1284fa8e473fc466d.tar.gz
gcc-8a5d0d72ea8c324bbfa2cff1284fa8e473fc466d.tar.bz2
[APX ZU] Support APX zero-upper
Enable ZU for IMUL (opcodes 0x69 and 0x6B) and SETcc. gcc/ChangeLog: * config/i386/i386-opts.h (enum apx_features): Add apx_zu. * config/i386/i386.h (TARGET_APX_ZU): Define. * config/i386/i386.md (*imulhi<mode>zu): New define_insn. (*setcc_<mode>_zu): Ditto. * config/i386/i386.opt: Add enum value for zu. gcc/testsuite/ChangeLog: * gcc.target/i386/apx-zu-1.c: New test. * gcc.target/i386/apx-zu-2.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/i386/i386-opts.h3
-rw-r--r--gcc/config/i386/i386.h1
-rw-r--r--gcc/config/i386/i386.md25
-rw-r--r--gcc/config/i386/i386.opt3
-rw-r--r--gcc/testsuite/gcc.target/i386/apx-zu-1.c38
-rw-r--r--gcc/testsuite/gcc.target/i386/apx-zu-2.c19
6 files changed, 86 insertions, 3 deletions
diff --git a/gcc/config/i386/i386-opts.h b/gcc/config/i386/i386-opts.h
index 5fcc492..c7ec0d9 100644
--- a/gcc/config/i386/i386-opts.h
+++ b/gcc/config/i386/i386-opts.h
@@ -142,8 +142,9 @@ enum apx_features {
apx_ppx = 1 << 3,
apx_nf = 1 << 4,
apx_ccmp = 1 << 5,
+ apx_zu = 1 << 6,
apx_all = apx_egpr | apx_push2pop2 | apx_ndd
- | apx_ppx | apx_nf | apx_ccmp,
+ | apx_ppx | apx_nf | apx_ccmp | apx_zu,
};
#endif
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 7051c6c..dc1a1f4 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -57,6 +57,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define TARGET_APX_PPX (ix86_apx_features & apx_ppx)
#define TARGET_APX_NF (ix86_apx_features & apx_nf)
#define TARGET_APX_CCMP (ix86_apx_features & apx_ccmp)
+#define TARGET_APX_ZU (ix86_apx_features & apx_zu)
#include "config/vxworks-dummy.h"
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index a64f2ad..5fc2bae 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -10060,6 +10060,19 @@
(const_string "direct")))
(set_attr "mode" "<MODE>")])
+(define_insn "*imulhi<mode>zu"
+ [(set (match_operand:SWI48x 0 "register_operand" "=r,r")
+ (zero_extend:SWI48x
+ (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm")
+ (match_operand:HI 2 "immediate_operand" "K,n"))))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_APX_ZU"
+ "@
+ imulzu{w}\t{%2, %1, %w0|%w0, %1, %2}
+ imulzu{w}\t{%2, %1, %w0|%w0, %1, %2}"
+ [(set_attr "type" "imul")
+ (set_attr "mode" "HI")])
+
(define_insn "*mulsi3_1_zext"
[(set (match_operand:DI 0 "register_operand" "=r,r,r")
(zero_extend:DI
@@ -18447,11 +18460,19 @@
;; For all sCOND expanders, also expand the compare or test insn that
;; generates cc0. Generate an equality comparison if `seq' or `sne'.
+(define_insn "*setcc_<mode>_zu"
+ [(set (match_operand:SWI248 0 "register_operand" "=r")
+ (match_operator:SWI248 1 "ix86_comparison_operator"
+ [(reg FLAGS_REG) (const_int 0)]))]
+ "TARGET_APX_ZU"
+ "setzu%C1\t%b0"
+ [(set_attr "type" "setcc")])
+
(define_insn_and_split "*setcc_di_1"
[(set (match_operand:DI 0 "register_operand" "=q")
(match_operator:DI 1 "ix86_comparison_operator"
[(reg FLAGS_REG) (const_int 0)]))]
- "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
+ "!TARGET_APX_ZU && TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
"#"
"&& reload_completed"
[(set (match_dup 2) (match_dup 1))
@@ -18484,7 +18505,7 @@
[(set (match_operand:SWI24 0 "register_operand" "=q")
(match_operator:SWI24 1 "ix86_comparison_operator"
[(reg FLAGS_REG) (const_int 0)]))]
- "!TARGET_PARTIAL_REG_STALL
+ "!TARGET_APX_ZU && !TARGET_PARTIAL_REG_STALL
&& (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
"#"
"&& reload_completed"
diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
index 7017cc8..353fffb 100644
--- a/gcc/config/i386/i386.opt
+++ b/gcc/config/i386/i386.opt
@@ -1343,6 +1343,9 @@ EnumValue
Enum(apx_features) String(ccmp) Value(apx_ccmp) Set(7)
EnumValue
+Enum(apx_features) String(zu) Value(apx_zu) Set(8)
+
+EnumValue
Enum(apx_features) String(all) Value(apx_all) Set(1)
mapx-inline-asm-use-gpr32
diff --git a/gcc/testsuite/gcc.target/i386/apx-zu-1.c b/gcc/testsuite/gcc.target/i386/apx-zu-1.c
new file mode 100644
index 0000000..927a876
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/apx-zu-1.c
@@ -0,0 +1,38 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-mapxf -march=x86-64 -O2" } */
+/* { dg-final { scan-assembler-not "setle"} } */
+/* { dg-final { scan-assembler-not "setge"} } */
+/* { dg-final { scan-assembler-not "sete"} } */
+/* { dg-final { scan-assembler-not "xor"} } */
+/* { dg-final { scan-assembler-times "setzune" 1} } */
+/* { dg-final { scan-assembler-times "setzule" 1} } */
+/* { dg-final { scan-assembler-times "setzue" 1} } */
+/* { dg-final { scan-assembler-times "setzuge" 1} } */
+/* { dg-final { scan-assembler "imulzu"} } */
+long long foo0 (int a)
+{
+ return a == 0 ? 0 : 1;
+}
+
+long foo1 (int a, int b)
+{
+ return a > b ? 0 : 1;
+}
+
+int foo2 (int a, int b)
+{
+ return a != b ? 0 : 1;
+}
+
+short foo3 (int a, int b)
+{
+ return a < b ? 0 : 1;
+}
+
+unsigned long
+f1(unsigned short x)
+{
+ unsigned short a;
+ a = x * 1000;
+ return a;
+}
diff --git a/gcc/testsuite/gcc.target/i386/apx-zu-2.c b/gcc/testsuite/gcc.target/i386/apx-zu-2.c
new file mode 100644
index 0000000..3ee0449
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/apx-zu-2.c
@@ -0,0 +1,19 @@
+/* { dg-do run { target { ! ia32 } } } */
+/* { dg-require-effective-target apxf } */
+/* { dg-options "-mapxf -march=x86-64 -O2" } */
+#include "apx-zu-1.c"
+
+int main(void)
+{
+ if (foo0 (0))
+ __builtin_abort ();
+ if (foo1 (3, 2))
+ __builtin_abort ();
+ if (foo2 (3, 2))
+ __builtin_abort ();
+ if (foo3 (2, 3))
+ __builtin_abort ();
+ if (f1 (2) != 2000)
+ __builtin_abort ();
+ return 0;
+}