From: liuhongt Date: Tue, 4 Aug 2020 02:00:13 +0000 (+0800) Subject: Force ENDBR immediate into memory. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9a5381f749ee2cef51af67895de182113e45f642;p=gcc.git 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. --- diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 10eb2dda3c7..e9ecb94d174 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 07e69d555c0..2850f80f71d 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 00000000000..3015512aa0e --- /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; +}