annotate src/hotspot/cpu/s390/vm_version_s390.cpp @ 54970:b776653628c5

8218991: s390: Add intrinsic for GHASH algorithm Reviewed-by: lucy, simonis
author mdoerr
date Mon, 18 Feb 2019 12:16:02 +0100
parents 9937ef7499dc
children ddc19ea5059c
rev   line source
goetz@42065 1 /*
mdoerr@54970 2 * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
mdoerr@54970 3 * Copyright (c) 2016, 2019 SAP SE. All rights reserved.
goetz@42065 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
goetz@42065 5 *
goetz@42065 6 * This code is free software; you can redistribute it and/or modify it
goetz@42065 7 * under the terms of the GNU General Public License version 2 only, as
goetz@42065 8 * published by the Free Software Foundation.
goetz@42065 9 *
goetz@42065 10 * This code is distributed in the hope that it will be useful, but WITHOUT
goetz@42065 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
goetz@42065 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
goetz@42065 13 * version 2 for more details (a copy is included in the LICENSE file that
goetz@42065 14 * accompanied this code).
goetz@42065 15 *
goetz@42065 16 * You should have received a copy of the GNU General Public License version
goetz@42065 17 * 2 along with this work; if not, write to the Free Software Foundation,
goetz@42065 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
goetz@42065 19 *
goetz@42065 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
goetz@42065 21 * or visit www.oracle.com if you need additional information or have any
goetz@42065 22 * questions.
goetz@42065 23 *
goetz@42065 24 */
goetz@42065 25
goetz@42065 26 #include "precompiled.hpp"
coleenp@47946 27 #include "jvm.h"
goetz@42065 28 #include "asm/assembler.inline.hpp"
goetz@42065 29 #include "compiler/disassembler.hpp"
goetz@42065 30 #include "code/compiledIC.hpp"
goetz@42065 31 #include "memory/resourceArea.hpp"
goetz@42065 32 #include "runtime/java.hpp"
goetz@42065 33 #include "runtime/stubCodeGenerator.hpp"
goetz@42065 34 #include "vm_version_s390.hpp"
goetz@42065 35
goetz@42065 36 # include <sys/sysinfo.h>
goetz@42065 37
goetz@42065 38 bool VM_Version::_is_determine_features_test_running = false;
ghaug@51695 39 const char* VM_Version::_model_string;
goetz@42065 40
goetz@42065 41 unsigned long VM_Version::_features[_features_buffer_len] = {0, 0, 0, 0};
goetz@42065 42 unsigned long VM_Version::_cipher_features[_features_buffer_len] = {0, 0, 0, 0};
goetz@42065 43 unsigned long VM_Version::_msgdigest_features[_features_buffer_len] = {0, 0, 0, 0};
goetz@42065 44 unsigned int VM_Version::_nfeatures = 0;
goetz@42065 45 unsigned int VM_Version::_ncipher_features = 0;
goetz@42065 46 unsigned int VM_Version::_nmsgdigest_features = 0;
goetz@42065 47 unsigned int VM_Version::_Dcache_lineSize = 256;
goetz@42065 48 unsigned int VM_Version::_Icache_lineSize = 256;
goetz@42065 49
goetz@42065 50 static const char* z_gen[] = {" ", "G1", "G2", "G3", "G4", "G5", "G6", "G7" };
goetz@42065 51 static const char* z_machine[] = {" ", "2064", "2084", "2094", "2097", "2817", " ", "2964" };
goetz@42065 52 static const char* z_name[] = {" ", "z900", "z990", "z9 EC", "z10 EC", "z196 EC", "ec12", "z13" };
goetz@42065 53
goetz@42065 54 void VM_Version::initialize() {
goetz@42065 55 determine_features(); // Get processor capabilities.
goetz@42065 56 set_features_string(); // Set a descriptive feature indication.
goetz@42065 57
goetz@42065 58 if (Verbose) {
goetz@42065 59 print_features();
goetz@42065 60 }
goetz@42065 61
goetz@42065 62 intx cache_line_size = Dcache_lineSize(0);
goetz@42065 63
goetz@42065 64 MaxVectorSize = 8;
goetz@42065 65
goetz@42065 66 if (has_PrefetchRaw()) {
goetz@42065 67 if (FLAG_IS_DEFAULT(AllocatePrefetchStyle)) { // not preset
goetz@42065 68 // 0 = no prefetch.
goetz@42065 69 // 1 = Prefetch instructions for each allocation.
goetz@42065 70 // 2 = Use TLAB watermark to gate allocation prefetch.
goetz@42065 71 AllocatePrefetchStyle = 1;
goetz@42065 72 }
goetz@42065 73
goetz@42065 74 if (AllocatePrefetchStyle > 0) { // Prefetching turned on at all?
goetz@42065 75 // Distance to prefetch ahead of allocation pointer.
goetz@42065 76 if (FLAG_IS_DEFAULT(AllocatePrefetchDistance) || (AllocatePrefetchDistance < 0)) { // not preset
goetz@42065 77 AllocatePrefetchDistance = 0;
goetz@42065 78 }
goetz@42065 79
goetz@42065 80 // Number of lines to prefetch ahead of allocation pointer.
goetz@42065 81 if (FLAG_IS_DEFAULT(AllocatePrefetchLines) || (AllocatePrefetchLines <= 0)) { // not preset
goetz@42065 82 AllocatePrefetchLines = 3;
goetz@42065 83 }
goetz@42065 84
goetz@42065 85 // Step size in bytes of sequential prefetch instructions.
goetz@42065 86 if (FLAG_IS_DEFAULT(AllocatePrefetchStepSize) || (AllocatePrefetchStepSize <= 0)) { // not preset
goetz@42065 87 FLAG_SET_DEFAULT(AllocatePrefetchStepSize, cache_line_size);
goetz@42065 88 } else if (AllocatePrefetchStepSize < cache_line_size) {
goetz@42065 89 FLAG_SET_DEFAULT(AllocatePrefetchStepSize, cache_line_size);
goetz@42065 90 } else {
goetz@42065 91 FLAG_SET_DEFAULT(AllocatePrefetchStepSize, cache_line_size);
goetz@42065 92 }
goetz@42065 93 } else {
goetz@42065 94 FLAG_SET_DEFAULT(AllocatePrefetchStyle, 0);
goetz@42065 95 AllocatePrefetchDistance = 0;
goetz@42065 96 AllocatePrefetchLines = 0;
goetz@42065 97 // Can't be zero. Will SIGFPE during constraints checking.
goetz@42065 98 FLAG_SET_DEFAULT(AllocatePrefetchStepSize, cache_line_size);
goetz@42065 99 }
goetz@42065 100
goetz@42065 101 } else {
goetz@42065 102 FLAG_SET_DEFAULT(AllocatePrefetchStyle, 0);
goetz@42065 103 AllocatePrefetchDistance = 0;
goetz@42065 104 AllocatePrefetchLines = 0;
goetz@42065 105 // Can't be zero. Will SIGFPE during constraints checking.
goetz@42065 106 FLAG_SET_DEFAULT(AllocatePrefetchStepSize, cache_line_size);
goetz@42065 107 }
goetz@42065 108
goetz@42065 109 // TODO:
goetz@42065 110 // On z/Architecture, cache line size is significantly large (256 bytes). Do we really need
goetz@42065 111 // to keep contended members that far apart? Performance tests are required.
goetz@42065 112 if (FLAG_IS_DEFAULT(ContendedPaddingWidth) && (cache_line_size > ContendedPaddingWidth)) {
goetz@42065 113 ContendedPaddingWidth = cache_line_size;
goetz@42065 114 }
goetz@42065 115
lucy@46315 116 // On z/Architecture, the CRC32/CRC32C intrinsics are implemented "by hand".
lucy@46315 117 // TODO: Provide implementation based on the vector instructions available from z13.
lucy@46315 118 // Note: The CHECKSUM instruction, which has been there since the very beginning
lucy@46315 119 // (of z/Architecture), computes "some kind of" a checksum.
lucy@46315 120 // It has nothing to do with the CRC32 algorithm.
goetz@42065 121 if (FLAG_IS_DEFAULT(UseCRC32Intrinsics)) {
goetz@42065 122 FLAG_SET_DEFAULT(UseCRC32Intrinsics, true);
goetz@42065 123 }
lucy@46315 124 if (FLAG_IS_DEFAULT(UseCRC32CIntrinsics)) {
lucy@46315 125 FLAG_SET_DEFAULT(UseCRC32CIntrinsics, true);
lucy@46315 126 }
lucy@46315 127
lucy@46315 128 // TODO: Provide implementation.
lucy@46315 129 if (UseAdler32Intrinsics) {
lucy@46315 130 warning("Adler32Intrinsics not available on this CPU.");
lucy@46315 131 FLAG_SET_DEFAULT(UseAdler32Intrinsics, false);
lucy@46315 132 }
goetz@42065 133
goetz@42065 134 // On z/Architecture, we take UseAES as the general switch to enable/disable the AES intrinsics.
goetz@42065 135 // The specific, and yet to be defined, switches UseAESxxxIntrinsics will then be set
goetz@42065 136 // depending on the actual machine capabilities.
goetz@42065 137 // Explicitly setting them via CmdLine option takes precedence, of course.
goetz@42065 138 // TODO: UseAESIntrinsics must be made keylength specific.
goetz@42065 139 // As of March 2015 and Java8, only AES128 is supported by the Java Cryptographic Extensions.
goetz@42065 140 // Therefore, UseAESIntrinsics is of minimal use at the moment.
goetz@42065 141 if (FLAG_IS_DEFAULT(UseAES) && has_Crypto_AES()) {
goetz@42065 142 FLAG_SET_DEFAULT(UseAES, true);
goetz@42065 143 }
goetz@42065 144 if (UseAES && !has_Crypto_AES()) {
goetz@42065 145 warning("AES instructions are not available on this CPU");
goetz@42065 146 FLAG_SET_DEFAULT(UseAES, false);
goetz@42065 147 }
goetz@42065 148 if (UseAES) {
goetz@42065 149 if (FLAG_IS_DEFAULT(UseAESIntrinsics)) {
goetz@42065 150 FLAG_SET_DEFAULT(UseAESIntrinsics, true);
goetz@42065 151 }
goetz@42065 152 }
goetz@42065 153 if (UseAESIntrinsics && !has_Crypto_AES()) {
goetz@42065 154 warning("AES intrinsics are not available on this CPU");
goetz@42065 155 FLAG_SET_DEFAULT(UseAESIntrinsics, false);
goetz@42065 156 }
lucy@46733 157 if (UseAESIntrinsics && !UseAES) {
lucy@46733 158 warning("AES intrinsics require UseAES flag to be enabled. Intrinsics will be disabled.");
lucy@46733 159 FLAG_SET_DEFAULT(UseAESIntrinsics, false);
lucy@46733 160 }
goetz@42065 161
goetz@42065 162 // TODO: implement AES/CTR intrinsics
goetz@42065 163 if (UseAESCTRIntrinsics) {
goetz@42065 164 warning("AES/CTR intrinsics are not available on this CPU");
goetz@42065 165 FLAG_SET_DEFAULT(UseAESCTRIntrinsics, false);
goetz@42065 166 }
goetz@42065 167
mdoerr@54970 168 if (FLAG_IS_DEFAULT(UseGHASHIntrinsics) && has_Crypto_GHASH()) {
mdoerr@54970 169 FLAG_SET_DEFAULT(UseGHASHIntrinsics, true);
mdoerr@54970 170 }
mdoerr@54970 171 if (UseGHASHIntrinsics && !has_Crypto_GHASH()) {
goetz@42065 172 warning("GHASH intrinsics are not available on this CPU");
goetz@42065 173 FLAG_SET_DEFAULT(UseGHASHIntrinsics, false);
goetz@42065 174 }
goetz@42065 175
mdoerr@42897 176 if (FLAG_IS_DEFAULT(UseFMA)) {
mdoerr@42897 177 FLAG_SET_DEFAULT(UseFMA, true);
goetz@42065 178 }
goetz@42065 179
goetz@42065 180 // On z/Architecture, we take UseSHA as the general switch to enable/disable the SHA intrinsics.
goetz@42065 181 // The specific switches UseSHAxxxIntrinsics will then be set depending on the actual
goetz@42065 182 // machine capabilities.
goetz@42065 183 // Explicitly setting them via CmdLine option takes precedence, of course.
goetz@42065 184 if (FLAG_IS_DEFAULT(UseSHA) && has_Crypto_SHA()) {
goetz@42065 185 FLAG_SET_DEFAULT(UseSHA, true);
goetz@42065 186 }
goetz@42065 187 if (UseSHA && !has_Crypto_SHA()) {
goetz@42065 188 warning("SHA instructions are not available on this CPU");
goetz@42065 189 FLAG_SET_DEFAULT(UseSHA, false);
goetz@42065 190 }
goetz@42065 191 if (UseSHA && has_Crypto_SHA1()) {
goetz@42065 192 if (FLAG_IS_DEFAULT(UseSHA1Intrinsics)) {
goetz@42065 193 FLAG_SET_DEFAULT(UseSHA1Intrinsics, true);
goetz@42065 194 }
goetz@42065 195 } else if (UseSHA1Intrinsics) {
goetz@42065 196 warning("Intrinsics for SHA-1 crypto hash functions not available on this CPU.");
goetz@42065 197 FLAG_SET_DEFAULT(UseSHA1Intrinsics, false);
goetz@42065 198 }
goetz@42065 199 if (UseSHA && has_Crypto_SHA256()) {
goetz@42065 200 if (FLAG_IS_DEFAULT(UseSHA256Intrinsics)) {
goetz@42065 201 FLAG_SET_DEFAULT(UseSHA256Intrinsics, true);
goetz@42065 202 }
goetz@42065 203 } else if (UseSHA256Intrinsics) {
goetz@42065 204 warning("Intrinsics for SHA-224 and SHA-256 crypto hash functions not available on this CPU.");
goetz@42065 205 FLAG_SET_DEFAULT(UseSHA256Intrinsics, false);
goetz@42065 206 }
goetz@42065 207 if (UseSHA && has_Crypto_SHA512()) {
goetz@42065 208 if (FLAG_IS_DEFAULT(UseSHA512Intrinsics)) {
goetz@42065 209 FLAG_SET_DEFAULT(UseSHA512Intrinsics, true);
goetz@42065 210 }
goetz@42065 211 } else if (UseSHA512Intrinsics) {
goetz@42065 212 warning("Intrinsics for SHA-384 and SHA-512 crypto hash functions not available on this CPU.");
goetz@42065 213 FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
goetz@42065 214 }
goetz@42065 215
mbaesken@51644 216 if (!(UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics)) {
mbaesken@51644 217 FLAG_SET_DEFAULT(UseSHA, false);
mbaesken@51644 218 }
mbaesken@51644 219
goetz@42065 220 if (FLAG_IS_DEFAULT(UseMultiplyToLenIntrinsic)) {
goetz@42065 221 FLAG_SET_DEFAULT(UseMultiplyToLenIntrinsic, true);
goetz@42065 222 }
goetz@42065 223 if (FLAG_IS_DEFAULT(UseMontgomeryMultiplyIntrinsic)) {
goetz@42065 224 FLAG_SET_DEFAULT(UseMontgomeryMultiplyIntrinsic, true);
goetz@42065 225 }
goetz@42065 226 if (FLAG_IS_DEFAULT(UseMontgomerySquareIntrinsic)) {
goetz@42065 227 FLAG_SET_DEFAULT(UseMontgomerySquareIntrinsic, true);
goetz@42065 228 }
goetz@42065 229 if (FLAG_IS_DEFAULT(UsePopCountInstruction)) {
goetz@42065 230 FLAG_SET_DEFAULT(UsePopCountInstruction, true);
goetz@42065 231 }
goetz@42065 232
goetz@42065 233 // z/Architecture supports 8-byte compare-exchange operations
coleenp@47789 234 // (see Atomic::cmpxchg)
goetz@42065 235 // and 'atomic long memory ops' (see Unsafe_GetLongVolatile).
goetz@42065 236 _supports_cx8 = true;
goetz@42065 237
goetz@42065 238 _supports_atomic_getadd4 = VM_Version::has_LoadAndALUAtomicV1();
goetz@42065 239 _supports_atomic_getadd8 = VM_Version::has_LoadAndALUAtomicV1();
goetz@42065 240
goetz@42065 241 // z/Architecture supports unaligned memory accesses.
goetz@42065 242 // Performance penalty is negligible. An additional tick or so
goetz@42065 243 // is lost if the accessed data spans a cache line boundary.
goetz@42065 244 // Unaligned accesses are not atomic, of course.
goetz@42065 245 if (FLAG_IS_DEFAULT(UseUnalignedAccesses)) {
goetz@42065 246 FLAG_SET_DEFAULT(UseUnalignedAccesses, true);
goetz@42065 247 }
goetz@42065 248 }
goetz@42065 249
goetz@42065 250
goetz@42065 251 void VM_Version::set_features_string() {
goetz@42065 252
goetz@42065 253 unsigned int ambiguity = 0;
ghaug@51695 254 _model_string = z_name[0];
goetz@42065 255 if (is_z13()) {
goetz@42065 256 _features_string = "System z G7-z13 (LDISP_fast, ExtImm, PCrel Load/Store, CmpB, Cond Load/Store, Interlocked Update, TxM, VectorInstr)";
ghaug@51695 257 _model_string = z_name[7];
goetz@42065 258 ambiguity++;
goetz@42065 259 }
goetz@42065 260 if (is_ec12()) {
goetz@42065 261 _features_string = "System z G6-EC12 (LDISP_fast, ExtImm, PCrel Load/Store, CmpB, Cond Load/Store, Interlocked Update, TxM)";
ghaug@51695 262 _model_string = z_name[6];
goetz@42065 263 ambiguity++;
goetz@42065 264 }
goetz@42065 265 if (is_z196()) {
goetz@42065 266 _features_string = "System z G5-z196 (LDISP_fast, ExtImm, PCrel Load/Store, CmpB, Cond Load/Store, Interlocked Update)";
ghaug@51695 267 _model_string = z_name[5];
goetz@42065 268 ambiguity++;
goetz@42065 269 }
goetz@42065 270 if (is_z10()) {
goetz@42065 271 _features_string = "System z G4-z10 (LDISP_fast, ExtImm, PCrel Load/Store, CmpB)";
ghaug@51695 272 _model_string = z_name[4];
goetz@42065 273 ambiguity++;
goetz@42065 274 }
goetz@42065 275 if (is_z9()) {
goetz@42065 276 _features_string = "System z G3-z9 (LDISP_fast, ExtImm), out-of-support as of 2016-04-01";
ghaug@51695 277 _model_string = z_name[3];
goetz@42065 278 ambiguity++;
goetz@42065 279 }
goetz@42065 280 if (is_z990()) {
goetz@42065 281 _features_string = "System z G2-z990 (LDISP_fast), out-of-support as of 2014-07-01";
ghaug@51695 282 _model_string = z_name[2];
goetz@42065 283 ambiguity++;
goetz@42065 284 }
goetz@42065 285 if (is_z900()) {
goetz@42065 286 _features_string = "System z G1-z900 (LDISP), out-of-support as of 2014-07-01";
ghaug@51695 287 _model_string = z_name[1];
goetz@42065 288 ambiguity++;
goetz@42065 289 }
goetz@42065 290
goetz@42065 291 if (ambiguity == 0) {
goetz@42065 292 _features_string = "z/Architecture (unknown generation)";
goetz@42065 293 } else if (ambiguity > 1) {
goetz@42065 294 tty->print_cr("*** WARNING *** Ambiguous z/Architecture detection, ambiguity = %d", ambiguity);
goetz@42065 295 tty->print_cr(" oldest detected generation is %s", _features_string);
goetz@42065 296 _features_string = "z/Architecture (ambiguous detection)";
goetz@42065 297 }
goetz@42556 298
goetz@42556 299 if (has_Crypto_AES()) {
goetz@42556 300 char buf[256];
goetz@42556 301 assert(strlen(_features_string) + 4 + 3*4 + 1 < sizeof(buf), "increase buffer size");
goetz@42556 302 jio_snprintf(buf, sizeof(buf), "%s aes%s%s%s", // String 'aes' must be surrounded by spaces so that jtreg tests recognize it.
goetz@42556 303 _features_string,
goetz@42556 304 has_Crypto_AES128() ? " 128" : "",
goetz@42556 305 has_Crypto_AES192() ? " 192" : "",
goetz@42556 306 has_Crypto_AES256() ? " 256" : "");
goetz@42556 307 _features_string = os::strdup(buf);
goetz@42556 308 }
goetz@42556 309
goetz@42556 310 if (has_Crypto_SHA()) {
goetz@42556 311 char buf[256];
goetz@42556 312 assert(strlen(_features_string) + 4 + 2 + 2*4 + 6 + 1 < sizeof(buf), "increase buffer size");
goetz@42556 313 // String 'sha1' etc must be surrounded by spaces so that jtreg tests recognize it.
goetz@42556 314 jio_snprintf(buf, sizeof(buf), "%s %s%s%s%s",
goetz@42556 315 _features_string,
goetz@42556 316 has_Crypto_SHA1() ? " sha1" : "",
goetz@42556 317 has_Crypto_SHA256() ? " sha256" : "",
goetz@42556 318 has_Crypto_SHA512() ? " sha512" : "",
goetz@42556 319 has_Crypto_GHASH() ? " ghash" : "");
goetz@42556 320 if (has_Crypto_AES()) { os::free((void *)_features_string); }
goetz@42556 321 _features_string = os::strdup(buf);
goetz@42556 322 }
goetz@42065 323 }
goetz@42065 324
goetz@42065 325 // featureBuffer - bit array indicating availability of various features
goetz@42065 326 // featureNum - bit index of feature to be tested
goetz@42065 327 // Featurenum < 0 requests test for any nonzero bit in featureBuffer.
goetz@42065 328 // bufLen - length of featureBuffer in bits
goetz@42065 329 bool VM_Version::test_feature_bit(unsigned long* featureBuffer, int featureNum, unsigned int bufLen) {
goetz@42065 330 assert(bufLen > 0, "buffer len must be positive");
goetz@42065 331 assert((bufLen & 0x0007) == 0, "unaligned buffer len");
goetz@42065 332 assert(((intptr_t)featureBuffer&0x0007) == 0, "unaligned feature buffer");
goetz@42065 333 if (featureNum < 0) {
goetz@42065 334 // Any bit set at all?
goetz@42065 335 bool anyBit = false;
goetz@42065 336 for (size_t i = 0; i < bufLen/(8*sizeof(long)); i++) {
goetz@42065 337 anyBit = anyBit || (featureBuffer[i] != 0);
goetz@42065 338 }
goetz@42065 339 return anyBit;
goetz@42065 340 } else {
goetz@42065 341 assert((unsigned int)featureNum < bufLen, "feature index out of range");
goetz@42065 342 unsigned char* byteBuffer = (unsigned char*)featureBuffer;
goetz@42065 343 int byteIndex = featureNum/(8*sizeof(char));
goetz@42065 344 int bitIndex = featureNum%(8*sizeof(char));
goetz@42065 345 // Indexed bit set?
goetz@42065 346 return (byteBuffer[byteIndex] & (1U<<(7-bitIndex))) != 0;
goetz@42065 347 }
goetz@42065 348 }
goetz@42065 349
goetz@42065 350 void VM_Version::print_features_internal(const char* text, bool print_anyway) {
goetz@42065 351 tty->print_cr("%s %s", text, features_string());
goetz@42065 352 tty->print("%s", text);
goetz@42065 353 for (unsigned int i = 0; i < _nfeatures; i++) {
goetz@42065 354 tty->print(" 0x%16.16lx", _features[i]);
goetz@42065 355 }
goetz@42065 356 tty->cr();
goetz@42065 357
goetz@42065 358 if (Verbose || print_anyway) {
goetz@42065 359 // z900
goetz@42065 360 if (has_long_displacement() ) tty->print_cr("available: %s", "LongDispFacility");
goetz@42065 361 // z990
goetz@42065 362 if (has_long_displacement_fast() ) tty->print_cr("available: %s", "LongDispFacilityHighPerf");
goetz@42065 363 if (has_ETF2() && has_ETF3() ) tty->print_cr("available: %s", "ETF2 and ETF3");
goetz@42065 364 if (has_Crypto() ) tty->print_cr("available: %s", "CryptoFacility");
goetz@42065 365 // z9
goetz@42065 366 if (has_extended_immediate() ) tty->print_cr("available: %s", "ExtImmedFacility");
goetz@42065 367 if (has_StoreFacilityListExtended()) tty->print_cr("available: %s", "StoreFacilityListExtended");
goetz@42065 368 if (has_StoreClockFast() ) tty->print_cr("available: %s", "StoreClockFast");
goetz@42065 369 if (has_ETF2Enhancements() ) tty->print_cr("available: %s", "ETF2 Enhancements");
goetz@42065 370 if (has_ETF3Enhancements() ) tty->print_cr("available: %s", "ETF3 Enhancements");
goetz@42065 371 if (has_HFPUnnormalized() ) tty->print_cr("available: %s", "HFPUnnormalizedFacility");
goetz@42065 372 if (has_HFPMultiplyAndAdd() ) tty->print_cr("available: %s", "HFPMultiplyAndAddFacility");
goetz@42065 373 // z10
goetz@42065 374 if (has_ParsingEnhancements() ) tty->print_cr("available: %s", "Parsing Enhancements");
goetz@42065 375 if (has_ExtractCPUtime() ) tty->print_cr("available: %s", "ExtractCPUTime");
goetz@42065 376 if (has_CompareSwapStore() ) tty->print_cr("available: %s", "CompareSwapStore");
goetz@42065 377 if (has_GnrlInstrExtensions() ) tty->print_cr("available: %s", "General Instruction Extensions");
goetz@42065 378 if (has_CompareBranch() ) tty->print_cr(" available: %s", "Compare and Branch");
goetz@42065 379 if (has_CompareTrap() ) tty->print_cr(" available: %s", "Compare and Trap");
goetz@42065 380 if (has_RelativeLoadStore() ) tty->print_cr(" available: %s", "Relative Load/Store");
goetz@42065 381 if (has_MultiplySingleImm32() ) tty->print_cr(" available: %s", "MultiplySingleImm32");
goetz@42065 382 if (has_Prefetch() ) tty->print_cr(" available: %s", "Prefetch");
goetz@42065 383 if (has_MoveImmToMem() ) tty->print_cr(" available: %s", "Direct Moves Immediate to Memory");
goetz@42065 384 if (has_MemWithImmALUOps() ) tty->print_cr(" available: %s", "Direct ALU Ops Memory .op. Immediate");
goetz@42065 385 if (has_ExtractCPUAttributes() ) tty->print_cr(" available: %s", "Extract CPU Atributes");
goetz@42065 386 if (has_ExecuteExtensions() ) tty->print_cr("available: %s", "ExecuteExtensions");
goetz@42065 387 if (has_FPSupportEnhancements() ) tty->print_cr("available: %s", "FPSupportEnhancements");
goetz@42065 388 if (has_DecimalFloatingPoint() ) tty->print_cr("available: %s", "DecimalFloatingPoint");
goetz@42065 389 // z196
goetz@42065 390 if (has_DistinctOpnds() ) tty->print_cr("available: %s", "Distinct Operands");
goetz@42065 391 if (has_InterlockedAccessV1() ) tty->print_cr(" available: %s", "InterlockedAccess V1 (fast)");
goetz@42065 392 if (has_PopCount() ) tty->print_cr(" available: %s", "PopCount");
goetz@42065 393 if (has_LoadStoreConditional() ) tty->print_cr(" available: %s", "LoadStoreConditional");
goetz@42065 394 if (has_HighWordInstr() ) tty->print_cr(" available: %s", "HighWord Instructions");
goetz@42065 395 if (has_FastSync() ) tty->print_cr(" available: %s", "FastSync (bcr 14,0)");
goetz@42065 396 if (has_AtomicMemWithImmALUOps() ) tty->print_cr("available: %s", "Atomic Direct ALU Ops Memory .op. Immediate");
goetz@42065 397 if (has_FPExtensions() ) tty->print_cr("available: %s", "Floatingpoint Extensions");
goetz@42065 398 if (has_CryptoExt3() ) tty->print_cr("available: %s", "Crypto Extensions 3");
goetz@42065 399 if (has_CryptoExt4() ) tty->print_cr("available: %s", "Crypto Extensions 4");
goetz@42065 400 // EC12
goetz@42065 401 if (has_MiscInstrExt() ) tty->print_cr("available: %s", "Miscelaneous Instruction Extensions");
goetz@42065 402 if (has_ExecutionHint() ) tty->print_cr(" available: %s", "Execution Hints (branch prediction)");
goetz@42065 403 if (has_ProcessorAssist() ) tty->print_cr(" available: %s", "Processor Assists");
goetz@42065 404 if (has_LoadAndTrap() ) tty->print_cr(" available: %s", "Load and Trap");
goetz@42065 405 if (has_TxMem() ) tty->print_cr("available: %s", "Transactional Memory");
goetz@42065 406 if (has_InterlockedAccessV2() ) tty->print_cr(" available: %s", "InterlockedAccess V2 (fast)");
goetz@42065 407 if (has_DFPZonedConversion() ) tty->print_cr(" available: %s", "DFP Zoned Conversions");
goetz@42065 408 // z13
goetz@42065 409 if (has_LoadStoreConditional2() ) tty->print_cr("available: %s", "Load/Store Conditional 2");
goetz@42065 410 if (has_CryptoExt5() ) tty->print_cr("available: %s", "Crypto Extensions 5");
goetz@42065 411 if (has_DFPPackedConversion() ) tty->print_cr("available: %s", "DFP Packed Conversions");
goetz@42065 412 if (has_VectorFacility() ) tty->print_cr("available: %s", "Vector Facility");
goetz@42065 413 // test switches
goetz@42065 414 if (has_TestFeature1Impl() ) tty->print_cr("available: %s", "TestFeature1Impl");
goetz@42065 415 if (has_TestFeature2Impl() ) tty->print_cr("available: %s", "TestFeature2Impl");
goetz@42065 416 if (has_TestFeature4Impl() ) tty->print_cr("available: %s", "TestFeature4Impl");
goetz@42065 417 if (has_TestFeature8Impl() ) tty->print_cr("available: %s", "TestFeature8Impl");
goetz@42065 418
goetz@42065 419 if (has_Crypto()) {
goetz@42065 420 tty->cr();
goetz@42556 421 tty->print_cr("detailed availability of %s capabilities:", "CryptoFacility");
goetz@42065 422 if (test_feature_bit(&_cipher_features[0], -1, 2*Cipher::_featureBits)) {
goetz@42065 423 tty->cr();
goetz@42065 424 tty->print_cr(" available: %s", "Message Cipher Functions");
goetz@42065 425 }
goetz@42065 426 if (test_feature_bit(&_cipher_features[0], -1, (int)Cipher::_featureBits)) {
goetz@42065 427 tty->print_cr(" available Crypto Features of KM (Cipher Message):");
goetz@42065 428 for (unsigned int i = 0; i < Cipher::_featureBits; i++) {
goetz@42065 429 if (test_feature_bit(&_cipher_features[0], i, (int)Cipher::_featureBits)) {
goetz@42065 430 switch (i) {
goetz@42065 431 case Cipher::_Query: tty->print_cr(" available: KM Query"); break;
goetz@42065 432 case Cipher::_DEA: tty->print_cr(" available: KM DEA"); break;
goetz@42065 433 case Cipher::_TDEA128: tty->print_cr(" available: KM TDEA-128"); break;
goetz@42065 434 case Cipher::_TDEA192: tty->print_cr(" available: KM TDEA-192"); break;
goetz@42065 435 case Cipher::_EncryptedDEA: tty->print_cr(" available: KM Encrypted DEA"); break;
goetz@42065 436 case Cipher::_EncryptedDEA128: tty->print_cr(" available: KM Encrypted DEA-128"); break;
goetz@42065 437 case Cipher::_EncryptedDEA192: tty->print_cr(" available: KM Encrypted DEA-192"); break;
goetz@42065 438 case Cipher::_AES128: tty->print_cr(" available: KM AES-128"); break;
goetz@42065 439 case Cipher::_AES192: tty->print_cr(" available: KM AES-192"); break;
goetz@42065 440 case Cipher::_AES256: tty->print_cr(" available: KM AES-256"); break;
goetz@42065 441 case Cipher::_EnccryptedAES128: tty->print_cr(" available: KM Encrypted-AES-128"); break;
goetz@42065 442 case Cipher::_EnccryptedAES192: tty->print_cr(" available: KM Encrypted-AES-192"); break;
goetz@42065 443 case Cipher::_EnccryptedAES256: tty->print_cr(" available: KM Encrypted-AES-256"); break;
goetz@42065 444 case Cipher::_XTSAES128: tty->print_cr(" available: KM XTS-AES-128"); break;
goetz@42065 445 case Cipher::_XTSAES256: tty->print_cr(" available: KM XTS-AES-256"); break;
goetz@42065 446 case Cipher::_EncryptedXTSAES128: tty->print_cr(" available: KM XTS-Encrypted-AES-128"); break;
goetz@42065 447 case Cipher::_EncryptedXTSAES256: tty->print_cr(" available: KM XTS-Encrypted-AES-256"); break;
goetz@42065 448 default: tty->print_cr(" available: unknown KM code %d", i); break;
goetz@42065 449 }
goetz@42065 450 }
goetz@42065 451 }
goetz@42065 452 }
goetz@42065 453 if (test_feature_bit(&_cipher_features[2], -1, (int)Cipher::_featureBits)) {
goetz@42065 454 tty->print_cr(" available Crypto Features of KMC (Cipher Message with Chaining):");
goetz@42065 455 for (unsigned int i = 0; i < Cipher::_featureBits; i++) {
goetz@42065 456 if (test_feature_bit(&_cipher_features[2], i, (int)Cipher::_featureBits)) {
goetz@42065 457 switch (i) {
goetz@42065 458 case Cipher::_Query: tty->print_cr(" available: KMC Query"); break;
goetz@42065 459 case Cipher::_DEA: tty->print_cr(" available: KMC DEA"); break;
goetz@42065 460 case Cipher::_TDEA128: tty->print_cr(" available: KMC TDEA-128"); break;
goetz@42065 461 case Cipher::_TDEA192: tty->print_cr(" available: KMC TDEA-192"); break;
goetz@42065 462 case Cipher::_EncryptedDEA: tty->print_cr(" available: KMC Encrypted DEA"); break;
goetz@42065 463 case Cipher::_EncryptedDEA128: tty->print_cr(" available: KMC Encrypted DEA-128"); break;
goetz@42065 464 case Cipher::_EncryptedDEA192: tty->print_cr(" available: KMC Encrypted DEA-192"); break;
goetz@42065 465 case Cipher::_AES128: tty->print_cr(" available: KMC AES-128"); break;
goetz@42065 466 case Cipher::_AES192: tty->print_cr(" available: KMC AES-192"); break;
goetz@42065 467 case Cipher::_AES256: tty->print_cr(" available: KMC AES-256"); break;
goetz@42065 468 case Cipher::_EnccryptedAES128: tty->print_cr(" available: KMC Encrypted-AES-128"); break;
goetz@42065 469 case Cipher::_EnccryptedAES192: tty->print_cr(" available: KMC Encrypted-AES-192"); break;
goetz@42065 470 case Cipher::_EnccryptedAES256: tty->print_cr(" available: KMC Encrypted-AES-256"); break;
goetz@42065 471 case Cipher::_PRNG: tty->print_cr(" available: KMC PRNG"); break;
goetz@42065 472 default: tty->print_cr(" available: unknown KMC code %d", i); break;
goetz@42065 473 }
goetz@42065 474 }
goetz@42065 475 }
goetz@42065 476 }
goetz@42065 477
goetz@42065 478 if (test_feature_bit(&_msgdigest_features[0], -1, 2*MsgDigest::_featureBits)) {
goetz@42065 479 tty->cr();
goetz@42065 480 tty->print_cr(" available: %s", "Message Digest Functions for SHA");
goetz@42065 481 }
goetz@42065 482 if (test_feature_bit(&_msgdigest_features[0], -1, (int)MsgDigest::_featureBits)) {
goetz@42065 483 tty->print_cr(" available Features of KIMD (Msg Digest):");
goetz@42065 484 for (unsigned int i = 0; i < MsgDigest::_featureBits; i++) {
goetz@42065 485 if (test_feature_bit(&_msgdigest_features[0], i, (int)MsgDigest::_featureBits)) {
goetz@42065 486 switch (i) {
goetz@42065 487 case MsgDigest::_Query: tty->print_cr(" available: KIMD Query"); break;
goetz@42065 488 case MsgDigest::_SHA1: tty->print_cr(" available: KIMD SHA-1"); break;
goetz@42065 489 case MsgDigest::_SHA256: tty->print_cr(" available: KIMD SHA-256"); break;
goetz@42065 490 case MsgDigest::_SHA512: tty->print_cr(" available: KIMD SHA-512"); break;
goetz@42065 491 case MsgDigest::_GHASH: tty->print_cr(" available: KIMD GHASH"); break;
goetz@42065 492 default: tty->print_cr(" available: unknown code %d", i); break;
goetz@42065 493 }
goetz@42065 494 }
goetz@42065 495 }
goetz@42065 496 }
goetz@42065 497 if (test_feature_bit(&_msgdigest_features[2], -1, (int)MsgDigest::_featureBits)) {
goetz@42065 498 tty->print_cr(" available Features of KLMD (Msg Digest):");
goetz@42065 499 for (unsigned int i = 0; i < MsgDigest::_featureBits; i++) {
goetz@42065 500 if (test_feature_bit(&_msgdigest_features[2], i, (int)MsgDigest::_featureBits)) {
goetz@42065 501 switch (i) {
goetz@42065 502 case MsgDigest::_Query: tty->print_cr(" available: KLMD Query"); break;
goetz@42065 503 case MsgDigest::_SHA1: tty->print_cr(" available: KLMD SHA-1"); break;
goetz@42065 504 case MsgDigest::_SHA256: tty->print_cr(" available: KLMD SHA-256"); break;
goetz@42065 505 case MsgDigest::_SHA512: tty->print_cr(" available: KLMD SHA-512"); break;
goetz@42065 506 default: tty->print_cr(" available: unknown code %d", i); break;
goetz@42065 507 }
goetz@42065 508 }
goetz@42065 509 }
goetz@42065 510 }
goetz@42065 511 }
goetz@42065 512 if (ContendedPaddingWidth > 0) {
goetz@42065 513 tty->cr();
goetz@42065 514 tty->print_cr("ContendedPaddingWidth " INTX_FORMAT, ContendedPaddingWidth);
goetz@42065 515 }
goetz@42065 516 }
goetz@42065 517 }
goetz@42065 518
goetz@42065 519 void VM_Version::print_features() {
goetz@42065 520 print_features_internal("Version:");
goetz@42065 521 }
goetz@42065 522
goetz@42065 523 void VM_Version::reset_features(bool reset) {
goetz@42065 524 if (reset) {
goetz@42065 525 for (unsigned int i = 0; i < _features_buffer_len; i++) {
goetz@42065 526 VM_Version::_features[i] = 0;
goetz@42065 527 }
goetz@42065 528 }
goetz@42065 529 }
goetz@42065 530
goetz@42065 531 void VM_Version::set_features_z900(bool reset) {
goetz@42065 532 reset_features(reset);
goetz@42065 533
goetz@42065 534 set_has_long_displacement();
goetz@42065 535 set_has_ETF2();
goetz@42065 536 }
goetz@42065 537
goetz@42065 538 void VM_Version::set_features_z990(bool reset) {
goetz@42065 539 reset_features(reset);
goetz@42065 540
goetz@42065 541 set_features_z900(false);
goetz@42065 542 set_has_ETF3();
goetz@42065 543 set_has_long_displacement_fast();
goetz@42065 544 set_has_HFPMultiplyAndAdd();
goetz@42065 545 }
goetz@42065 546
goetz@42065 547 void VM_Version::set_features_z9(bool reset) {
goetz@42065 548 reset_features(reset);
goetz@42065 549
goetz@42065 550 set_features_z990(false);
goetz@42065 551 set_has_StoreFacilityListExtended();
goetz@42065 552 // set_has_Crypto(); // Do not set, crypto features must be retrieved separately.
goetz@42065 553 set_has_ETF2Enhancements();
goetz@42065 554 set_has_ETF3Enhancements();
goetz@42065 555 set_has_extended_immediate();
goetz@42065 556 set_has_StoreClockFast();
goetz@42065 557 set_has_HFPUnnormalized();
goetz@42065 558 }
goetz@42065 559
goetz@42065 560 void VM_Version::set_features_z10(bool reset) {
goetz@42065 561 reset_features(reset);
goetz@42065 562
goetz@42065 563 set_features_z9(false);
goetz@42065 564 set_has_CompareSwapStore();
goetz@42065 565 set_has_RelativeLoadStore();
goetz@42065 566 set_has_CompareBranch();
goetz@42065 567 set_has_CompareTrap();
goetz@42065 568 set_has_MultiplySingleImm32();
goetz@42065 569 set_has_Prefetch();
goetz@42065 570 set_has_MoveImmToMem();
goetz@42065 571 set_has_MemWithImmALUOps();
goetz@42065 572 set_has_ExecuteExtensions();
goetz@42065 573 set_has_FPSupportEnhancements();
goetz@42065 574 set_has_DecimalFloatingPoint();
goetz@42065 575 set_has_ExtractCPUtime();
goetz@42065 576 set_has_CryptoExt3();
goetz@42065 577 }
goetz@42065 578
goetz@42065 579 void VM_Version::set_features_z196(bool reset) {
goetz@42065 580 reset_features(reset);
goetz@42065 581
goetz@42065 582 set_features_z10(false);
goetz@42065 583 set_has_InterlockedAccessV1();
goetz@42065 584 set_has_PopCount();
goetz@42065 585 set_has_LoadStoreConditional();
goetz@42065 586 set_has_HighWordInstr();
goetz@42065 587 set_has_FastSync();
goetz@42065 588 set_has_FPExtensions();
goetz@42065 589 set_has_DistinctOpnds();
goetz@42065 590 set_has_CryptoExt4();
goetz@42065 591 }
goetz@42065 592
goetz@42065 593 void VM_Version::set_features_ec12(bool reset) {
goetz@42065 594 reset_features(reset);
goetz@42065 595
goetz@42065 596 set_features_z196(false);
goetz@42065 597 set_has_MiscInstrExt();
goetz@42065 598 set_has_InterlockedAccessV2();
goetz@42065 599 set_has_LoadAndALUAtomicV2();
goetz@42065 600 set_has_TxMem();
goetz@42065 601 }
goetz@42065 602
goetz@42065 603 void VM_Version::set_features_z13(bool reset) {
goetz@42065 604 reset_features(reset);
goetz@42065 605
goetz@42065 606 set_features_ec12(false);
goetz@42065 607 set_has_LoadStoreConditional2();
goetz@42065 608 set_has_CryptoExt5();
goetz@42065 609 set_has_VectorFacility();
goetz@42065 610 }
goetz@42065 611
goetz@42065 612 void VM_Version::set_features_from(const char* march) {
goetz@42065 613 bool err = false;
goetz@42065 614 bool prt = false;
goetz@42065 615
goetz@42065 616 if ((march != NULL) && (march[0] != '\0')) {
goetz@42065 617 const int buf_len = 16;
goetz@42065 618 const int hdr_len = 5;
goetz@42065 619 char buf[buf_len];
goetz@42065 620 if (strlen(march) >= hdr_len) {
goetz@42065 621 memcpy(buf, march, hdr_len);
goetz@42065 622 buf[hdr_len] = '\00';
goetz@42065 623 } else {
goetz@42065 624 buf[0] = '\00';
goetz@42065 625 }
goetz@42065 626
goetz@42065 627 if (!strcmp(march, "z900")) {
goetz@42065 628 set_features_z900();
goetz@42065 629 } else if (!strcmp(march, "z990")) {
goetz@42065 630 set_features_z990();
goetz@42065 631 } else if (!strcmp(march, "z9")) {
goetz@42065 632 set_features_z9();
goetz@42065 633 } else if (!strcmp(march, "z10")) {
goetz@42065 634 set_features_z10();
goetz@42065 635 } else if (!strcmp(march, "z196")) {
goetz@42065 636 set_features_z196();
goetz@42065 637 } else if (!strcmp(march, "ec12")) {
goetz@42065 638 set_features_ec12();
goetz@42065 639 } else if (!strcmp(march, "z13")) {
goetz@42065 640 set_features_z13();
goetz@42065 641 } else if (!strcmp(buf, "ztest")) {
goetz@42065 642 assert(!has_TestFeaturesImpl(), "possible facility list flag conflict");
goetz@42065 643 if (strlen(march) > hdr_len) {
goetz@42065 644 int itest = 0;
goetz@42065 645 if ((strlen(march)-hdr_len) >= buf_len) err = true;
goetz@42065 646 if (!err) {
goetz@42065 647 memcpy(buf, &march[hdr_len], strlen(march)-hdr_len);
goetz@42065 648 buf[strlen(march)-hdr_len] = '\00';
goetz@42065 649 for (size_t i = 0; !err && (i < strlen(buf)); i++) {
goetz@42065 650 itest = itest*10 + buf[i]-'0';
goetz@42065 651 err = err || ((buf[i]-'0') < 0) || ((buf[i]-'0') > 9) || (itest > 15);
goetz@42065 652 }
goetz@42065 653 }
goetz@42065 654 if (!err) {
goetz@42065 655 prt = true;
goetz@42065 656 if (itest & 0x01) { set_has_TestFeature1Impl(); }
goetz@42065 657 if (itest & 0x02) { set_has_TestFeature2Impl(); }
goetz@42065 658 if (itest & 0x04) { set_has_TestFeature4Impl(); }
goetz@42065 659 if (itest & 0x08) { set_has_TestFeature8Impl(); }
goetz@42065 660 }
goetz@42065 661 } else {
goetz@42065 662 prt = true;
goetz@42065 663 set_has_TestFeature1Impl();
goetz@42065 664 set_has_TestFeature2Impl();
goetz@42065 665 set_has_TestFeature4Impl();
goetz@42065 666 set_has_TestFeature8Impl();
goetz@42065 667 }
goetz@42065 668 } else {
goetz@42065 669 err = true;
goetz@42065 670 }
goetz@42065 671 if (!err) {
goetz@42065 672 set_features_string();
goetz@42065 673 if (prt || PrintAssembly) {
goetz@42065 674 print_features_internal("CPU Version as set by cmdline option:", prt);
goetz@42065 675 }
goetz@42065 676 } else {
goetz@42065 677 tty->print_cr("***Warning: Unsupported ProcessorArchitecture: %s, internal settings left undisturbed.", march);
goetz@42065 678 }
goetz@42065 679 }
goetz@42065 680
goetz@42065 681 }
goetz@42065 682
goetz@42065 683 static long (*getFeatures)(unsigned long*, int, int) = NULL;
goetz@42065 684
goetz@42065 685 void VM_Version::set_getFeatures(address entryPoint) {
goetz@42065 686 if (getFeatures == NULL) {
goetz@42065 687 getFeatures = (long(*)(unsigned long*, int, int))entryPoint;
goetz@42065 688 }
goetz@42065 689 }
goetz@42065 690
goetz@42065 691 long VM_Version::call_getFeatures(unsigned long* buffer, int buflen, int functionCode) {
goetz@42065 692 VM_Version::_is_determine_features_test_running = true;
goetz@42065 693 long functionResult = (*getFeatures)(buffer, buflen, functionCode);
goetz@42065 694 VM_Version::_is_determine_features_test_running = false;
goetz@42065 695 return functionResult;
goetz@42065 696 }
goetz@42065 697
goetz@42065 698 // Helper function for "extract cache attribute" instruction.
goetz@42065 699 int VM_Version::calculate_ECAG_functionCode(unsigned int attributeIndication,
goetz@42065 700 unsigned int levelIndication,
goetz@42065 701 unsigned int typeIndication) {
goetz@42065 702 return (attributeIndication<<4) | (levelIndication<<1) | typeIndication;
goetz@42065 703 }
goetz@42065 704
goetz@42065 705 void VM_Version::determine_features() {
goetz@42065 706
goetz@42065 707 const int cbuf_size = _code_buffer_len;
goetz@42065 708 const int buf_len = _features_buffer_len;
goetz@42065 709
goetz@42065 710 // Allocate code buffer space for the detection code.
goetz@42065 711 ResourceMark rm;
goetz@42065 712 CodeBuffer cbuf("determine CPU features", cbuf_size, 0);
goetz@42065 713 MacroAssembler* a = new MacroAssembler(&cbuf);
goetz@42065 714
goetz@42065 715 // Emit code.
goetz@42065 716 set_getFeatures(a->pc());
goetz@42065 717 address code = a->pc();
goetz@42065 718
goetz@42065 719 // Try STFLE. Possible INVOP will cause defaults to be used.
goetz@42065 720 Label getFEATURES;
goetz@42065 721 Label getCPUFEATURES; // fcode = -1 (cache)
goetz@42065 722 Label getCIPHERFEATURES; // fcode = -2 (cipher)
goetz@42065 723 Label getMSGDIGESTFEATURES; // fcode = -3 (SHA)
lucy@47762 724 Label getVECTORFEATURES; // fcode = -4 (OS support for vector instructions)
goetz@42065 725 Label errRTN;
goetz@42065 726 a->z_ltgfr(Z_R0, Z_ARG2); // Buf len to r0 and test.
lucy@47762 727 a->z_brl(getFEATURES); // negative -> Get machine features not covered by facility list.
lucy@47830 728 a->z_lghi(Z_R1,0);
lucy@47830 729 a->z_brz(errRTN); // zero -> Function code currently not used, indicate "aborted".
lucy@47830 730
goetz@42065 731 a->z_aghi(Z_R0, -1);
goetz@42065 732 a->z_stfle(0, Z_ARG1);
goetz@42065 733 a->z_lg(Z_R1, 0, Z_ARG1); // Get first DW of facility list.
goetz@42065 734 a->z_lgr(Z_RET, Z_R0); // Calculate rtn value for success.
goetz@42065 735 a->z_la(Z_RET, 1, Z_RET);
goetz@42065 736 a->z_brnz(errRTN); // Instr failed if non-zero CC.
goetz@42065 737 a->z_ltgr(Z_R1, Z_R1); // Instr failed if first DW == 0.
goetz@42065 738 a->z_bcr(Assembler::bcondNotZero, Z_R14); // Successful return.
goetz@42065 739
goetz@42065 740 a->bind(errRTN);
goetz@42065 741 a->z_lngr(Z_RET, Z_RET);
goetz@42065 742 a->z_ltgr(Z_R1, Z_R1);
goetz@42065 743 a->z_bcr(Assembler::bcondNotZero, Z_R14); // Return "buffer too small".
goetz@42065 744 a->z_xgr(Z_RET, Z_RET);
goetz@42065 745 a->z_br(Z_R14); // Return "operation aborted".
goetz@42065 746
goetz@42065 747 a->bind(getFEATURES);
goetz@42065 748 a->z_cghi(Z_R0, -1); // -1: Extract CPU attributes, currently: cache layout only.
goetz@42065 749 a->z_bre(getCPUFEATURES);
goetz@42065 750 a->z_cghi(Z_R0, -2); // -2: Extract detailed crypto capabilities (cipher instructions).
goetz@42065 751 a->z_bre(getCIPHERFEATURES);
goetz@42065 752 a->z_cghi(Z_R0, -3); // -3: Extract detailed crypto capabilities (msg digest instructions).
goetz@42065 753 a->z_bre(getMSGDIGESTFEATURES);
lucy@47762 754 a->z_cghi(Z_R0, -4); // -4: Verify vector instruction availability (OS support).
lucy@47762 755 a->z_bre(getVECTORFEATURES);
goetz@42065 756
goetz@42065 757 a->z_xgr(Z_RET, Z_RET); // Not a valid function code.
goetz@42065 758 a->z_br(Z_R14); // Return "operation aborted".
goetz@42065 759
goetz@42065 760 // Try KIMD/KLMD query function to get details about msg digest (secure hash, SHA) instructions.
goetz@42065 761 a->bind(getMSGDIGESTFEATURES);
goetz@42065 762 a->z_lghi(Z_R0,(int)MsgDigest::_Query); // query function code
goetz@42065 763 a->z_lgr(Z_R1,Z_R2); // param block addr, 2*16 bytes min size
goetz@42065 764 a->z_kimd(Z_R2,Z_R2); // Get available KIMD functions (bit pattern in param blk).
goetz@42065 765 a->z_la(Z_R1,16,Z_R1); // next param block addr
goetz@42065 766 a->z_klmd(Z_R2,Z_R2); // Get available KLMD functions (bit pattern in param blk).
goetz@42065 767 a->z_lghi(Z_RET,4);
goetz@42065 768 a->z_br(Z_R14);
goetz@42065 769
goetz@42065 770 // Try KM/KMC query function to get details about crypto instructions.
goetz@42065 771 a->bind(getCIPHERFEATURES);
goetz@42065 772 a->z_lghi(Z_R0,(int)Cipher::_Query); // query function code
goetz@42065 773 a->z_lgr(Z_R1,Z_R2); // param block addr, 2*16 bytes min size (KIMD/KLMD output)
goetz@42065 774 a->z_km(Z_R2,Z_R2); // get available KM functions
goetz@42065 775 a->z_la(Z_R1,16,Z_R1); // next param block addr
goetz@42065 776 a->z_kmc(Z_R2,Z_R2); // get available KMC functions
goetz@42065 777 a->z_lghi(Z_RET,4);
goetz@42065 778 a->z_br(Z_R14);
goetz@42065 779
goetz@42065 780 // Use EXTRACT CPU ATTRIBUTE instruction to get information about cache layout.
goetz@42065 781 a->bind(getCPUFEATURES);
goetz@42065 782 a->z_xgr(Z_R0,Z_R0); // as recommended in instruction documentation
goetz@42065 783 a->z_ecag(Z_RET,Z_R0,0,Z_ARG3); // Extract information as requested by Z_ARG1 contents.
goetz@42065 784 a->z_br(Z_R14);
goetz@42065 785
lucy@47762 786 // Use a vector instruction to verify OS support. Will fail with SIGFPE if OS support is missing.
lucy@47762 787 a->bind(getVECTORFEATURES);
lucy@47762 788 a->z_vtm(Z_V0,Z_V0); // non-destructive vector instruction. Will cause SIGFPE if not supported.
lucy@47762 789 a->z_br(Z_R14);
lucy@47762 790
goetz@42065 791 address code_end = a->pc();
goetz@42065 792 a->flush();
goetz@42065 793
goetz@42065 794 // Print the detection code.
goetz@42065 795 bool printVerbose = Verbose || PrintAssembly || PrintStubCode;
goetz@42065 796 if (printVerbose) {
goetz@42065 797 ttyLocker ttyl;
goetz@42065 798 tty->print_cr("Decoding CPU feature detection stub at " INTPTR_FORMAT " before execution:", p2i(code));
goetz@42065 799 tty->print_cr("Stub length is %ld bytes, codebuffer reserves %d bytes, %ld bytes spare.",
goetz@42065 800 code_end-code, cbuf_size, cbuf_size-(code_end-code));
goetz@42065 801
goetz@42065 802 // Use existing decode function. This enables the [Code] format which is needed to DecodeErrorFile.
goetz@42065 803 Disassembler::decode((u_char*)code, (u_char*)code_end, tty);
goetz@42065 804 }
goetz@42065 805
goetz@42065 806 // Prepare for detection code execution and clear work buffer.
goetz@42065 807 _nfeatures = 0;
goetz@42065 808 _ncipher_features = 0;
goetz@42065 809 unsigned long buffer[buf_len];
goetz@42065 810
goetz@42065 811 for (int i = 0; i < buf_len; i++) {
goetz@42065 812 buffer[i] = 0L;
goetz@42065 813 }
goetz@42065 814
goetz@42065 815 // execute code
goetz@42065 816 // Illegal instructions will be replaced by 0 in signal handler.
goetz@42065 817 // In case of problems, call_getFeatures will return a not-positive result.
goetz@42065 818 long used_len = call_getFeatures(buffer, buf_len, 0);
goetz@42065 819
goetz@42065 820 bool ok;
goetz@42065 821 if (used_len == 1) {
goetz@42065 822 ok = true;
goetz@42065 823 } else if (used_len > 1) {
goetz@42065 824 unsigned int used_lenU = (unsigned int)used_len;
goetz@42065 825 ok = true;
goetz@42065 826 for (unsigned int i = 1; i < used_lenU; i++) {
goetz@42065 827 ok = ok && (buffer[i] == 0L);
goetz@42065 828 }
goetz@42065 829 if (printVerbose && !ok) {
goetz@42065 830 bool compact = false;
goetz@42065 831 tty->print_cr("Note: feature list has %d (i.e. more than one) array elements.", used_lenU);
goetz@42065 832 if (compact) {
goetz@42065 833 tty->print("non-zero feature list elements:");
goetz@42065 834 for (unsigned int i = 0; i < used_lenU; i++) {
goetz@42065 835 tty->print(" [%d]: 0x%16.16lx", i, buffer[i]);
goetz@42065 836 }
goetz@42065 837 tty->cr();
goetz@42065 838 } else {
goetz@42065 839 for (unsigned int i = 0; i < used_lenU; i++) {
goetz@42065 840 tty->print_cr("non-zero feature list[%d]: 0x%16.16lx", i, buffer[i]);
goetz@42065 841 }
goetz@42065 842 }
goetz@42065 843
goetz@42065 844 if (compact) {
goetz@42065 845 tty->print_cr("Active features (compact view):");
goetz@42065 846 for (unsigned int k = 0; k < used_lenU; k++) {
goetz@42065 847 tty->print_cr(" buffer[%d]:", k);
goetz@42065 848 for (unsigned int j = k*sizeof(long); j < (k+1)*sizeof(long); j++) {
goetz@42065 849 bool line = false;
goetz@42065 850 for (unsigned int i = j*8; i < (j+1)*8; i++) {
goetz@42065 851 bool bit = test_feature_bit(buffer, i, used_lenU*sizeof(long)*8);
goetz@42065 852 if (bit) {
goetz@42065 853 if (!line) {
goetz@42065 854 tty->print(" byte[%d]:", j);
goetz@42065 855 line = true;
goetz@42065 856 }
goetz@42065 857 tty->print(" [%3.3d]", i);
goetz@42065 858 }
goetz@42065 859 }
goetz@42065 860 if (line) {
goetz@42065 861 tty->cr();
goetz@42065 862 }
goetz@42065 863 }
goetz@42065 864 }
goetz@42065 865 } else {
goetz@42065 866 tty->print_cr("Active features (full view):");
goetz@42065 867 for (unsigned int k = 0; k < used_lenU; k++) {
goetz@42065 868 tty->print_cr(" buffer[%d]:", k);
goetz@42065 869 for (unsigned int j = k*sizeof(long); j < (k+1)*sizeof(long); j++) {
goetz@42065 870 tty->print(" byte[%d]:", j);
goetz@42065 871 for (unsigned int i = j*8; i < (j+1)*8; i++) {
goetz@42065 872 bool bit = test_feature_bit(buffer, i, used_lenU*sizeof(long)*8);
goetz@42065 873 if (bit) {
goetz@42065 874 tty->print(" [%3.3d]", i);
goetz@42065 875 } else {
goetz@42065 876 tty->print(" ");
goetz@42065 877 }
goetz@42065 878 }
goetz@42065 879 tty->cr();
goetz@42065 880 }
goetz@42065 881 }
goetz@42065 882 }
goetz@42065 883 }
goetz@42065 884 ok = true;
goetz@42065 885 } else { // No features retrieved if we reach here. Buffer too short or instr not available.
goetz@42065 886 if (used_len < 0) {
goetz@42065 887 ok = false;
goetz@42065 888 if (printVerbose) {
goetz@42065 889 tty->print_cr("feature list buffer[%d] too short, required: buffer[%ld]", buf_len, -used_len);
goetz@42065 890 }
goetz@42065 891 } else {
goetz@42065 892 if (printVerbose) {
goetz@42065 893 tty->print_cr("feature list could not be retrieved. Running on z900 or z990? Trying to find out...");
goetz@42065 894 }
goetz@42065 895 used_len = call_getFeatures(buffer, 0, 0); // Must provide at least two DW buffer elements!!!!
goetz@42065 896
goetz@42065 897 ok = used_len > 0;
goetz@42065 898 if (ok) {
goetz@42065 899 if (buffer[1]*10 < buffer[0]) {
goetz@42065 900 set_features_z900();
goetz@42065 901 } else {
goetz@42065 902 set_features_z990();
goetz@42065 903 }
goetz@42065 904
goetz@42065 905 if (printVerbose) {
goetz@42065 906 tty->print_cr("Note: high-speed long displacement test used %ld iterations.", used_len);
goetz@42065 907 tty->print_cr(" Positive displacement loads took %8.8lu microseconds.", buffer[1]);
goetz@42065 908 tty->print_cr(" Negative displacement loads took %8.8lu microseconds.", buffer[0]);
goetz@42065 909 if (has_long_displacement_fast()) {
goetz@42065 910 tty->print_cr(" assuming high-speed long displacement IS available.");
goetz@42065 911 } else {
goetz@42065 912 tty->print_cr(" assuming high-speed long displacement is NOT available.");
goetz@42065 913 }
goetz@42065 914 }
goetz@42065 915 } else {
goetz@42065 916 if (printVerbose) {
goetz@42065 917 tty->print_cr("Note: high-speed long displacement test was not successful.");
goetz@42065 918 tty->print_cr(" assuming long displacement is NOT available.");
goetz@42065 919 }
goetz@42065 920 }
goetz@42065 921 return; // Do not copy buffer to _features, no test for cipher features.
goetz@42065 922 }
goetz@42065 923 }
goetz@42065 924
goetz@42065 925 if (ok) {
goetz@42065 926 // Fill features buffer.
goetz@42065 927 // Clear work buffer.
goetz@42065 928 for (int i = 0; i < buf_len; i++) {
goetz@42065 929 _features[i] = buffer[i];
goetz@42065 930 _cipher_features[i] = 0;
goetz@42065 931 _msgdigest_features[i] = 0;
goetz@42065 932 buffer[i] = 0L;
goetz@42065 933 }
goetz@42065 934 _nfeatures = used_len;
goetz@42065 935 } else {
goetz@42065 936 for (int i = 0; i < buf_len; i++) {
goetz@42065 937 _features[i] = 0;
goetz@42065 938 _cipher_features[i] = 0;
goetz@42065 939 _msgdigest_features[i] = 0;
goetz@42065 940 buffer[i] = 0L;
goetz@42065 941 }
goetz@42065 942 _nfeatures = 0;
goetz@42065 943 }
goetz@42065 944
lucy@47762 945 if (has_VectorFacility()) {
lucy@47762 946 // Verify that feature can actually be used. OS support required.
lucy@47762 947 call_getFeatures(buffer, -4, 0);
lucy@47762 948 if (printVerbose) {
lucy@47762 949 ttyLocker ttyl;
lucy@47762 950 if (has_VectorFacility()) {
lucy@47762 951 tty->print_cr(" Vector Facility has been verified to be supported by OS");
lucy@47762 952 } else {
lucy@47762 953 tty->print_cr(" Vector Facility has been disabled - not supported by OS");
lucy@47762 954 }
lucy@47762 955 }
lucy@47762 956 }
lucy@47762 957
goetz@42065 958 // Extract Crypto Facility details.
goetz@42065 959 if (has_Crypto()) {
goetz@42065 960 // Get cipher features.
goetz@42065 961 used_len = call_getFeatures(buffer, -2, 0);
goetz@42065 962 for (int i = 0; i < buf_len; i++) {
goetz@42065 963 _cipher_features[i] = buffer[i];
goetz@42065 964 }
goetz@42065 965 _ncipher_features = used_len;
goetz@42065 966
goetz@42065 967 // Get msg digest features.
goetz@42065 968 used_len = call_getFeatures(buffer, -3, 0);
goetz@42065 969 for (int i = 0; i < buf_len; i++) {
goetz@42065 970 _msgdigest_features[i] = buffer[i];
goetz@42065 971 }
goetz@42065 972 _nmsgdigest_features = used_len;
goetz@42065 973 }
goetz@42065 974
goetz@42065 975 static int levelProperties[_max_cache_levels]; // All property indications per level.
goetz@42065 976 static int levelScope[_max_cache_levels]; // private/shared
goetz@42065 977 static const char* levelScopeText[4] = {"No cache ",
goetz@42065 978 "CPU private",
goetz@42065 979 "shared ",
goetz@42065 980 "reserved "};
goetz@42065 981
goetz@42065 982 static int levelType[_max_cache_levels]; // D/I/mixed
goetz@42065 983 static const char* levelTypeText[4] = {"separate D and I caches",
goetz@42065 984 "I cache only ",
goetz@42065 985 "D-cache only ",
goetz@42065 986 "combined D/I cache "};
goetz@42065 987
goetz@42065 988 static unsigned int levelReserved[_max_cache_levels]; // reserved property bits
goetz@42065 989 static unsigned int levelLineSize[_max_cache_levels];
goetz@42065 990 static unsigned int levelTotalSize[_max_cache_levels];
goetz@42065 991 static unsigned int levelAssociativity[_max_cache_levels];
goetz@42065 992
goetz@42065 993
goetz@42065 994 // Extract Cache Layout details.
goetz@42065 995 if (has_ExtractCPUAttributes() && printVerbose) { // For information only, as of now.
goetz@42065 996 bool lineSize_mismatch;
goetz@42065 997 bool print_something;
goetz@42065 998 long functionResult;
goetz@42065 999 unsigned int attributeIndication = 0; // 0..15
goetz@42065 1000 unsigned int levelIndication = 0; // 0..8
goetz@42065 1001 unsigned int typeIndication = 0; // 0..1 (D-Cache, I-Cache)
goetz@42065 1002 int functionCode = calculate_ECAG_functionCode(attributeIndication, levelIndication, typeIndication);
goetz@42065 1003
goetz@42065 1004 // Get cache topology.
goetz@42065 1005 functionResult = call_getFeatures(buffer, -1, functionCode);
goetz@42065 1006
goetz@42065 1007 for (unsigned int i = 0; i < _max_cache_levels; i++) {
goetz@42065 1008 if (functionResult > 0) {
goetz@42065 1009 int shiftVal = 8*(_max_cache_levels-(i+1));
goetz@42065 1010 levelProperties[i] = (functionResult & (0xffUL<<shiftVal)) >> shiftVal;
goetz@42065 1011 levelReserved[i] = (levelProperties[i] & 0xf0) >> 4;
goetz@42065 1012 levelScope[i] = (levelProperties[i] & 0x0c) >> 2;
goetz@42065 1013 levelType[i] = (levelProperties[i] & 0x03);
goetz@42065 1014 } else {
goetz@42065 1015 levelProperties[i] = 0;
goetz@42065 1016 levelReserved[i] = 0;
goetz@42065 1017 levelScope[i] = 0;
goetz@42065 1018 levelType[i] = 0;
goetz@42065 1019 }
goetz@42065 1020 levelLineSize[i] = 0;
goetz@42065 1021 levelTotalSize[i] = 0;
goetz@42065 1022 levelAssociativity[i] = 0;
goetz@42065 1023 }
goetz@42065 1024
goetz@42065 1025 tty->cr();
goetz@42065 1026 tty->print_cr("------------------------------------");
goetz@42065 1027 tty->print_cr("--- Cache Topology Information ---");
goetz@42065 1028 tty->print_cr("------------------------------------");
goetz@42065 1029 for (unsigned int i = 0; (i < _max_cache_levels) && (levelProperties[i] != 0); i++) {
goetz@42065 1030 tty->print_cr(" Cache Level %d: <scope> %s | <type> %s",
goetz@42065 1031 i+1, levelScopeText[levelScope[i]], levelTypeText[levelType[i]]);
goetz@42065 1032 }
goetz@42065 1033
goetz@42065 1034 // Get D-cache details per level.
goetz@42065 1035 _Dcache_lineSize = 0;
goetz@42065 1036 lineSize_mismatch = false;
goetz@42065 1037 print_something = false;
goetz@42065 1038 typeIndication = 0; // 0..1 (D-Cache, I-Cache)
goetz@42065 1039 for (unsigned int i = 0; (i < _max_cache_levels) && (levelProperties[i] != 0); i++) {
goetz@42065 1040 if ((levelType[i] == 0) || (levelType[i] == 2)) {
goetz@42065 1041 print_something = true;
goetz@42065 1042
goetz@42065 1043 // Get cache line size of level i.
goetz@42065 1044 attributeIndication = 1;
goetz@42065 1045 functionCode = calculate_ECAG_functionCode(attributeIndication, i, typeIndication);
goetz@42065 1046 levelLineSize[i] = (unsigned int)call_getFeatures(buffer, -1, functionCode);
goetz@42065 1047
goetz@42065 1048 // Get cache total size of level i.
goetz@42065 1049 attributeIndication = 2;
goetz@42065 1050 functionCode = calculate_ECAG_functionCode(attributeIndication, i, typeIndication);
goetz@42065 1051 levelTotalSize[i] = (unsigned int)call_getFeatures(buffer, -1, functionCode);
goetz@42065 1052
goetz@42065 1053 // Get cache associativity of level i.
goetz@42065 1054 attributeIndication = 3;
goetz@42065 1055 functionCode = calculate_ECAG_functionCode(attributeIndication, i, typeIndication);
goetz@42065 1056 levelAssociativity[i] = (unsigned int)call_getFeatures(buffer, -1, functionCode);
goetz@42065 1057
goetz@42065 1058 _Dcache_lineSize = _Dcache_lineSize == 0 ? levelLineSize[i] : _Dcache_lineSize;
goetz@42065 1059 lineSize_mismatch = lineSize_mismatch || (_Dcache_lineSize != levelLineSize[i]);
goetz@42065 1060 } else {
goetz@42065 1061 levelLineSize[i] = 0;
goetz@42065 1062 }
goetz@42065 1063 }
goetz@42065 1064
goetz@42065 1065 if (print_something) {
goetz@42065 1066 tty->cr();
goetz@42065 1067 tty->print_cr("------------------------------------");
goetz@42065 1068 tty->print_cr("--- D-Cache Detail Information ---");
goetz@42065 1069 tty->print_cr("------------------------------------");
goetz@42065 1070 if (lineSize_mismatch) {
goetz@42065 1071 tty->print_cr("WARNING: D-Cache line size mismatch!");
goetz@42065 1072 }
goetz@42065 1073 for (unsigned int i = 0; (i < _max_cache_levels) && (levelProperties[i] != 0); i++) {
goetz@42065 1074 if (levelLineSize[i] > 0) {
goetz@42065 1075 tty->print_cr(" D-Cache Level %d: line size = %4d, total size = %6dKB, associativity = %2d",
goetz@42065 1076 i+1, levelLineSize[i], levelTotalSize[i]/(int)K, levelAssociativity[i]);
goetz@42065 1077 }
goetz@42065 1078 }
goetz@42065 1079 }
goetz@42065 1080
goetz@42065 1081 // Get I-cache details per level.
goetz@42065 1082 _Icache_lineSize = 0;
goetz@42065 1083 lineSize_mismatch = false;
goetz@42065 1084 print_something = false;
goetz@42065 1085 typeIndication = 1; // 0..1 (D-Cache, I-Cache)
goetz@42065 1086 for (unsigned int i = 0; (i < _max_cache_levels) && (levelProperties[i] != 0); i++) {
goetz@42065 1087 if ((levelType[i] == 0) || (levelType[i] == 1)) {
goetz@42065 1088 print_something = true;
goetz@42065 1089
goetz@42065 1090 // Get cache line size of level i.
goetz@42065 1091 attributeIndication = 1;
goetz@42065 1092 functionCode = calculate_ECAG_functionCode(attributeIndication, i, typeIndication);
goetz@42065 1093 levelLineSize[i] = (unsigned int)call_getFeatures(buffer, -1, functionCode);
goetz@42065 1094
goetz@42065 1095 // Get cache total size of level i.
goetz@42065 1096 attributeIndication = 2;
goetz@42065 1097 functionCode = calculate_ECAG_functionCode(attributeIndication, i, typeIndication);
goetz@42065 1098 levelTotalSize[i] = (unsigned int)call_getFeatures(buffer, -1, functionCode);
goetz@42065 1099
goetz@42065 1100 // Get cache associativity of level i.
goetz@42065 1101 attributeIndication = 3;
goetz@42065 1102 functionCode = calculate_ECAG_functionCode(attributeIndication, i, typeIndication);
goetz@42065 1103 levelAssociativity[i] = (unsigned int)call_getFeatures(buffer, -1, functionCode);
goetz@42065 1104
goetz@42065 1105 _Icache_lineSize = _Icache_lineSize == 0 ? levelLineSize[i] : _Icache_lineSize;
goetz@42065 1106 lineSize_mismatch = lineSize_mismatch || (_Icache_lineSize != levelLineSize[i]);
goetz@42065 1107 } else {
goetz@42065 1108 levelLineSize[i] = 0;
goetz@42065 1109 }
goetz@42065 1110 }
goetz@42065 1111
goetz@42065 1112 if (print_something) {
goetz@42065 1113 tty->cr();
goetz@42065 1114 tty->print_cr("------------------------------------");
goetz@42065 1115 tty->print_cr("--- I-Cache Detail Information ---");
goetz@42065 1116 tty->print_cr("------------------------------------");
goetz@42065 1117 if (lineSize_mismatch) {
goetz@42065 1118 tty->print_cr("WARNING: I-Cache line size mismatch!");
goetz@42065 1119 }
goetz@42065 1120 for (unsigned int i = 0; (i < _max_cache_levels) && (levelProperties[i] != 0); i++) {
goetz@42065 1121 if (levelLineSize[i] > 0) {
goetz@42065 1122 tty->print_cr(" I-Cache Level %d: line size = %4d, total size = %6dKB, associativity = %2d",
goetz@42065 1123 i+1, levelLineSize[i], levelTotalSize[i]/(int)K, levelAssociativity[i]);
goetz@42065 1124 }
goetz@42065 1125 }
goetz@42065 1126 }
goetz@42065 1127
goetz@42065 1128 // Get D/I-cache details per level.
goetz@42065 1129 lineSize_mismatch = false;
goetz@42065 1130 print_something = false;
goetz@42065 1131 typeIndication = 0; // 0..1 (D-Cache, I-Cache)
goetz@42065 1132 for (unsigned int i = 0; (i < _max_cache_levels) && (levelProperties[i] != 0); i++) {
goetz@42065 1133 if (levelType[i] == 3) {
goetz@42065 1134 print_something = true;
goetz@42065 1135
goetz@42065 1136 // Get cache line size of level i.
goetz@42065 1137 attributeIndication = 1;
goetz@42065 1138 functionCode = calculate_ECAG_functionCode(attributeIndication, i, typeIndication);
goetz@42065 1139 levelLineSize[i] = (unsigned int)call_getFeatures(buffer, -1, functionCode);
goetz@42065 1140
goetz@42065 1141 // Get cache total size of level i.
goetz@42065 1142 attributeIndication = 2;
goetz@42065 1143 functionCode = calculate_ECAG_functionCode(attributeIndication, i, typeIndication);
goetz@42065 1144 levelTotalSize[i] = (unsigned int)call_getFeatures(buffer, -1, functionCode);
goetz@42065 1145
goetz@42065 1146 // Get cache associativity of level i.
goetz@42065 1147 attributeIndication = 3;
goetz@42065 1148 functionCode = calculate_ECAG_functionCode(attributeIndication, i, typeIndication);
goetz@42065 1149 levelAssociativity[i] = (unsigned int)call_getFeatures(buffer, -1, functionCode);
goetz@42065 1150
goetz@42065 1151 _Dcache_lineSize = _Dcache_lineSize == 0 ? levelLineSize[i] : _Dcache_lineSize;
goetz@42065 1152 _Icache_lineSize = _Icache_lineSize == 0 ? levelLineSize[i] : _Icache_lineSize;
goetz@42065 1153 lineSize_mismatch = lineSize_mismatch || (_Dcache_lineSize != levelLineSize[i])
goetz@42065 1154 || (_Icache_lineSize != levelLineSize[i]);
goetz@42065 1155 } else {
goetz@42065 1156 levelLineSize[i] = 0;
goetz@42065 1157 }
goetz@42065 1158 }
goetz@42065 1159
goetz@42065 1160 if (print_something) {
goetz@42065 1161 tty->cr();
goetz@42065 1162 tty->print_cr("--------------------------------------");
goetz@42065 1163 tty->print_cr("--- D/I-Cache Detail Information ---");
goetz@42065 1164 tty->print_cr("--------------------------------------");
goetz@42065 1165 if (lineSize_mismatch) {
goetz@42065 1166 tty->print_cr("WARNING: D/I-Cache line size mismatch!");
goetz@42065 1167 }
goetz@42065 1168 for (unsigned int i = 0; (i < _max_cache_levels) && (levelProperties[i] != 0); i++) {
goetz@42065 1169 if (levelLineSize[i] > 0) {
goetz@42065 1170 tty->print_cr(" D/I-Cache Level %d: line size = %4d, total size = %6dKB, associativity = %2d",
goetz@42065 1171 i+1, levelLineSize[i], levelTotalSize[i]/(int)K, levelAssociativity[i]);
goetz@42065 1172 }
goetz@42065 1173 }
goetz@42065 1174 }
goetz@42065 1175 tty->cr();
goetz@42065 1176 }
goetz@42065 1177 return;
goetz@42065 1178 }
goetz@42065 1179
goetz@42065 1180 unsigned long VM_Version::z_SIGILL() {
goetz@42065 1181 unsigned long ZeroBuffer = 0;
goetz@42065 1182 unsigned long work;
goetz@42065 1183 asm(
goetz@42065 1184 " LA %[work],%[buffer] \n\t" // Load address of buffer.
goetz@42065 1185 " LARL 14,+6 \n\t" // Load address of faulting instruction.
goetz@42065 1186 " BCR 15,%[work] \n\t" // Branch into buffer, execute whatever is in there.
goetz@42065 1187 : [buffer] "+Q" (ZeroBuffer) /* outputs */
goetz@42065 1188 , [work] "=&a" (work) /* outputs */
goetz@42065 1189 : /* inputs */
goetz@42065 1190 : "cc" /* clobbered */
goetz@42065 1191 );
goetz@42065 1192 return ZeroBuffer;
goetz@42065 1193 }
goetz@42065 1194
goetz@42065 1195 unsigned long VM_Version::z_SIGSEGV() {
goetz@42065 1196 unsigned long ZeroBuffer = 0;
goetz@42065 1197 unsigned long work;
goetz@42065 1198 asm(
goetz@42065 1199 " LG %[work],%[buffer] \n\t" // Load zero address.
goetz@42065 1200 " STG %[work],0(,%[work])\n\t" // Store to address zero.
goetz@42065 1201 : [buffer] "+Q" (ZeroBuffer) /* outputs */
goetz@42065 1202 , [work] "=&a" (work) /* outputs */
goetz@42065 1203 : /* inputs */
goetz@42065 1204 : "cc" /* clobbered */
goetz@42065 1205 );
goetz@42065 1206 return ZeroBuffer;
goetz@42065 1207 }
goetz@42065 1208