aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorliuhongt <hongtao.liu@intel.com>2020-08-04 10:00:13 +0800
committerGiuliano Belinassi <giuliano.belinassi@usp.br>2020-08-17 15:08:16 -0300
commit3c8620f572c60a37f8334067025eca072e096018 (patch)
tree693bef15734860b24f2f8b8127ac9ad213a41615
parent0b958ddad526f921122097aa9f07b2489ba00efe (diff)
downloadgcc-3c8620f572c60a37f8334067025eca072e096018.zip
gcc-3c8620f572c60a37f8334067025eca072e096018.tar.gz
gcc-3c8620f572c60a37f8334067025eca072e096018.tar.bz2
Force ENDBR immediate into memory.
gcc/ PR target/96350 * config/i386/i386.c (ix86_legitimate_constant_p): Return false for ENDBR immediate. (ix86_legitimate_address_p): Ditto. * config/i386/predicates.md (x86_64_immediate_operand): Exclude ENDBR immediate. (x86_64_zext_immediate_operand): Ditto. (x86_64_dwzext_immediate_operand): Ditto. (ix86_endbr_immediate_operand): New predicate. gcc/testsuite * gcc.target/i386/endbr_immediate.c: New test.
-rw-r--r--gcc/config/i386/i386.c6
-rw-r--r--gcc/config/i386/predicates.md31
-rw-r--r--gcc/testsuite/gcc.target/i386/endbr_immediate.c198
3 files changed, 235 insertions, 0 deletions
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 10eb2dd..e9ecb94 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -10056,6 +10056,9 @@ ix86_legitimate_constant_p (machine_mode mode, rtx x)
break;
CASE_CONST_SCALAR_INT:
+ if (ix86_endbr_immediate_operand (x, VOIDmode))
+ return false;
+
switch (mode)
{
case E_TImode:
@@ -10449,6 +10452,9 @@ ix86_legitimate_address_p (machine_mode, rtx addr, bool strict)
/* Validate displacement. */
if (disp)
{
+ if (ix86_endbr_immediate_operand (disp, VOIDmode))
+ return false;
+
if (GET_CODE (disp) == CONST
&& GET_CODE (XEXP (disp, 0)) == UNSPEC
&& XINT (XEXP (disp, 0), 1) != UNSPEC_MACHOPIC_OFFSET)
diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
index 07e69d5..2850f80 100644
--- a/gcc/config/i386/predicates.md
+++ b/gcc/config/i386/predicates.md
@@ -130,10 +130,35 @@
(define_predicate "symbol_operand"
(match_code "symbol_ref"))
+;; Return true if VALUE is an ENDBR opcode in immediate field.
+(define_predicate "ix86_endbr_immediate_operand"
+ (match_code "const_int")
+{
+ if (flag_cf_protection & CF_BRANCH)
+ {
+ unsigned HOST_WIDE_INT imm = UINTVAL (op);
+ unsigned HOST_WIDE_INT val = TARGET_64BIT ? 0xfa1e0ff3 : 0xfb1e0ff3;
+
+ if (imm == val)
+ return 1;
+
+ /* NB: Encoding is byte based. */
+ if (TARGET_64BIT)
+ for (; imm >= val; imm >>= 8)
+ if (imm == val)
+ return 1;
+ }
+
+ return 0;
+})
+
;; Return true if VALUE can be stored in a sign extended immediate field.
(define_predicate "x86_64_immediate_operand"
(match_code "const_int,symbol_ref,label_ref,const")
{
+ if (ix86_endbr_immediate_operand (op, VOIDmode))
+ return false;
+
if (!TARGET_64BIT)
return immediate_operand (op, mode);
@@ -260,6 +285,9 @@
(define_predicate "x86_64_zext_immediate_operand"
(match_code "const_int,symbol_ref,label_ref,const")
{
+ if (ix86_endbr_immediate_operand (op, VOIDmode))
+ return false;
+
switch (GET_CODE (op))
{
case CONST_INT:
@@ -374,6 +402,9 @@
(define_predicate "x86_64_dwzext_immediate_operand"
(match_code "const_int,const_wide_int")
{
+ if (ix86_endbr_immediate_operand (op, VOIDmode))
+ return false;
+
switch (GET_CODE (op))
{
case CONST_INT:
diff --git a/gcc/testsuite/gcc.target/i386/endbr_immediate.c b/gcc/testsuite/gcc.target/i386/endbr_immediate.c
new file mode 100644
index 0000000..3015512
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/endbr_immediate.c
@@ -0,0 +1,198 @@
+/* PR target/96350 */
+/* { dg-do compile } */
+/* { dg-options "-fcf-protection -O2" } */
+/* { dg-final { scan-assembler-not "$-81915917" { target { ia32 } } } } */
+/* { dg-final { scan-assembler-not "$-98693133" { target { ! ia32 } } } } *
+/* { dg-final { scan-assembler-not "$-423883778574778368" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "\[ \t\]*-81915917" { target { ia32 } } } } */
+/* { dg-final { scan-assembler "\[ \t\]*-98693133" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "\[ \t\]*-423883778574778368" { target { ! ia32 } } } } */
+
+
+#ifdef __x86_64__
+#define ENDBR_IMMEDIATE 0xfa1e0ff3
+#define EXTEND_ENDBR_IMMEDIATE 0xfa1e0ff300000000
+#else
+#define ENDBR_IMMEDIATE 0xfb1e0ff3
+#define EXTEND_ENDBR_IMMEDIATE 0xfffb1e0ff300
+#endif
+
+int
+foo (int a)
+{
+ return a + ENDBR_IMMEDIATE;
+}
+
+int
+foo2 (int a)
+{
+ return a - ENDBR_IMMEDIATE;
+}
+
+int
+foo3 (int a)
+{
+ return a * ENDBR_IMMEDIATE;
+}
+
+int
+foo4 (int a)
+{
+ return a | ENDBR_IMMEDIATE;
+}
+
+int
+foo5 (int a)
+{
+ return a ^ ENDBR_IMMEDIATE;
+}
+
+int
+foo6 (int a)
+{
+ return a & ENDBR_IMMEDIATE;
+}
+
+int
+foo7 (int a)
+{
+ return a > ENDBR_IMMEDIATE;
+}
+
+int
+foo8 (int a)
+{
+ return ENDBR_IMMEDIATE;
+}
+
+int
+foo9 (int* p)
+{
+ return *(p + ENDBR_IMMEDIATE);
+}
+
+int
+foo10 (int* p)
+{
+ return *(int*) ENDBR_IMMEDIATE;
+}
+
+long long
+foo11 (long long a)
+{
+ return a + EXTEND_ENDBR_IMMEDIATE;
+}
+
+long long
+foo12 (long long a)
+{
+ return a - EXTEND_ENDBR_IMMEDIATE;
+}
+
+long long
+foo13 (long long a)
+{
+ return a * EXTEND_ENDBR_IMMEDIATE;
+}
+
+long long
+foo14 (long long a)
+{
+ return a | EXTEND_ENDBR_IMMEDIATE;
+}
+
+long long
+foo15 (long long a)
+{
+ return a ^ EXTEND_ENDBR_IMMEDIATE;
+}
+
+long long
+foo16 (long long a)
+{
+ return a & EXTEND_ENDBR_IMMEDIATE;
+}
+
+long long
+foo17 (long long a)
+{
+ return a > EXTEND_ENDBR_IMMEDIATE;
+}
+
+long long
+foo18 (long long a)
+{
+ return EXTEND_ENDBR_IMMEDIATE;
+}
+
+long long
+foo19 (long long* p)
+{
+ return *(p + EXTEND_ENDBR_IMMEDIATE);
+}
+
+long long
+foo20 (long long* p)
+{
+ return *(long long*) EXTEND_ENDBR_IMMEDIATE;
+}
+
+long long
+foo21 (int a)
+{
+ return a + ENDBR_IMMEDIATE;
+}
+
+long long
+foo22 (int a)
+{
+ return a - ENDBR_IMMEDIATE;
+}
+
+long long
+foo23 (long long a)
+{
+ return a * ENDBR_IMMEDIATE;
+}
+
+long long
+foo24 (int a)
+{
+ return a | ENDBR_IMMEDIATE;
+}
+
+long long
+foo25 (int a)
+{
+ return a ^ ENDBR_IMMEDIATE;
+}
+
+long long
+foo26 (int a)
+{
+ return a & ENDBR_IMMEDIATE;
+}
+
+long long
+foo27 (int a)
+{
+ return a > ENDBR_IMMEDIATE;
+}
+
+long long
+foo28 (int a)
+{
+ return ENDBR_IMMEDIATE;
+}
+
+long long
+foo29 (int* p)
+{
+ return *(p + ENDBR_IMMEDIATE);
+}
+
+long long
+foo30 (int* p)
+{
+ return *(long long*) ENDBR_IMMEDIATE;
+}