annotate src/hotspot/cpu/s390/vm_version_s390.cpp @ 58700:a53c269e9656

changes to the spec of ObjectMethods
author vromero
date Tue, 19 Nov 2019 18:04:39 -0500
parents ddc19ea5059c
children b7b170ba3ba9
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
mbaesken@55788 519 void VM_Version::print_platform_virtualization_info(outputStream* st) {
mbaesken@55788 520 // /proc/sysinfo contains interesting information about
mbaesken@55788 521 // - LPAR
mbaesken@55788 522 // - whole "Box" (CPUs )
mbaesken@55788 523 // - z/VM / KVM (VM<nn>); this is not available in an LPAR-only setup
mbaesken@55788 524 const char* kw[] = { "LPAR", "CPUs", "VM", NULL };
mbaesken@55788 525 const char* info_file = "/proc/sysinfo";
mbaesken@55788 526
mbaesken@55788 527 if (!print_matching_lines_from_file(info_file, st, kw)) {
mbaesken@55788 528 st->print_cr(" <%s Not Available>", info_file);
mbaesken@55788 529 }
mbaesken@55788 530 }
mbaesken@55788 531
goetz@42065 532 void VM_Version::print_features() {
goetz@42065 533 print_features_internal("Version:");
goetz@42065 534 }
goetz@42065 535
goetz@42065 536 void VM_Version::reset_features(bool reset) {
goetz@42065 537 if (reset) {
goetz@42065 538 for (unsigned int i = 0; i < _features_buffer_len; i++) {
goetz@42065 539 VM_Version::_features[i] = 0;
goetz@42065 540 }
goetz@42065 541 }
goetz@42065 542 }
goetz@42065 543
goetz@42065 544 void VM_Version::set_features_z900(bool reset) {
goetz@42065 545 reset_features(reset);
goetz@42065 546
goetz@42065 547 set_has_long_displacement();
goetz@42065 548 set_has_ETF2();
goetz@42065 549 }
goetz@42065 550
goetz@42065 551 void VM_Version::set_features_z990(bool reset) {
goetz@42065 552 reset_features(reset);
goetz@42065 553
goetz@42065 554 set_features_z900(false);
goetz@42065 555 set_has_ETF3();
goetz@42065 556 set_has_long_displacement_fast();
goetz@42065 557 set_has_HFPMultiplyAndAdd();
goetz@42065 558 }
goetz@42065 559
goetz@42065 560 void VM_Version::set_features_z9(bool reset) {
goetz@42065 561 reset_features(reset);
goetz@42065 562
goetz@42065 563 set_features_z990(false);
goetz@42065 564 set_has_StoreFacilityListExtended();
goetz@42065 565 // set_has_Crypto(); // Do not set, crypto features must be retrieved separately.
goetz@42065 566 set_has_ETF2Enhancements();
goetz@42065 567 set_has_ETF3Enhancements();
goetz@42065 568 set_has_extended_immediate();
goetz@42065 569 set_has_StoreClockFast();
goetz@42065 570 set_has_HFPUnnormalized();
goetz@42065 571 }
goetz@42065 572
goetz@42065 573 void VM_Version::set_features_z10(bool reset) {
goetz@42065 574 reset_features(reset);
goetz@42065 575
goetz@42065 576 set_features_z9(false);
goetz@42065 577 set_has_CompareSwapStore();
goetz@42065 578 set_has_RelativeLoadStore();
goetz@42065 579 set_has_CompareBranch();
goetz@42065 580 set_has_CompareTrap();
goetz@42065 581 set_has_MultiplySingleImm32();
goetz@42065 582 set_has_Prefetch();
goetz@42065 583 set_has_MoveImmToMem();
goetz@42065 584 set_has_MemWithImmALUOps();
goetz@42065 585 set_has_ExecuteExtensions();
goetz@42065 586 set_has_FPSupportEnhancements();
goetz@42065 587 set_has_DecimalFloatingPoint();
goetz@42065 588 set_has_ExtractCPUtime();
goetz@42065 589 set_has_CryptoExt3();
goetz@42065 590 }
goetz@42065 591
goetz@42065 592 void VM_Version::set_features_z196(bool reset) {
goetz@42065 593 reset_features(reset);
goetz@42065 594
goetz@42065 595 set_features_z10(false);
goetz@42065 596 set_has_InterlockedAccessV1();
goetz@42065 597 set_has_PopCount();
goetz@42065 598 set_has_LoadStoreConditional();
goetz@42065 599 set_has_HighWordInstr();
goetz@42065 600 set_has_FastSync();
goetz@42065 601 set_has_FPExtensions();
goetz@42065 602 set_has_DistinctOpnds();
goetz@42065 603 set_has_CryptoExt4();
goetz@42065 604 }
goetz@42065 605
goetz@42065 606 void VM_Version::set_features_ec12(bool reset) {
goetz@42065 607 reset_features(reset);
goetz@42065 608
goetz@42065 609 set_features_z196(false);
goetz@42065 610 set_has_MiscInstrExt();
goetz@42065 611 set_has_InterlockedAccessV2();
goetz@42065 612 set_has_LoadAndALUAtomicV2();
goetz@42065 613 set_has_TxMem();
goetz@42065 614 }
goetz@42065 615
goetz@42065 616 void VM_Version::set_features_z13(bool reset) {
goetz@42065 617 reset_features(reset);
goetz@42065 618
goetz@42065 619 set_features_ec12(false);
goetz@42065 620 set_has_LoadStoreConditional2();
goetz@42065 621 set_has_CryptoExt5();
goetz@42065 622 set_has_VectorFacility();
goetz@42065 623 }
goetz@42065 624
goetz@42065 625 void VM_Version::set_features_from(const char* march) {
goetz@42065 626 bool err = false;
goetz@42065 627 bool prt = false;
goetz@42065 628
goetz@42065 629 if ((march != NULL) && (march[0] != '\0')) {
goetz@42065 630 const int buf_len = 16;
goetz@42065 631 const int hdr_len = 5;
goetz@42065 632 char buf[buf_len];
goetz@42065 633 if (strlen(march) >= hdr_len) {
goetz@42065 634 memcpy(buf, march, hdr_len);
goetz@42065 635 buf[hdr_len] = '\00';
goetz@42065 636 } else {
goetz@42065 637 buf[0] = '\00';
goetz@42065 638 }
goetz@42065 639
goetz@42065 640 if (!strcmp(march, "z900")) {
goetz@42065 641 set_features_z900();
goetz@42065 642 } else if (!strcmp(march, "z990")) {
goetz@42065 643 set_features_z990();
goetz@42065 644 } else if (!strcmp(march, "z9")) {
goetz@42065 645 set_features_z9();
goetz@42065 646 } else if (!strcmp(march, "z10")) {
goetz@42065 647 set_features_z10();
goetz@42065 648 } else if (!strcmp(march, "z196")) {
goetz@42065 649 set_features_z196();
goetz@42065 650 } else if (!strcmp(march, "ec12")) {
goetz@42065 651 set_features_ec12();
goetz@42065 652 } else if (!strcmp(march, "z13")) {
goetz@42065 653 set_features_z13();
goetz@42065 654 } else if (!strcmp(buf, "ztest")) {
goetz@42065 655 assert(!has_TestFeaturesImpl(), "possible facility list flag conflict");
goetz@42065 656 if (strlen(march) > hdr_len) {
goetz@42065 657 int itest = 0;
goetz@42065 658 if ((strlen(march)-hdr_len) >= buf_len) err = true;
goetz@42065 659 if (!err) {
goetz@42065 660 memcpy(buf, &march[hdr_len], strlen(march)-hdr_len);
goetz@42065 661 buf[strlen(march)-hdr_len] = '\00';
goetz@42065 662 for (size_t i = 0; !err && (i < strlen(buf)); i++) {
goetz@42065 663 itest = itest*10 + buf[i]-'0';
goetz@42065 664 err = err || ((buf[i]-'0') < 0) || ((buf[i]-'0') > 9) || (itest > 15);
goetz@42065 665 }
goetz@42065 666 }
goetz@42065 667 if (!err) {
goetz@42065 668 prt = true;
goetz@42065 669 if (itest & 0x01) { set_has_TestFeature1Impl(); }
goetz@42065 670 if (itest & 0x02) { set_has_TestFeature2Impl(); }
goetz@42065 671 if (itest & 0x04) { set_has_TestFeature4Impl(); }
goetz@42065 672 if (itest & 0x08) { set_has_TestFeature8Impl(); }
goetz@42065 673 }
goetz@42065 674 } else {
goetz@42065 675 prt = true;
goetz@42065 676 set_has_TestFeature1Impl();
goetz@42065 677 set_has_TestFeature2Impl();
goetz@42065 678 set_has_TestFeature4Impl();
goetz@42065 679 set_has_TestFeature8Impl();
goetz@42065 680 }
goetz@42065 681 } else {
goetz@42065 682 err = true;
goetz@42065 683 }
goetz@42065 684 if (!err) {
goetz@42065 685 set_features_string();
goetz@42065 686 if (prt || PrintAssembly) {
goetz@42065 687 print_features_internal("CPU Version as set by cmdline option:", prt);
goetz@42065 688 }
goetz@42065 689 } else {
goetz@42065 690 tty->print_cr("***Warning: Unsupported ProcessorArchitecture: %s, internal settings left undisturbed.", march);
goetz@42065 691 }
goetz@42065 692 }
goetz@42065 693
goetz@42065 694 }
goetz@42065 695
goetz@42065 696 static long (*getFeatures)(unsigned long*, int, int) = NULL;
goetz@42065 697
goetz@42065 698 void VM_Version::set_getFeatures(address entryPoint) {
goetz@42065 699 if (getFeatures == NULL) {
goetz@42065 700 getFeatures = (long(*)(unsigned long*, int, int))entryPoint;
goetz@42065 701 }
goetz@42065 702 }
goetz@42065 703
goetz@42065 704 long VM_Version::call_getFeatures(unsigned long* buffer, int buflen, int functionCode) {
goetz@42065 705 VM_Version::_is_determine_features_test_running = true;
goetz@42065 706 long functionResult = (*getFeatures)(buffer, buflen, functionCode);
goetz@42065 707 VM_Version::_is_determine_features_test_running = false;
goetz@42065 708 return functionResult;
goetz@42065 709 }
goetz@42065 710
goetz@42065 711 // Helper function for "extract cache attribute" instruction.
goetz@42065 712 int VM_Version::calculate_ECAG_functionCode(unsigned int attributeIndication,
goetz@42065 713 unsigned int levelIndication,
goetz@42065 714 unsigned int typeIndication) {
goetz@42065 715 return (attributeIndication<<4) | (levelIndication<<1) | typeIndication;
goetz@42065 716 }
goetz@42065 717
goetz@42065 718 void VM_Version::determine_features() {
goetz@42065 719
goetz@42065 720 const int cbuf_size = _code_buffer_len;
goetz@42065 721 const int buf_len = _features_buffer_len;
goetz@42065 722
goetz@42065 723 // Allocate code buffer space for the detection code.
goetz@42065 724 ResourceMark rm;
goetz@42065 725 CodeBuffer cbuf("determine CPU features", cbuf_size, 0);
goetz@42065 726 MacroAssembler* a = new MacroAssembler(&cbuf);
goetz@42065 727
goetz@42065 728 // Emit code.
goetz@42065 729 set_getFeatures(a->pc());
goetz@42065 730 address code = a->pc();
goetz@42065 731
goetz@42065 732 // Try STFLE. Possible INVOP will cause defaults to be used.
goetz@42065 733 Label getFEATURES;
goetz@42065 734 Label getCPUFEATURES; // fcode = -1 (cache)
goetz@42065 735 Label getCIPHERFEATURES; // fcode = -2 (cipher)
goetz@42065 736 Label getMSGDIGESTFEATURES; // fcode = -3 (SHA)
lucy@47762 737 Label getVECTORFEATURES; // fcode = -4 (OS support for vector instructions)
goetz@42065 738 Label errRTN;
goetz@42065 739 a->z_ltgfr(Z_R0, Z_ARG2); // Buf len to r0 and test.
lucy@47762 740 a->z_brl(getFEATURES); // negative -> Get machine features not covered by facility list.
lucy@47830 741 a->z_lghi(Z_R1,0);
lucy@47830 742 a->z_brz(errRTN); // zero -> Function code currently not used, indicate "aborted".
lucy@47830 743
goetz@42065 744 a->z_aghi(Z_R0, -1);
goetz@42065 745 a->z_stfle(0, Z_ARG1);
goetz@42065 746 a->z_lg(Z_R1, 0, Z_ARG1); // Get first DW of facility list.
goetz@42065 747 a->z_lgr(Z_RET, Z_R0); // Calculate rtn value for success.
goetz@42065 748 a->z_la(Z_RET, 1, Z_RET);
goetz@42065 749 a->z_brnz(errRTN); // Instr failed if non-zero CC.
goetz@42065 750 a->z_ltgr(Z_R1, Z_R1); // Instr failed if first DW == 0.
goetz@42065 751 a->z_bcr(Assembler::bcondNotZero, Z_R14); // Successful return.
goetz@42065 752
goetz@42065 753 a->bind(errRTN);
goetz@42065 754 a->z_lngr(Z_RET, Z_RET);
goetz@42065 755 a->z_ltgr(Z_R1, Z_R1);
goetz@42065 756 a->z_bcr(Assembler::bcondNotZero, Z_R14); // Return "buffer too small".
goetz@42065 757 a->z_xgr(Z_RET, Z_RET);
goetz@42065 758 a->z_br(Z_R14); // Return "operation aborted".
goetz@42065 759
goetz@42065 760 a->bind(getFEATURES);
goetz@42065 761 a->z_cghi(Z_R0, -1); // -1: Extract CPU attributes, currently: cache layout only.
goetz@42065 762 a->z_bre(getCPUFEATURES);
goetz@42065 763 a->z_cghi(Z_R0, -2); // -2: Extract detailed crypto capabilities (cipher instructions).
goetz@42065 764 a->z_bre(getCIPHERFEATURES);
goetz@42065 765 a->z_cghi(Z_R0, -3); // -3: Extract detailed crypto capabilities (msg digest instructions).
goetz@42065 766 a->z_bre(getMSGDIGESTFEATURES);
lucy@47762 767 a->z_cghi(Z_R0, -4); // -4: Verify vector instruction availability (OS support).
lucy@47762 768 a->z_bre(getVECTORFEATURES);
goetz@42065 769
goetz@42065 770 a->z_xgr(Z_RET, Z_RET); // Not a valid function code.
goetz@42065 771 a->z_br(Z_R14); // Return "operation aborted".
goetz@42065 772
goetz@42065 773 // Try KIMD/KLMD query function to get details about msg digest (secure hash, SHA) instructions.
goetz@42065 774 a->bind(getMSGDIGESTFEATURES);
goetz@42065 775 a->z_lghi(Z_R0,(int)MsgDigest::_Query); // query function code
goetz@42065 776 a->z_lgr(Z_R1,Z_R2); // param block addr, 2*16 bytes min size
goetz@42065 777 a->z_kimd(Z_R2,Z_R2); // Get available KIMD functions (bit pattern in param blk).
goetz@42065 778 a->z_la(Z_R1,16,Z_R1); // next param block addr
goetz@42065 779 a->z_klmd(Z_R2,Z_R2); // Get available KLMD functions (bit pattern in param blk).
goetz@42065 780 a->z_lghi(Z_RET,4);
goetz@42065 781 a->z_br(Z_R14);
goetz@42065 782
goetz@42065 783 // Try KM/KMC query function to get details about crypto instructions.
goetz@42065 784 a->bind(getCIPHERFEATURES);
goetz@42065 785 a->z_lghi(Z_R0,(int)Cipher::_Query); // query function code
goetz@42065 786 a->z_lgr(Z_R1,Z_R2); // param block addr, 2*16 bytes min size (KIMD/KLMD output)
goetz@42065 787 a->z_km(Z_R2,Z_R2); // get available KM functions
goetz@42065 788 a->z_la(Z_R1,16,Z_R1); // next param block addr
goetz@42065 789 a->z_kmc(Z_R2,Z_R2); // get available KMC functions
goetz@42065 790 a->z_lghi(Z_RET,4);
goetz@42065 791 a->z_br(Z_R14);
goetz@42065 792
goetz@42065 793 // Use EXTRACT CPU ATTRIBUTE instruction to get information about cache layout.
goetz@42065 794 a->bind(getCPUFEATURES);
goetz@42065 795 a->z_xgr(Z_R0,Z_R0); // as recommended in instruction documentation
goetz@42065 796 a->z_ecag(Z_RET,Z_R0,0,Z_ARG3); // Extract information as requested by Z_ARG1 contents.
goetz@42065 797 a->z_br(Z_R14);
goetz@42065 798
lucy@47762 799 // Use a vector instruction to verify OS support. Will fail with SIGFPE if OS support is missing.
lucy@47762 800 a->bind(getVECTORFEATURES);
lucy@47762 801 a->z_vtm(Z_V0,Z_V0); // non-destructive vector instruction. Will cause SIGFPE if not supported.
lucy@47762 802 a->z_br(Z_R14);
lucy@47762 803
goetz@42065 804 address code_end = a->pc();
goetz@42065 805 a->flush();
goetz@42065 806
lucy@56313 807 cbuf.insts()->set_end(code_end);
lucy@56313 808
goetz@42065 809 // Print the detection code.
goetz@42065 810 bool printVerbose = Verbose || PrintAssembly || PrintStubCode;
goetz@42065 811 if (printVerbose) {
goetz@42065 812 ttyLocker ttyl;
goetz@42065 813 tty->print_cr("Decoding CPU feature detection stub at " INTPTR_FORMAT " before execution:", p2i(code));
goetz@42065 814 tty->print_cr("Stub length is %ld bytes, codebuffer reserves %d bytes, %ld bytes spare.",
goetz@42065 815 code_end-code, cbuf_size, cbuf_size-(code_end-code));
goetz@42065 816
lucy@56313 817 // Use existing decode function. This enables the [MachCode] format which is needed to DecodeErrorFile.
lucy@56313 818 Disassembler::decode(&cbuf, code, code_end, tty);
goetz@42065 819 }
goetz@42065 820
goetz@42065 821 // Prepare for detection code execution and clear work buffer.
goetz@42065 822 _nfeatures = 0;
goetz@42065 823 _ncipher_features = 0;
goetz@42065 824 unsigned long buffer[buf_len];
goetz@42065 825
goetz@42065 826 for (int i = 0; i < buf_len; i++) {
goetz@42065 827 buffer[i] = 0L;
goetz@42065 828 }
goetz@42065 829
goetz@42065 830 // execute code
goetz@42065 831 // Illegal instructions will be replaced by 0 in signal handler.
goetz@42065 832 // In case of problems, call_getFeatures will return a not-positive result.
goetz@42065 833 long used_len = call_getFeatures(buffer, buf_len, 0);
goetz@42065 834
goetz@42065 835 bool ok;
goetz@42065 836 if (used_len == 1) {
goetz@42065 837 ok = true;
goetz@42065 838 } else if (used_len > 1) {
goetz@42065 839 unsigned int used_lenU = (unsigned int)used_len;
goetz@42065 840 ok = true;
goetz@42065 841 for (unsigned int i = 1; i < used_lenU; i++) {
goetz@42065 842 ok = ok && (buffer[i] == 0L);
goetz@42065 843 }
goetz@42065 844 if (printVerbose && !ok) {
goetz@42065 845 bool compact = false;
goetz@42065 846 tty->print_cr("Note: feature list has %d (i.e. more than one) array elements.", used_lenU);
goetz@42065 847 if (compact) {
goetz@42065 848 tty->print("non-zero feature list elements:");
goetz@42065 849 for (unsigned int i = 0; i < used_lenU; i++) {
goetz@42065 850 tty->print(" [%d]: 0x%16.16lx", i, buffer[i]);
goetz@42065 851 }
goetz@42065 852 tty->cr();
goetz@42065 853 } else {
goetz@42065 854 for (unsigned int i = 0; i < used_lenU; i++) {
goetz@42065 855 tty->print_cr("non-zero feature list[%d]: 0x%16.16lx", i, buffer[i]);
goetz@42065 856 }
goetz@42065 857 }
goetz@42065 858
goetz@42065 859 if (compact) {
goetz@42065 860 tty->print_cr("Active features (compact view):");
goetz@42065 861 for (unsigned int k = 0; k < used_lenU; k++) {
goetz@42065 862 tty->print_cr(" buffer[%d]:", k);
goetz@42065 863 for (unsigned int j = k*sizeof(long); j < (k+1)*sizeof(long); j++) {
goetz@42065 864 bool line = false;
goetz@42065 865 for (unsigned int i = j*8; i < (j+1)*8; i++) {
goetz@42065 866 bool bit = test_feature_bit(buffer, i, used_lenU*sizeof(long)*8);
goetz@42065 867 if (bit) {
goetz@42065 868 if (!line) {
goetz@42065 869 tty->print(" byte[%d]:", j);
goetz@42065 870 line = true;
goetz@42065 871 }
goetz@42065 872 tty->print(" [%3.3d]", i);
goetz@42065 873 }
goetz@42065 874 }
goetz@42065 875 if (line) {
goetz@42065 876 tty->cr();
goetz@42065 877 }
goetz@42065 878 }
goetz@42065 879 }
goetz@42065 880 } else {
goetz@42065 881 tty->print_cr("Active features (full view):");
goetz@42065 882 for (unsigned int k = 0; k < used_lenU; k++) {
goetz@42065 883 tty->print_cr(" buffer[%d]:", k);
goetz@42065 884 for (unsigned int j = k*sizeof(long); j < (k+1)*sizeof(long); j++) {
goetz@42065 885 tty->print(" byte[%d]:", j);
goetz@42065 886 for (unsigned int i = j*8; i < (j+1)*8; i++) {
goetz@42065 887 bool bit = test_feature_bit(buffer, i, used_lenU*sizeof(long)*8);
goetz@42065 888 if (bit) {
goetz@42065 889 tty->print(" [%3.3d]", i);
goetz@42065 890 } else {
goetz@42065 891 tty->print(" ");
goetz@42065 892 }
goetz@42065 893 }
goetz@42065 894 tty->cr();
goetz@42065 895 }
goetz@42065 896 }
goetz@42065 897 }
goetz@42065 898 }
goetz@42065 899 ok = true;
goetz@42065 900 } else { // No features retrieved if we reach here. Buffer too short or instr not available.
goetz@42065 901 if (used_len < 0) {
goetz@42065 902 ok = false;
goetz@42065 903 if (printVerbose) {
goetz@42065 904 tty->print_cr("feature list buffer[%d] too short, required: buffer[%ld]", buf_len, -used_len);
goetz@42065 905 }
goetz@42065 906 } else {
goetz@42065 907 if (printVerbose) {
goetz@42065 908 tty->print_cr("feature list could not be retrieved. Running on z900 or z990? Trying to find out...");
goetz@42065 909 }
goetz@42065 910 used_len = call_getFeatures(buffer, 0, 0); // Must provide at least two DW buffer elements!!!!
goetz@42065 911
goetz@42065 912 ok = used_len > 0;
goetz@42065 913 if (ok) {
goetz@42065 914 if (buffer[1]*10 < buffer[0]) {
goetz@42065 915 set_features_z900();
goetz@42065 916 } else {
goetz@42065 917 set_features_z990();
goetz@42065 918 }
goetz@42065 919
goetz@42065 920 if (printVerbose) {
goetz@42065 921 tty->print_cr("Note: high-speed long displacement test used %ld iterations.", used_len);
goetz@42065 922 tty->print_cr(" Positive displacement loads took %8.8lu microseconds.", buffer[1]);
goetz@42065 923 tty->print_cr(" Negative displacement loads took %8.8lu microseconds.", buffer[0]);
goetz@42065 924 if (has_long_displacement_fast()) {
goetz@42065 925 tty->print_cr(" assuming high-speed long displacement IS available.");
goetz@42065 926 } else {
goetz@42065 927 tty->print_cr(" assuming high-speed long displacement is NOT available.");
goetz@42065 928 }
goetz@42065 929 }
goetz@42065 930 } else {
goetz@42065 931 if (printVerbose) {
goetz@42065 932 tty->print_cr("Note: high-speed long displacement test was not successful.");
goetz@42065 933 tty->print_cr(" assuming long displacement is NOT available.");
goetz@42065 934 }
goetz@42065 935 }
goetz@42065 936 return; // Do not copy buffer to _features, no test for cipher features.
goetz@42065 937 }
goetz@42065 938 }
goetz@42065 939
goetz@42065 940 if (ok) {
goetz@42065 941 // Fill features buffer.
goetz@42065 942 // Clear work buffer.
goetz@42065 943 for (int i = 0; i < buf_len; i++) {
goetz@42065 944 _features[i] = buffer[i];
goetz@42065 945 _cipher_features[i] = 0;
goetz@42065 946 _msgdigest_features[i] = 0;
goetz@42065 947 buffer[i] = 0L;
goetz@42065 948 }
goetz@42065 949 _nfeatures = used_len;
goetz@42065 950 } else {
goetz@42065 951 for (int i = 0; i < buf_len; i++) {
goetz@42065 952 _features[i] = 0;
goetz@42065 953 _cipher_features[i] = 0;
goetz@42065 954 _msgdigest_features[i] = 0;
goetz@42065 955 buffer[i] = 0L;
goetz@42065 956 }
goetz@42065 957 _nfeatures = 0;
goetz@42065 958 }
goetz@42065 959
lucy@47762 960 if (has_VectorFacility()) {
lucy@47762 961 // Verify that feature can actually be used. OS support required.
lucy@47762 962 call_getFeatures(buffer, -4, 0);
lucy@47762 963 if (printVerbose) {
lucy@47762 964 ttyLocker ttyl;
lucy@47762 965 if (has_VectorFacility()) {
lucy@47762 966 tty->print_cr(" Vector Facility has been verified to be supported by OS");
lucy@47762 967 } else {
lucy@47762 968 tty->print_cr(" Vector Facility has been disabled - not supported by OS");
lucy@47762 969 }
lucy@47762 970 }
lucy@47762 971 }
lucy@47762 972
goetz@42065 973 // Extract Crypto Facility details.
goetz@42065 974 if (has_Crypto()) {
goetz@42065 975 // Get cipher features.
goetz@42065 976 used_len = call_getFeatures(buffer, -2, 0);
goetz@42065 977 for (int i = 0; i < buf_len; i++) {
goetz@42065 978 _cipher_features[i] = buffer[i];
goetz@42065 979 }
goetz@42065 980 _ncipher_features = used_len;
goetz@42065 981
goetz@42065 982 // Get msg digest features.
goetz@42065 983 used_len = call_getFeatures(buffer, -3, 0);
goetz@42065 984 for (int i = 0; i < buf_len; i++) {
goetz@42065 985 _msgdigest_features[i] = buffer[i];
goetz@42065 986 }
goetz@42065 987 _nmsgdigest_features = used_len;
goetz@42065 988 }
goetz@42065 989
goetz@42065 990 static int levelProperties[_max_cache_levels]; // All property indications per level.
goetz@42065 991 static int levelScope[_max_cache_levels]; // private/shared
goetz@42065 992 static const char* levelScopeText[4] = {"No cache ",
goetz@42065 993 "CPU private",
goetz@42065 994 "shared ",
goetz@42065 995 "reserved "};
goetz@42065 996
goetz@42065 997 static int levelType[_max_cache_levels]; // D/I/mixed
goetz@42065 998 static const char* levelTypeText[4] = {"separate D and I caches",
goetz@42065 999 "I cache only ",
goetz@42065 1000 "D-cache only ",
goetz@42065 1001 "combined D/I cache "};
goetz@42065 1002
goetz@42065 1003 static unsigned int levelReserved[_max_cache_levels]; // reserved property bits
goetz@42065 1004 static unsigned int levelLineSize[_max_cache_levels];
goetz@42065 1005 static unsigned int levelTotalSize[_max_cache_levels];
goetz@42065 1006 static unsigned int levelAssociativity[_max_cache_levels];
goetz@42065 1007
goetz@42065 1008
goetz@42065 1009 // Extract Cache Layout details.
goetz@42065 1010 if (has_ExtractCPUAttributes() && printVerbose) { // For information only, as of now.
goetz@42065 1011 bool lineSize_mismatch;
goetz@42065 1012 bool print_something;
goetz@42065 1013 long functionResult;
goetz@42065 1014 unsigned int attributeIndication = 0; // 0..15
goetz@42065 1015 unsigned int levelIndication = 0; // 0..8
goetz@42065 1016 unsigned int typeIndication = 0; // 0..1 (D-Cache, I-Cache)
goetz@42065 1017 int functionCode = calculate_ECAG_functionCode(attributeIndication, levelIndication, typeIndication);
goetz@42065 1018
goetz@42065 1019 // Get cache topology.
goetz@42065 1020 functionResult = call_getFeatures(buffer, -1, functionCode);
goetz@42065 1021
goetz@42065 1022 for (unsigned int i = 0; i < _max_cache_levels; i++) {
goetz@42065 1023 if (functionResult > 0) {
goetz@42065 1024 int shiftVal = 8*(_max_cache_levels-(i+1));
goetz@42065 1025 levelProperties[i] = (functionResult & (0xffUL<<shiftVal)) >> shiftVal;
goetz@42065 1026 levelReserved[i] = (levelProperties[i] & 0xf0) >> 4;
goetz@42065 1027 levelScope[i] = (levelProperties[i] & 0x0c) >> 2;
goetz@42065 1028 levelType[i] = (levelProperties[i] & 0x03);
goetz@42065 1029 } else {
goetz@42065 1030 levelProperties[i] = 0;
goetz@42065 1031 levelReserved[i] = 0;
goetz@42065 1032 levelScope[i] = 0;
goetz@42065 1033 levelType[i] = 0;
goetz@42065 1034 }
goetz@42065 1035 levelLineSize[i] = 0;
goetz@42065 1036 levelTotalSize[i] = 0;
goetz@42065 1037 levelAssociativity[i] = 0;
goetz@42065 1038 }
goetz@42065 1039
goetz@42065 1040 tty->cr();
goetz@42065 1041 tty->print_cr("------------------------------------");
goetz@42065 1042 tty->print_cr("--- Cache Topology Information ---");
goetz@42065 1043 tty->print_cr("------------------------------------");
goetz@42065 1044 for (unsigned int i = 0; (i < _max_cache_levels) && (levelProperties[i] != 0); i++) {
goetz@42065 1045 tty->print_cr(" Cache Level %d: <scope> %s | <type> %s",
goetz@42065 1046 i+1, levelScopeText[levelScope[i]], levelTypeText[levelType[i]]);
goetz@42065 1047 }
goetz@42065 1048
goetz@42065 1049 // Get D-cache details per level.
goetz@42065 1050 _Dcache_lineSize = 0;
goetz@42065 1051 lineSize_mismatch = false;
goetz@42065 1052 print_something = false;
goetz@42065 1053 typeIndication = 0; // 0..1 (D-Cache, I-Cache)
goetz@42065 1054 for (unsigned int i = 0; (i < _max_cache_levels) && (levelProperties[i] != 0); i++) {
goetz@42065 1055 if ((levelType[i] == 0) || (levelType[i] == 2)) {
goetz@42065 1056 print_something = true;
goetz@42065 1057
goetz@42065 1058 // Get cache line size of level i.
goetz@42065 1059 attributeIndication = 1;
goetz@42065 1060 functionCode = calculate_ECAG_functionCode(attributeIndication, i, typeIndication);
goetz@42065 1061 levelLineSize[i] = (unsigned int)call_getFeatures(buffer, -1, functionCode);
goetz@42065 1062
goetz@42065 1063 // Get cache total size of level i.
goetz@42065 1064 attributeIndication = 2;
goetz@42065 1065 functionCode = calculate_ECAG_functionCode(attributeIndication, i, typeIndication);
goetz@42065 1066 levelTotalSize[i] = (unsigned int)call_getFeatures(buffer, -1, functionCode);
goetz@42065 1067
goetz@42065 1068 // Get cache associativity of level i.
goetz@42065 1069 attributeIndication = 3;
goetz@42065 1070 functionCode = calculate_ECAG_functionCode(attributeIndication, i, typeIndication);
goetz@42065 1071 levelAssociativity[i] = (unsigned int)call_getFeatures(buffer, -1, functionCode);
goetz@42065 1072
goetz@42065 1073 _Dcache_lineSize = _Dcache_lineSize == 0 ? levelLineSize[i] : _Dcache_lineSize;
goetz@42065 1074 lineSize_mismatch = lineSize_mismatch || (_Dcache_lineSize != levelLineSize[i]);
goetz@42065 1075 } else {
goetz@42065 1076 levelLineSize[i] = 0;
goetz@42065 1077 }
goetz@42065 1078 }
goetz@42065 1079
goetz@42065 1080 if (print_something) {
goetz@42065 1081 tty->cr();
goetz@42065 1082 tty->print_cr("------------------------------------");
goetz@42065 1083 tty->print_cr("--- D-Cache Detail Information ---");
goetz@42065 1084 tty->print_cr("------------------------------------");
goetz@42065 1085 if (lineSize_mismatch) {
goetz@42065 1086 tty->print_cr("WARNING: D-Cache line size mismatch!");
goetz@42065 1087 }
goetz@42065 1088 for (unsigned int i = 0; (i < _max_cache_levels) && (levelProperties[i] != 0); i++) {
goetz@42065 1089 if (levelLineSize[i] > 0) {
goetz@42065 1090 tty->print_cr(" D-Cache Level %d: line size = %4d, total size = %6dKB, associativity = %2d",
goetz@42065 1091 i+1, levelLineSize[i], levelTotalSize[i]/(int)K, levelAssociativity[i]);
goetz@42065 1092 }
goetz@42065 1093 }
goetz@42065 1094 }
goetz@42065 1095
goetz@42065 1096 // Get I-cache details per level.
goetz@42065 1097 _Icache_lineSize = 0;
goetz@42065 1098 lineSize_mismatch = false;
goetz@42065 1099 print_something = false;
goetz@42065 1100 typeIndication = 1; // 0..1 (D-Cache, I-Cache)
goetz@42065 1101 for (unsigned int i = 0; (i < _max_cache_levels) && (levelProperties[i] != 0); i++) {
goetz@42065 1102 if ((levelType[i] == 0) || (levelType[i] == 1)) {
goetz@42065 1103 print_something = true;
goetz@42065 1104
goetz@42065 1105 // Get cache line size of level i.
goetz@42065 1106 attributeIndication = 1;
goetz@42065 1107 functionCode = calculate_ECAG_functionCode(attributeIndication, i, typeIndication);
goetz@42065 1108 levelLineSize[i] = (unsigned int)call_getFeatures(buffer, -1, functionCode);
goetz@42065 1109
goetz@42065 1110 // Get cache total size of level i.
goetz@42065 1111 attributeIndication = 2;
goetz@42065 1112 functionCode = calculate_ECAG_functionCode(attributeIndication, i, typeIndication);
goetz@42065 1113 levelTotalSize[i] = (unsigned int)call_getFeatures(buffer, -1, functionCode);
goetz@42065 1114
goetz@42065 1115 // Get cache associativity of level i.
goetz@42065 1116 attributeIndication = 3;
goetz@42065 1117 functionCode = calculate_ECAG_functionCode(attributeIndication, i, typeIndication);
goetz@42065 1118 levelAssociativity[i] = (unsigned int)call_getFeatures(buffer, -1, functionCode);
goetz@42065 1119
goetz@42065 1120 _Icache_lineSize = _Icache_lineSize == 0 ? levelLineSize[i] : _Icache_lineSize;
goetz@42065 1121 lineSize_mismatch = lineSize_mismatch || (_Icache_lineSize != levelLineSize[i]);
goetz@42065 1122 } else {
goetz@42065 1123 levelLineSize[i] = 0;
goetz@42065 1124 }
goetz@42065 1125 }
goetz@42065 1126
goetz@42065 1127 if (print_something) {
goetz@42065 1128 tty->cr();
goetz@42065 1129 tty->print_cr("------------------------------------");
goetz@42065 1130 tty->print_cr("--- I-Cache Detail Information ---");
goetz@42065 1131 tty->print_cr("------------------------------------");
goetz@42065 1132 if (lineSize_mismatch) {
goetz@42065 1133 tty->print_cr("WARNING: I-Cache line size mismatch!");
goetz@42065 1134 }
goetz@42065 1135 for (unsigned int i = 0; (i < _max_cache_levels) && (levelProperties[i] != 0); i++) {
goetz@42065 1136 if (levelLineSize[i] > 0) {
goetz@42065 1137 tty->print_cr(" I-Cache Level %d: line size = %4d, total size = %6dKB, associativity = %2d",
goetz@42065 1138 i+1, levelLineSize[i], levelTotalSize[i]/(int)K, levelAssociativity[i]);
goetz@42065 1139 }
goetz@42065 1140 }
goetz@42065 1141 }
goetz@42065 1142
goetz@42065 1143 // Get D/I-cache details per level.
goetz@42065 1144 lineSize_mismatch = false;
goetz@42065 1145 print_something = false;
goetz@42065 1146 typeIndication = 0; // 0..1 (D-Cache, I-Cache)
goetz@42065 1147 for (unsigned int i = 0; (i < _max_cache_levels) && (levelProperties[i] != 0); i++) {
goetz@42065 1148 if (levelType[i] == 3) {
goetz@42065 1149 print_something = true;
goetz@42065 1150
goetz@42065 1151 // Get cache line size of level i.
goetz@42065 1152 attributeIndication = 1;
goetz@42065 1153 functionCode = calculate_ECAG_functionCode(attributeIndication, i, typeIndication);
goetz@42065 1154 levelLineSize[i] = (unsigned int)call_getFeatures(buffer, -1, functionCode);
goetz@42065 1155
goetz@42065 1156 // Get cache total size of level i.
goetz@42065 1157 attributeIndication = 2;
goetz@42065 1158 functionCode = calculate_ECAG_functionCode(attributeIndication, i, typeIndication);
goetz@42065 1159 levelTotalSize[i] = (unsigned int)call_getFeatures(buffer, -1, functionCode);
goetz@42065 1160
goetz@42065 1161 // Get cache associativity of level i.
goetz@42065 1162 attributeIndication = 3;
goetz@42065 1163 functionCode = calculate_ECAG_functionCode(attributeIndication, i, typeIndication);
goetz@42065 1164 levelAssociativity[i] = (unsigned int)call_getFeatures(buffer, -1, functionCode);
goetz@42065 1165
goetz@42065 1166 _Dcache_lineSize = _Dcache_lineSize == 0 ? levelLineSize[i] : _Dcache_lineSize;
goetz@42065 1167 _Icache_lineSize = _Icache_lineSize == 0 ? levelLineSize[i] : _Icache_lineSize;
goetz@42065 1168 lineSize_mismatch = lineSize_mismatch || (_Dcache_lineSize != levelLineSize[i])
goetz@42065 1169 || (_Icache_lineSize != levelLineSize[i]);
goetz@42065 1170 } else {
goetz@42065 1171 levelLineSize[i] = 0;
goetz@42065 1172 }
goetz@42065 1173 }
goetz@42065 1174
goetz@42065 1175 if (print_something) {
goetz@42065 1176 tty->cr();
goetz@42065 1177 tty->print_cr("--------------------------------------");
goetz@42065 1178 tty->print_cr("--- D/I-Cache Detail Information ---");
goetz@42065 1179 tty->print_cr("--------------------------------------");
goetz@42065 1180 if (lineSize_mismatch) {
goetz@42065 1181 tty->print_cr("WARNING: D/I-Cache line size mismatch!");
goetz@42065 1182 }
goetz@42065 1183 for (unsigned int i = 0; (i < _max_cache_levels) && (levelProperties[i] != 0); i++) {
goetz@42065 1184 if (levelLineSize[i] > 0) {
goetz@42065 1185 tty->print_cr(" D/I-Cache Level %d: line size = %4d, total size = %6dKB, associativity = %2d",
goetz@42065 1186 i+1, levelLineSize[i], levelTotalSize[i]/(int)K, levelAssociativity[i]);
goetz@42065 1187 }
goetz@42065 1188 }
goetz@42065 1189 }
goetz@42065 1190 tty->cr();
goetz@42065 1191 }
goetz@42065 1192 return;
goetz@42065 1193 }
goetz@42065 1194
goetz@42065 1195 unsigned long VM_Version::z_SIGILL() {
goetz@42065 1196 unsigned long ZeroBuffer = 0;
goetz@42065 1197 unsigned long work;
goetz@42065 1198 asm(
goetz@42065 1199 " LA %[work],%[buffer] \n\t" // Load address of buffer.
goetz@42065 1200 " LARL 14,+6 \n\t" // Load address of faulting instruction.
goetz@42065 1201 " BCR 15,%[work] \n\t" // Branch into buffer, execute whatever is in there.
goetz@42065 1202 : [buffer] "+Q" (ZeroBuffer) /* outputs */
goetz@42065 1203 , [work] "=&a" (work) /* outputs */
goetz@42065 1204 : /* inputs */
goetz@42065 1205 : "cc" /* clobbered */
goetz@42065 1206 );
goetz@42065 1207 return ZeroBuffer;
goetz@42065 1208 }
goetz@42065 1209
goetz@42065 1210 unsigned long VM_Version::z_SIGSEGV() {
goetz@42065 1211 unsigned long ZeroBuffer = 0;
goetz@42065 1212 unsigned long work;
goetz@42065 1213 asm(
goetz@42065 1214 " LG %[work],%[buffer] \n\t" // Load zero address.
goetz@42065 1215 " STG %[work],0(,%[work])\n\t" // Store to address zero.
goetz@42065 1216 : [buffer] "+Q" (ZeroBuffer) /* outputs */
goetz@42065 1217 , [work] "=&a" (work) /* outputs */
goetz@42065 1218 : /* inputs */
goetz@42065 1219 : "cc" /* clobbered */
goetz@42065 1220 );
goetz@42065 1221 return ZeroBuffer;
goetz@42065 1222 }
goetz@42065 1223