28 #include "runtime/stubRoutines.hpp"
29 #include "utilities/globalDefinitions.hpp"
30 #include "crc32c.h"
31
32 // Implementation of the platform-specific part of StubRoutines - for
33 // a description of how to extend it, see the stubRoutines.hpp file.
34
35 // define fields for arch-specific entries
36
37 #define DEFINE_ARCH_ENTRY(arch, blob_name, stub_name, field_name, getter_name) \
38 address StubRoutines:: arch :: STUB_FIELD_NAME(field_name) = nullptr;
39
40 #define DEFINE_ARCH_ENTRY_INIT(arch, blob_name, stub_name, field_name, getter_name, init_function) \
41 address StubRoutines:: arch :: STUB_FIELD_NAME(field_name) = CAST_FROM_FN_PTR(address, init_function);
42
43 STUBGEN_ARCH_ENTRIES_DO(DEFINE_ARCH_ENTRY, DEFINE_ARCH_ENTRY_INIT)
44
45 #undef DEFINE_ARCH_ENTRY_INIT
46 #undef DEFINE_ARCH_ENTRY
47
48 address StubRoutines::x86::_k256_adr = nullptr;
49 address StubRoutines::x86::_k256_W_adr = nullptr;
50 address StubRoutines::x86::_k512_W_addr = nullptr;
51
52 const uint64_t StubRoutines::x86::_crc_by128_masks[] =
53 {
54 /* The fields in this structure are arranged so that they can be
55 * picked up two at a time with 128-bit loads.
56 *
57 * Because of flipped bit order for this CRC polynomials
58 * the constant for X**N is left-shifted by 1. This is because
59 * a 64 x 64 polynomial multiply produces a 127-bit result
60 * but the highest term is always aligned to bit 0 in the container.
61 * Pre-shifting by one fixes this, at the cost of potentially making
62 * the 32-bit constant no longer fit in a 32-bit container (thus the
63 * use of uint64_t, though this is also the size used by the carry-
64 * less multiply instruction.
65 *
66 * In addition, the flipped bit order and highest-term-at-least-bit
67 * multiply changes the constants used. The 96-bit result will be
274 _crc32c_pow_2k_table[k] = crc32c_multiply(tmp, tmp);
275 }
276 }
277
278 // x^N mod P(x)
279 static uint32_t crc32c_f_pow_n(uint32_t n) {
280 // result = 1 (polynomial)
281 uint32_t one, result = 0x80000000, i = 0;
282
283 while (one = (n & 1), (n == 1 || n - one > 0)) {
284 if (one) {
285 result = crc32c_multiply(result, _crc32c_pow_2k_table[i]);
286 }
287 n >>= 1;
288 i++;
289 }
290
291 return result;
292 }
293
294 juint *StubRoutines::x86::_crc32c_table;
295
296 void StubRoutines::x86::generate_CRC32C_table(bool is_pclmulqdq_table_supported) {
297
298 static juint pow_n[CRC32C_NUM_PRECOMPUTED_CONSTANTS];
299
300 crc32c_init_pow_2k();
301
302 pow_n[0] = crc32c_f_pow_n(CRC32C_HIGH * 8); // 8N * 8 = 64N
303 pow_n[1] = crc32c_f_pow_n(CRC32C_HIGH * 8 * 2); // 128N
304
305 pow_n[2] = crc32c_f_pow_n(CRC32C_MIDDLE * 8);
306 pow_n[3] = crc32c_f_pow_n(CRC32C_MIDDLE * 8 * 2);
307
308 pow_n[4] = crc32c_f_pow_n(CRC32C_LOW * 8);
309 pow_n[CRC32C_NUM_PRECOMPUTED_CONSTANTS - 1] =
310 crc32c_f_pow_n(CRC32C_LOW * 8 * 2);
311
312 if (is_pclmulqdq_table_supported) {
313 _crc32c_table = pow_n;
314 } else {
|
28 #include "runtime/stubRoutines.hpp"
29 #include "utilities/globalDefinitions.hpp"
30 #include "crc32c.h"
31
32 // Implementation of the platform-specific part of StubRoutines - for
33 // a description of how to extend it, see the stubRoutines.hpp file.
34
35 // define fields for arch-specific entries
36
37 #define DEFINE_ARCH_ENTRY(arch, blob_name, stub_name, field_name, getter_name) \
38 address StubRoutines:: arch :: STUB_FIELD_NAME(field_name) = nullptr;
39
40 #define DEFINE_ARCH_ENTRY_INIT(arch, blob_name, stub_name, field_name, getter_name, init_function) \
41 address StubRoutines:: arch :: STUB_FIELD_NAME(field_name) = CAST_FROM_FN_PTR(address, init_function);
42
43 STUBGEN_ARCH_ENTRIES_DO(DEFINE_ARCH_ENTRY, DEFINE_ARCH_ENTRY_INIT)
44
45 #undef DEFINE_ARCH_ENTRY_INIT
46 #undef DEFINE_ARCH_ENTRY
47
48 address StubRoutines::crc_table_addr() {
49 return (address)StubRoutines::x86::_crc_table;
50 }
51 address StubRoutines::crc32c_table_addr() {
52 if (StubRoutines::x86::_crc32c_table == nullptr) {
53 bool supports_clmul = VM_Version::supports_clmul();
54 StubRoutines::x86::generate_CRC32C_table(supports_clmul);
55 }
56 return (address)StubRoutines::x86::_crc32c_table;
57 }
58
59 address StubRoutines::x86::_k256_adr = nullptr;
60 address StubRoutines::x86::_k256_W_adr = nullptr;
61 address StubRoutines::x86::_k512_W_addr = nullptr;
62
63 const uint64_t StubRoutines::x86::_crc_by128_masks[] =
64 {
65 /* The fields in this structure are arranged so that they can be
66 * picked up two at a time with 128-bit loads.
67 *
68 * Because of flipped bit order for this CRC polynomials
69 * the constant for X**N is left-shifted by 1. This is because
70 * a 64 x 64 polynomial multiply produces a 127-bit result
71 * but the highest term is always aligned to bit 0 in the container.
72 * Pre-shifting by one fixes this, at the cost of potentially making
73 * the 32-bit constant no longer fit in a 32-bit container (thus the
74 * use of uint64_t, though this is also the size used by the carry-
75 * less multiply instruction.
76 *
77 * In addition, the flipped bit order and highest-term-at-least-bit
78 * multiply changes the constants used. The 96-bit result will be
285 _crc32c_pow_2k_table[k] = crc32c_multiply(tmp, tmp);
286 }
287 }
288
289 // x^N mod P(x)
290 static uint32_t crc32c_f_pow_n(uint32_t n) {
291 // result = 1 (polynomial)
292 uint32_t one, result = 0x80000000, i = 0;
293
294 while (one = (n & 1), (n == 1 || n - one > 0)) {
295 if (one) {
296 result = crc32c_multiply(result, _crc32c_pow_2k_table[i]);
297 }
298 n >>= 1;
299 i++;
300 }
301
302 return result;
303 }
304
305 juint* StubRoutines::x86::_crc32c_table = nullptr;
306
307 void StubRoutines::x86::generate_CRC32C_table(bool is_pclmulqdq_table_supported) {
308
309 static juint pow_n[CRC32C_NUM_PRECOMPUTED_CONSTANTS];
310
311 crc32c_init_pow_2k();
312
313 pow_n[0] = crc32c_f_pow_n(CRC32C_HIGH * 8); // 8N * 8 = 64N
314 pow_n[1] = crc32c_f_pow_n(CRC32C_HIGH * 8 * 2); // 128N
315
316 pow_n[2] = crc32c_f_pow_n(CRC32C_MIDDLE * 8);
317 pow_n[3] = crc32c_f_pow_n(CRC32C_MIDDLE * 8 * 2);
318
319 pow_n[4] = crc32c_f_pow_n(CRC32C_LOW * 8);
320 pow_n[CRC32C_NUM_PRECOMPUTED_CONSTANTS - 1] =
321 crc32c_f_pow_n(CRC32C_LOW * 8 * 2);
322
323 if (is_pclmulqdq_table_supported) {
324 _crc32c_table = pow_n;
325 } else {
|