aboutsummaryrefslogtreecommitdiff
path: root/libgcc
diff options
context:
space:
mode:
authorMaxim Kuvyrkov <maxim.kuvyrkov@linaro.org>2018-04-25 13:47:35 +0000
committerMaxim Kuvyrkov <maxim.kuvyrkov@linaro.org>2018-04-25 13:47:35 +0000
commit3abf97fef8148d7ac80769db30d5d9373275d286 (patch)
treecca40c52a874df838dd0a9c8d122bc5196a4584c /libgcc
parent998285928828fb45028c187dbc59d3968586d89d (diff)
Merge branches/gcc-6-branch rev 259634.
Change-Id: I7b52b8f2a04e93123094009da7895d55238b03ef
Diffstat (limited to 'libgcc')
-rw-r--r--libgcc/ChangeLog26
-rw-r--r--libgcc/config/i386/cpuinfo.c102
-rw-r--r--libgcc/config/pa/fptr.c20
3 files changed, 120 insertions, 28 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index bd37acf21c2..df5e7a44659 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,29 @@
+2018-04-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ Backport from mainline
+ 2018-03-29 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/85100
+ * config/i386/cpuinfo.c (XCR_XFEATURE_ENABLED_MASK): New.
+ (XSTATE_FP): Likewise.
+ (XSTATE_SSE): Likewise.
+ (XSTATE_YMM): Likewise.
+ (XSTATE_OPMASK): Likewise.
+ (XSTATE_ZMM): Likewise.
+ (XSTATE_HI_ZMM): Likewise.
+ (XCR_AVX_ENABLED_MASK): Likewise.
+ (XCR_AVX512F_ENABLED_MASK): Likewise.
+ (get_available_features): Enable AVX and AVX512 features only
+ if their states are supported by OSXSAVE.
+
+2018-03-11 John David Anglin <danglin@gcc.gnu.org>
+
+ Backport from mainline
+ 2018-03-06 John David Anglin <danglin@gcc.gnu.org>
+
+ * config/pa/fptr.c (_dl_read_access_allowed): New.
+ (__canonicalize_funcptr_for_compare): Use it.
+
2018-02-20 Max Filippov <jcmvbkbc@gmail.com>
Backport from mainline
diff --git a/libgcc/config/i386/cpuinfo.c b/libgcc/config/i386/cpuinfo.c
index 8c2248df3d3..0886b836292 100644
--- a/libgcc/config/i386/cpuinfo.c
+++ b/libgcc/config/i386/cpuinfo.c
@@ -303,6 +303,40 @@ get_available_features (unsigned int ecx, unsigned int edx,
{
unsigned int features = 0;
+ /* Get XCR_XFEATURE_ENABLED_MASK register with xgetbv. */
+#define XCR_XFEATURE_ENABLED_MASK 0x0
+#define XSTATE_FP 0x1
+#define XSTATE_SSE 0x2
+#define XSTATE_YMM 0x4
+#define XSTATE_OPMASK 0x20
+#define XSTATE_ZMM 0x40
+#define XSTATE_HI_ZMM 0x80
+
+#define XCR_AVX_ENABLED_MASK \
+ (XSTATE_SSE | XSTATE_YMM)
+#define XCR_AVX512F_ENABLED_MASK \
+ (XSTATE_SSE | XSTATE_YMM | XSTATE_OPMASK | XSTATE_ZMM | XSTATE_HI_ZMM)
+
+ /* Check if AVX and AVX512 are usable. */
+ int avx_usable = 0;
+ int avx512_usable = 0;
+ if ((ecx & bit_OSXSAVE))
+ {
+ /* Check if XMM, YMM, OPMASK, upper 256 bits of ZMM0-ZMM15 and
+ ZMM16-ZMM31 states are supported by OSXSAVE. */
+ unsigned int xcrlow;
+ unsigned int xcrhigh;
+ asm (".byte 0x0f, 0x01, 0xd0"
+ : "=a" (xcrlow), "=d" (xcrhigh)
+ : "c" (XCR_XFEATURE_ENABLED_MASK));
+ if ((xcrlow & XCR_AVX_ENABLED_MASK) == XCR_AVX_ENABLED_MASK)
+ {
+ avx_usable = 1;
+ avx512_usable = ((xcrlow & XCR_AVX512F_ENABLED_MASK)
+ == XCR_AVX512F_ENABLED_MASK);
+ }
+ }
+
if (edx & bit_CMOV)
features |= (1 << FEATURE_CMOV);
if (edx & bit_MMX)
@@ -325,10 +359,13 @@ get_available_features (unsigned int ecx, unsigned int edx,
features |= (1 << FEATURE_SSE4_1);
if (ecx & bit_SSE4_2)
features |= (1 << FEATURE_SSE4_2);
- if (ecx & bit_AVX)
- features |= (1 << FEATURE_AVX);
- if (ecx & bit_FMA)
- features |= (1 << FEATURE_FMA);
+ if (avx_usable)
+ {
+ if (ecx & bit_AVX)
+ features |= (1 << FEATURE_AVX);
+ if (ecx & bit_FMA)
+ features |= (1 << FEATURE_FMA);
+ }
/* Get Advanced Features at level 7 (eax = 7, ecx = 0). */
if (max_cpuid_level >= 7)
@@ -337,28 +374,34 @@ get_available_features (unsigned int ecx, unsigned int edx,
__cpuid_count (7, 0, eax, ebx, ecx, edx);
if (ebx & bit_BMI)
features |= (1 << FEATURE_BMI);
- if (ebx & bit_AVX2)
- features |= (1 << FEATURE_AVX2);
+ if (avx_usable)
+ {
+ if (ebx & bit_AVX2)
+ features |= (1 << FEATURE_AVX2);
+ }
if (ebx & bit_BMI2)
features |= (1 << FEATURE_BMI2);
- if (ebx & bit_AVX512F)
- features |= (1 << FEATURE_AVX512F);
- if (ebx & bit_AVX512VL)
- features |= (1 << FEATURE_AVX512VL);
- if (ebx & bit_AVX512BW)
- features |= (1 << FEATURE_AVX512BW);
- if (ebx & bit_AVX512DQ)
- features |= (1 << FEATURE_AVX512DQ);
- if (ebx & bit_AVX512CD)
- features |= (1 << FEATURE_AVX512CD);
- if (ebx & bit_AVX512PF)
- features |= (1 << FEATURE_AVX512PF);
- if (ebx & bit_AVX512ER)
- features |= (1 << FEATURE_AVX512ER);
- if (ebx & bit_AVX512IFMA)
- features |= (1 << FEATURE_AVX512IFMA);
- if (ecx & bit_AVX512VBMI)
- features |= (1 << FEATURE_AVX512VBMI);
+ if (avx512_usable)
+ {
+ if (ebx & bit_AVX512F)
+ features |= (1 << FEATURE_AVX512F);
+ if (ebx & bit_AVX512VL)
+ features |= (1 << FEATURE_AVX512VL);
+ if (ebx & bit_AVX512BW)
+ features |= (1 << FEATURE_AVX512BW);
+ if (ebx & bit_AVX512DQ)
+ features |= (1 << FEATURE_AVX512DQ);
+ if (ebx & bit_AVX512CD)
+ features |= (1 << FEATURE_AVX512CD);
+ if (ebx & bit_AVX512PF)
+ features |= (1 << FEATURE_AVX512PF);
+ if (ebx & bit_AVX512ER)
+ features |= (1 << FEATURE_AVX512ER);
+ if (ebx & bit_AVX512IFMA)
+ features |= (1 << FEATURE_AVX512IFMA);
+ if (ecx & bit_AVX512VBMI)
+ features |= (1 << FEATURE_AVX512VBMI);
+ }
}
unsigned int ext_level;
@@ -372,10 +415,13 @@ get_available_features (unsigned int ecx, unsigned int edx,
if (ecx & bit_SSE4a)
features |= (1 << FEATURE_SSE4_A);
- if (ecx & bit_FMA4)
- features |= (1 << FEATURE_FMA4);
- if (ecx & bit_XOP)
- features |= (1 << FEATURE_XOP);
+ if (avx_usable)
+ {
+ if (ecx & bit_FMA4)
+ features |= (1 << FEATURE_FMA4);
+ if (ecx & bit_XOP)
+ features |= (1 << FEATURE_XOP);
+ }
}
__cpu_model.__cpu_features[0] = features;
diff --git a/libgcc/config/pa/fptr.c b/libgcc/config/pa/fptr.c
index 3febc9062db..761b98fa364 100644
--- a/libgcc/config/pa/fptr.c
+++ b/libgcc/config/pa/fptr.c
@@ -52,6 +52,16 @@ typedef int (*fptr_t) (void);
typedef int (*fixup_t) (struct link_map *, unsigned int);
extern unsigned int _GLOBAL_OFFSET_TABLE_;
+static inline int
+_dl_read_access_allowed (unsigned int *addr)
+{
+ int result;
+
+ asm ("proberi (%1),3,%0" : "=r" (result) : "r" (addr) : );
+
+ return result;
+}
+
/* __canonicalize_funcptr_for_compare must be hidden so that it is not
placed in the dynamic symbol table. Like millicode functions, it
must be linked into all binaries in order access the got table of
@@ -82,6 +92,16 @@ __canonicalize_funcptr_for_compare (fptr_t fptr)
The second word in the plabel contains the relocation offset for the
function. */
plabel = (unsigned int *) ((unsigned int) fptr & ~3);
+ if (!_dl_read_access_allowed (plabel))
+ return (unsigned int) fptr;
+
+ /* Load first word of candidate descriptor. It should be a pointer
+ with word alignment and point to memory that can be read. */
+ got = (unsigned int *) plabel[0];
+ if (((unsigned int) got & 3) != 0
+ || !_dl_read_access_allowed (got))
+ return (unsigned int) fptr;
+
got = (unsigned int *) (plabel[0] + GOT_FROM_PLT_STUB);
/* Return the address of the function if the plabel has been resolved. */