author | vromero |
Mon, 08 Oct 2018 06:52:41 -0700 | |
changeset 52038 | 957de5be48bc |
parent 49755 | 80e7764e4d09 |
child 59122 | 5d73255c2d52 |
permissions | -rw-r--r-- |
380 | 1 |
/* |
49755
80e7764e4d09
8201480: ISA/CPU feature detection code crashes on linux-sparc
glaubitz
parents:
47772
diff
changeset
|
2 |
* Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved. |
380 | 3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 |
* |
|
5 |
* This code is free software; you can redistribute it and/or modify it |
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
|
7 |
* published by the Free Software Foundation. |
|
8 |
* |
|
9 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
10 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
11 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
12 |
* version 2 for more details (a copy is included in the LICENSE file that |
|
13 |
* accompanied this code). |
|
14 |
* |
|
15 |
* You should have received a copy of the GNU General Public License version |
|
16 |
* 2 along with this work; if not, write to the Free Software Foundation, |
|
17 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
18 |
* |
|
5547
f4b087cbb361
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
670
diff
changeset
|
19 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
f4b087cbb361
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
670
diff
changeset
|
20 |
* or visit www.oracle.com if you need additional information or have any |
f4b087cbb361
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
670
diff
changeset
|
21 |
* questions. |
380 | 22 |
* |
23 |
*/ |
|
24 |
||
46666
32434b633549
8182163: Missing #include "logging/log.hpp" in vm_version_linux_sparc.cpp
ehelin
parents:
37430
diff
changeset
|
25 |
#include "logging/log.hpp" |
7397 | 26 |
#include "precompiled.hpp" |
27 |
#include "runtime/os.hpp" |
|
28 |
#include "vm_version_sparc.hpp" |
|
380 | 29 |
|
47772
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
30 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
31 |
#define CPUINFO_LINE_SIZE 1024 |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
32 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
33 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
34 |
class CPUinfo { |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
35 |
public: |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
36 |
CPUinfo(const char* field) : _string(NULL) { |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
37 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
38 |
char line[CPUINFO_LINE_SIZE]; |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
39 |
FILE* fp = fopen("/proc/cpuinfo", "r"); |
380 | 40 |
|
47772
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
41 |
if (fp != NULL) { |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
42 |
while (fgets(line, sizeof(line), fp) != NULL) { |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
43 |
assert(strlen(line) < sizeof(line) - 1, |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
44 |
"buffer too small (%d)", CPUINFO_LINE_SIZE); |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
45 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
46 |
const char* vstr = match_field(line, field); |
380 | 47 |
|
47772
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
48 |
if (vstr != NULL) { |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
49 |
// We have a matching line and a valid starting point to the value of |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
50 |
// the field, copy the string for keeps. |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
51 |
_string = strdup(vstr); |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
52 |
break; |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
53 |
} |
380 | 54 |
} |
47772
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
55 |
fclose(fp); |
380 | 56 |
} |
57 |
} |
|
58 |
||
49755
80e7764e4d09
8201480: ISA/CPU feature detection code crashes on linux-sparc
glaubitz
parents:
47772
diff
changeset
|
59 |
~CPUinfo() { free((void*)_string); } |
47772
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
60 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
61 |
const char* value() const { return _string; } |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
62 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
63 |
bool valid() const { return _string != NULL; } |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
64 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
65 |
bool match(const char* s) const { |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
66 |
return valid() ? strcmp(_string, s) == 0 : false; |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
67 |
} |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
68 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
69 |
private: |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
70 |
const char* _string; |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
71 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
72 |
const char* match_field(char line[CPUINFO_LINE_SIZE], const char* field); |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
73 |
const char* match_alo(const char* text, const char* exp); |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
74 |
const char* match_seq(const char* text, const char* seq); |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
75 |
}; |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
76 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
77 |
/* Given a line of text read from /proc/cpuinfo, determine if the property header |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
78 |
* matches the field specified, according to the following regexp: "<field>"\W+:\W+ |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
79 |
* |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
80 |
* If we have a matching expression, return a pointer to the first character after |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
81 |
* the matching pattern, i.e. the "value", otherwise return NULL. |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
82 |
*/ |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
83 |
const char* CPUinfo::match_field(char line[CPUINFO_LINE_SIZE], const char* field) { |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
84 |
return match_alo(match_seq(match_alo(match_seq(line, field), "\t "), ":"), "\t "); |
29210
f8d006dc2485
8062672: JVM crashes during GC on various asserts which checks that HeapWord ptr is an oop
sjohanss
parents:
25079
diff
changeset
|
85 |
} |
380 | 86 |
|
47772
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
87 |
/* Match a sequence of at-least-one character in the string expression (exp) to |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
88 |
* the text input. |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
89 |
*/ |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
90 |
const char* CPUinfo::match_alo(const char* text, const char* exp) { |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
91 |
if (text == NULL) return NULL; |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
92 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
93 |
const char* chp; |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
94 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
95 |
for (chp = &text[0]; *chp != '\0'; chp++) { |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
96 |
if (strchr(exp, *chp) == NULL) break; |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
97 |
} |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
98 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
99 |
return text < chp ? chp : NULL; |
29210
f8d006dc2485
8062672: JVM crashes during GC on various asserts which checks that HeapWord ptr is an oop
sjohanss
parents:
25079
diff
changeset
|
100 |
} |
f8d006dc2485
8062672: JVM crashes during GC on various asserts which checks that HeapWord ptr is an oop
sjohanss
parents:
25079
diff
changeset
|
101 |
|
47772
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
102 |
/* Match an exact sequence of characters as specified by the string expression |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
103 |
* (seq) to the text input. |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
104 |
*/ |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
105 |
const char* CPUinfo::match_seq(const char* text, const char* seq) { |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
106 |
if (text == NULL) return NULL; |
32605
dab0de4ff7ff
8134161: JVM is creating too many GC helper threads on T7/M7 linux/sparc platform
gthornbr
parents:
29210
diff
changeset
|
107 |
|
47772
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
108 |
while (*seq != '\0') { |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
109 |
if (*seq != *text++) break; else seq++; |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
110 |
} |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
111 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
112 |
return *seq == '\0' ? text : NULL; |
380 | 113 |
} |
114 |
||
47772
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
115 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
116 |
typedef struct { |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
117 |
const uint32_t hash; |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
118 |
bool seen; |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
119 |
const char* const name; |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
120 |
const uint64_t mask; |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
121 |
} FeatureEntry; |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
122 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
123 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
124 |
static uint64_t parse_features(FeatureEntry feature_tbl[], const char input[]); |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
125 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
126 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
127 |
void VM_Version::platform_features() { |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
128 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
129 |
// Some of the features reported via "cpucaps", such as; 'flush', 'stbar', |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
130 |
// 'swap', 'muldiv', 'ultra3', 'blkinit', 'n2', 'mul32', 'div32', 'fsmuld' |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
131 |
// and 'v8plus', are either SPARC V8, supported by all HW or simply nonsense |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
132 |
// (the 'ultra3' "property"). |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
133 |
// |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
134 |
// Entries marked as 'NYI' are not yet supported via "cpucaps" but are |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
135 |
// expected to have the names used in the table below (these are SPARC M7 |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
136 |
// features or more recent). |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
137 |
// |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
138 |
// NOTE: Table sorted on lookup/hash ID. |
380 | 139 |
|
47772
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
140 |
static FeatureEntry s_feature_tbl[] = { |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
141 |
{ 0x006f, false, "v9", ISA_v9_msk }, // Mandatory |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
142 |
{ 0x00a6, false, "md5", ISA_md5_msk }, |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
143 |
{ 0x00ce, false, "adi", ISA_adi_msk }, // NYI |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
144 |
{ 0x00d7, false, "ima", ISA_ima_msk }, |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
145 |
{ 0x00d9, false, "aes", ISA_aes_msk }, |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
146 |
{ 0x00db, false, "hpc", ISA_hpc_msk }, |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
147 |
{ 0x00dc, false, "des", ISA_des_msk }, |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
148 |
{ 0x00ed, false, "sha1", ISA_sha1_msk }, |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
149 |
{ 0x00f2, false, "vis", ISA_vis1_msk }, |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
150 |
{ 0x0104, false, "vis2", ISA_vis2_msk }, |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
151 |
{ 0x0105, false, "vis3", ISA_vis3_msk }, |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
152 |
{ 0x0114, false, "sha512", ISA_sha512_msk }, |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
153 |
{ 0x0119, false, "sha256", ISA_sha256_msk }, |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
154 |
{ 0x011a, false, "fmaf", ISA_fmaf_msk }, |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
155 |
{ 0x0132, false, "popc", ISA_popc_msk }, |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
156 |
{ 0x0140, false, "crc32c", ISA_crc32c_msk }, |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
157 |
{ 0x0147, false, "vis3b", ISA_vis3b_msk }, // NYI |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
158 |
{ 0x017e, false, "pause", ISA_pause_msk }, |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
159 |
{ 0x0182, false, "mwait", ISA_mwait_msk }, // NYI |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
160 |
{ 0x018b, false, "mpmul", ISA_mpmul_msk }, |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
161 |
{ 0x018e, false, "sparc5", ISA_sparc5_msk }, // NYI |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
162 |
{ 0x01a9, false, "cbcond", ISA_cbcond_msk }, |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
163 |
{ 0x01c3, false, "vamask", ISA_vamask_msk }, // NYI |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
164 |
{ 0x01ca, false, "kasumi", ISA_kasumi_msk }, |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
165 |
{ 0x01e3, false, "xmpmul", ISA_xmpmul_msk }, // NYI |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
166 |
{ 0x022c, false, "montmul", ISA_mont_msk }, |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
167 |
{ 0x0234, false, "montsqr", ISA_mont_msk }, |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
168 |
{ 0x0238, false, "camellia", ISA_camellia_msk }, |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
169 |
{ 0x024a, false, "ASIBlkInit", ISA_blk_init_msk }, |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
170 |
{ 0x0284, false, "xmontmul", ISA_xmont_msk }, // NYI |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
171 |
{ 0x02e6, false, "pause_nsec", ISA_pause_nsec_msk }, // NYI |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
172 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
173 |
{ 0x0000, false, NULL, 0 } |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
174 |
}; |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
175 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
176 |
CPUinfo caps("cpucaps"); // Read "cpucaps" from /proc/cpuinfo. |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
177 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
178 |
assert(caps.valid(), "must be"); |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
179 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
180 |
_features = parse_features(s_feature_tbl, caps.value()); |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
181 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
182 |
assert(has_v9(), "must be"); // Basic SPARC-V9 required (V8 not supported). |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
183 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
184 |
CPUinfo type("type"); |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
185 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
186 |
bool is_sun4v = type.match("sun4v"); // All Oracle SPARC + Fujitsu Athena+ |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
187 |
bool is_sun4u = type.match("sun4u"); // All other Fujitsu |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
188 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
189 |
uint64_t synthetic = 0; |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
190 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
191 |
if (is_sun4v) { |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
192 |
// Indirect and direct branches are equally fast. |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
193 |
synthetic = CPU_fast_ind_br_msk; |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
194 |
// Fast IDIV, BIS and LD available on Niagara Plus. |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
195 |
if (has_vis2()) { |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
196 |
synthetic |= (CPU_fast_idiv_msk | CPU_fast_ld_msk); |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
197 |
// ...on Core C4 however, we prefer not to use BIS. |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
198 |
if (!has_sparc5()) { |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
199 |
synthetic |= CPU_fast_bis_msk; |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
200 |
} |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
201 |
} |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
202 |
// Niagara Core C3 supports fast RDPC and block zeroing. |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
203 |
if (has_ima()) { |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
204 |
synthetic |= (CPU_fast_rdpc_msk | CPU_blk_zeroing_msk); |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
205 |
} |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
206 |
// Niagara Core C3 and C4 have slow CMOVE. |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
207 |
if (!has_ima()) { |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
208 |
synthetic |= CPU_fast_cmove_msk; |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
209 |
} |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
210 |
} else if (is_sun4u) { |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
211 |
// SPARC64 only have fast IDIV and RDPC. |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
212 |
synthetic |= (CPU_fast_idiv_msk | CPU_fast_rdpc_msk); |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
213 |
} else { |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
214 |
log_info(os, cpu)("Unable to derive CPU features: %s", type.value()); |
380 | 215 |
} |
216 |
||
47772
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
217 |
_features += synthetic; // Including CPU derived/synthetic features. |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
218 |
} |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
219 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
220 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
221 |
//////////////////////////////////////////////////////////////////////////////// |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
222 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
223 |
static uint32_t uhash32(const char name[]); |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
224 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
225 |
static void update_table(FeatureEntry feature_tbl[], uint32_t hv, |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
226 |
const char* ch1p, |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
227 |
const char* endp); |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
228 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
229 |
/* Given a feature table, parse the input text holding the string value of |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
230 |
* 'cpucaps' as reported by '/proc/cpuinfo', in order to complete the table |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
231 |
* with information on each admissible feature (whether present or not). |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
232 |
* |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
233 |
* Return the composite bit-mask representing the features found. |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
234 |
*/ |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
235 |
static uint64_t parse_features(FeatureEntry feature_tbl[], const char input[]) { |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
236 |
log_info(os, cpu)("Parse CPU features: %s\n", input); |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
237 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
238 |
#ifdef ASSERT |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
239 |
// Verify that hash value entries in the table are unique and ordered. |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
240 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
241 |
uint32_t prev = 0; |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
242 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
243 |
for (uint k = 0; feature_tbl[k].name != NULL; k++) { |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
244 |
feature_tbl[k].seen = false; |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
245 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
246 |
assert(feature_tbl[k].hash == uhash32(feature_tbl[k].name), |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
247 |
"feature '%s' has mismatching hash 0x%08x (expected 0x%08x).\n", |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
248 |
feature_tbl[k].name, |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
249 |
feature_tbl[k].hash, |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
250 |
uhash32(feature_tbl[k].name)); |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
251 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
252 |
assert(prev < feature_tbl[k].hash, |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
253 |
"feature '%s' has invalid hash 0x%08x (previous is 0x%08x).\n", |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
254 |
feature_tbl[k].name, |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
255 |
feature_tbl[k].hash, |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
256 |
prev); |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
257 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
258 |
prev = feature_tbl[k].hash; |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
259 |
} |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
260 |
#endif |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
261 |
// Identify features from the input, consisting of a string with features |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
262 |
// separated by commas (or whitespace), e.g. "flush,muldiv,v9,mul32,div32, |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
263 |
// v8plus,popc,vis". |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
264 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
265 |
uint32_t hv = 0; |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
266 |
const char* ch1p = &input[0]; |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
267 |
uint i = 0; |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
268 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
269 |
do { |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
270 |
char ch = input[i]; |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
271 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
272 |
if (isalnum(ch) || ch == '_') { |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
273 |
hv += (ch - 32u); |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
274 |
} |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
275 |
else if (isspace(ch) || ch == ',' || ch == '\0') { // end-of-token |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
276 |
if (ch1p < &input[i]) { |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
277 |
update_table(feature_tbl, hv, ch1p, &input[i]); |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
278 |
} |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
279 |
ch1p = &input[i + 1]; hv = 0; |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
280 |
} else { |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
281 |
// Handle non-accepted input robustly. |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
282 |
log_info(os, cpu)("Bad token in feature string: '%c' (0x%02x).\n", ch, ch); |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
283 |
ch1p = &input[i + 1]; hv = 0; |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
284 |
} |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
285 |
} |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
286 |
while (input[i++] != '\0'); |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
287 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
288 |
// Compute actual bit-mask representation. |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
289 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
290 |
uint64_t mask = 0; |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
291 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
292 |
for (uint k = 0; feature_tbl[k].name != NULL; k++) { |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
293 |
mask |= feature_tbl[k].seen ? feature_tbl[k].mask : 0; |
32605
dab0de4ff7ff
8134161: JVM is creating too many GC helper threads on T7/M7 linux/sparc platform
gthornbr
parents:
29210
diff
changeset
|
294 |
} |
dab0de4ff7ff
8134161: JVM is creating too many GC helper threads on T7/M7 linux/sparc platform
gthornbr
parents:
29210
diff
changeset
|
295 |
|
47772
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
296 |
return mask; |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
297 |
} |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
298 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
299 |
static uint32_t uhash32(const char name[]) { |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
300 |
uint32_t hv = 0; |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
301 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
302 |
for (uint i = 0; name[i] != '\0'; i++) { |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
303 |
hv += (name[i] - 32u); |
29210
f8d006dc2485
8062672: JVM crashes during GC on various asserts which checks that HeapWord ptr is an oop
sjohanss
parents:
25079
diff
changeset
|
304 |
} |
f8d006dc2485
8062672: JVM crashes during GC on various asserts which checks that HeapWord ptr is an oop
sjohanss
parents:
25079
diff
changeset
|
305 |
|
47772
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
306 |
return hv; |
380 | 307 |
} |
47772
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
308 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
309 |
static bool verify_match(const char name[], const char* ch1p, const char* endp); |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
310 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
311 |
static void update_table(FeatureEntry feature_tbl[], uint32_t hv, const char* ch1p, const char* endp) { |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
312 |
assert(ch1p < endp, "at least one character"); |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
313 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
314 |
// Look for a hash value in the table. Since this table is a small one (and |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
315 |
// is expected to stay small), we use a simple linear search (iff the table |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
316 |
// grows large, we may consider to adopt a binary ditto, or a perfect hash). |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
317 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
318 |
for (uint k = 0; feature_tbl[k].name != NULL; k++) { |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
319 |
uint32_t hash = feature_tbl[k].hash; |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
320 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
321 |
if (hash < hv) continue; |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
322 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
323 |
if (hash == hv) { |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
324 |
const char* name = feature_tbl[k].name; |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
325 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
326 |
if (verify_match(name, ch1p, endp)) { |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
327 |
feature_tbl[k].seen = true; |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
328 |
break; |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
329 |
} |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
330 |
} |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
331 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
332 |
// Either a non-matching feature (when hash == hv) or hash > hv. In either |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
333 |
// case we break out of the loop and terminate the search (note that the |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
334 |
// table is assumed to be uniquely sorted on the hash). |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
335 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
336 |
break; |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
337 |
} |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
338 |
} |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
339 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
340 |
static bool verify_match(const char name[], const char* ch1p, const char* endp) { |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
341 |
size_t len = strlen(name); |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
342 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
343 |
if (len != static_cast<size_t>(endp - ch1p)) { |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
344 |
return false; |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
345 |
} |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
346 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
347 |
for (uint i = 0; ch1p + i < endp; i++) { |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
348 |
if (name[i] != ch1p[i]) return false; |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
349 |
} |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
350 |
|
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
351 |
return true; |
71ad0eec75e8
8172232: SPARC ISA/CPU feature detection is broken/insufficient (on Linux).
phedlin
parents:
47216
diff
changeset
|
352 |
} |