1 /*
   2  * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2016, 2018 SAP SE. All rights reserved.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  *
  24  */
  25 
  26 #ifndef CPU_S390_VM_VERSION_S390_HPP
  27 #define CPU_S390_VM_VERSION_S390_HPP
  28 
  29 
  30 #include "runtime/globals_extension.hpp"
  31 #include "runtime/vm_version.hpp"
  32 
  33 class VM_Version: public Abstract_VM_Version {
  34 
  35  protected:
  36 // The following list contains the (approximate) announcement/availability
  37 // dates of the many System z generations in existence as of now which
  38 // implement the z/Architecture.
  39 //   z900: 2000-10
  40 //   z990: 2003-06
  41 //   z9:   2005-09
  42 //   z10:  2007-04
  43 //   z10:  2008-02
  44 //   z196: 2010-08
  45 //   ec12: 2012-09
  46 //   z13:  2015-03
  47 //
  48 // z/Architecture is the name of the 64-bit extension of the 31-bit s390
  49 // architecture.
  50 //
  51 // ----------------------------------------------
  52 // --- FeatureBitString Bits   0.. 63 (DW[0]) ---
  53 // ----------------------------------------------
  54 //                                           11222334445566
  55 //                                        04826048260482604
  56 #define  StoreFacilityListExtendedMask  0x0100000000000000UL  // z9
  57 #define  ETF2Mask                       0x0000800000000000UL  // z900
  58 #define  CryptoFacilityMask             0x0000400000000000UL  // z990
  59 #define  LongDispFacilityMask           0x0000200000000000UL  // z900 with microcode update
  60 #define  LongDispFacilityHighPerfMask   0x0000300000000000UL  // z990
  61 #define  HFPMultiplyAndAddMask          0x0000080000000000UL  // z990
  62 #define  ExtImmedFacilityMask           0x0000040000000000UL  // z9
  63 #define  ETF3Mask                       0x0000020000000000UL  // z990/z9 (?)
  64 #define  HFPUnnormalizedMask            0x0000010000000000UL  // z9
  65 #define  ETF2EnhancementMask            0x0000008000000000UL  // z9
  66 #define  StoreClockFastMask             0x0000004000000000UL  // z9
  67 #define  ParsingEnhancementsMask        0x0000002000000000UL  // z10(?)
  68 #define  ETF3EnhancementMask            0x0000000200000000UL  // z9
  69 #define  ExtractCPUTimeMask             0x0000000100000000UL  // z10
  70 #define  CompareSwapStoreMask           0x00000000c0000000UL  // z10
  71 #define  GnrlInstrExtFacilityMask       0x0000000020000000UL  // z10
  72 #define  ExecuteExtensionsMask          0x0000000010000000UL  // z10
  73 #define  FPExtensionsMask               0x0000000004000000UL  // z196
  74 #define  FPSupportEnhancementsMask      0x0000000000400000UL  // z10
  75 #define  DecimalFloatingPointMask       0x0000000000300000UL  // z10
  76 // z196 begin
  77 #define  DistinctOpndsMask              0x0000000000040000UL  // z196
  78 #define  FastBCRSerializationMask       DistinctOpndsMask
  79 #define  HighWordMask                   DistinctOpndsMask
  80 #define  LoadStoreConditionalMask       DistinctOpndsMask
  81 #define  PopulationCountMask            DistinctOpndsMask
  82 #define  InterlockedAccess1Mask         DistinctOpndsMask
  83 // z196 end
  84 // EC12 begin
  85 #define  DFPZonedConversionMask         0x0000000000008000UL  // ec12
  86 #define  MiscInstrExtMask               0x0000000000004000UL  // ec12
  87 #define  ExecutionHintMask              MiscInstrExtMask
  88 #define  LoadAndTrapMask                MiscInstrExtMask
  89 #define  ProcessorAssistMask            MiscInstrExtMask
  90 #define  ConstrainedTxExecutionMask     0x0000000000002000UL  // ec12
  91 #define  InterlockedAccess2Mask         0x0000000000000800UL  // ec12
  92 // EC12 end
  93 // z13 begin
  94 #define  LoadStoreConditional2Mask      0x0000000000000400UL  // z13
  95 #define  CryptoExtension5Mask           0x0000000000000040UL  // z13
  96 // z13 end
  97 // Feature-DW[0] starts to fill up. Use of these masks is risky.
  98 #define  TestFeature1ImplMask           0x0000000000000001UL
  99 #define  TestFeature2ImplMask           0x0000000000000002UL
 100 #define  TestFeature4ImplMask           0x0000000000000004UL
 101 #define  TestFeature8ImplMask           0x0000000000000008UL
 102 // ----------------------------------------------
 103 // --- FeatureBitString Bits  64..127 (DW[1]) ---
 104 // ----------------------------------------------
 105 //                                                 11111111
 106 //                                        66778889900011222
 107 //                                        48260482604826048
 108 #define  TransactionalExecutionMask     0x0040000000000000UL  // ec12
 109 #define  CryptoExtension3Mask           0x0008000000000000UL  // z196
 110 #define  CryptoExtension4Mask           0x0004000000000000UL  // z196
 111 #define  DFPPackedConversionMask        0x0000800000000000UL  // z13
 112 // ----------------------------------------------
 113 // --- FeatureBitString Bits 128..192 (DW[2]) ---
 114 // ----------------------------------------------
 115 //                                        11111111111111111
 116 //                                        23344455666778889
 117 //                                        82604826048260482
 118 #define  VectorFacilityMask             0x4000000000000000UL  // z13, not avail in VM guest mode!
 119 
 120   enum {
 121     _max_cache_levels = 8,    // As limited by ECAG instruction.
 122     _features_buffer_len = 4, // in DW
 123     _code_buffer_len = 2*256  // For feature detection code.
 124   };
 125   static unsigned long _features[_features_buffer_len];
 126   static unsigned long _cipher_features[_features_buffer_len];
 127   static unsigned long _msgdigest_features[_features_buffer_len];
 128   static unsigned int  _nfeatures;
 129   static unsigned int  _ncipher_features;
 130   static unsigned int  _nmsgdigest_features;
 131   static unsigned int  _Dcache_lineSize;
 132   static unsigned int  _Icache_lineSize;
 133   static bool          _is_determine_features_test_running;
 134   static const char*   _model_string;
 135 
 136   static bool test_feature_bit(unsigned long* featureBuffer, int featureNum, unsigned int bufLen);
 137   static void set_features_string();
 138   static void print_features_internal(const char* text, bool print_anyway=false);
 139   static void determine_features();
 140   static long call_getFeatures(unsigned long* buffer, int buflen, int functionCode);
 141   static void set_getFeatures(address entryPoint);
 142   static int  calculate_ECAG_functionCode(unsigned int attributeIndication,
 143                                           unsigned int levelIndication,
 144                                           unsigned int typeIndication);
 145 
 146   // Setting features via march=z900|z990|z9|z10|z196|ec12|z13|ztest commandline option.
 147   static void reset_features(bool reset);
 148   static void set_features_z900(bool reset = true);
 149   static void set_features_z990(bool reset = true);
 150   static void set_features_z9(bool reset = true);
 151   static void set_features_z10(bool reset = true);
 152   static void set_features_z196(bool reset = true);
 153   static void set_features_ec12(bool reset = true);
 154   static void set_features_z13(bool reset = true);
 155   static void set_features_from(const char* march);
 156 
 157   // Get the CPU type from feature bit settings.
 158   static bool is_z900() { return has_long_displacement()      && !has_long_displacement_fast(); }
 159   static bool is_z990() { return has_long_displacement_fast() && !has_extended_immediate();  }
 160   static bool is_z9()   { return has_extended_immediate()     && !has_GnrlInstrExtensions(); }
 161   static bool is_z10()  { return has_GnrlInstrExtensions()    && !has_DistinctOpnds(); }
 162   static bool is_z196() { return has_DistinctOpnds()          && !has_MiscInstrExt(); }
 163   static bool is_ec12() { return has_MiscInstrExt()           && !has_CryptoExt5(); }
 164   static bool is_z13()  { return has_CryptoExt5();}
 165 
 166   // Get information about cache line sizes.
 167   // As of now and the foreseeable future, line size of all levels will be the same and 256.
 168   static unsigned int Dcache_lineSize(unsigned int level = 0) { return _Dcache_lineSize; }
 169   static unsigned int Icache_lineSize(unsigned int level = 0) { return _Icache_lineSize; }
 170 
 171  public:
 172 
 173   // Need to use nested class with unscoped enum.
 174   // C++11 declaration "enum class Cipher { ... } is not supported.
 175   class CipherMode {
 176     public:
 177       enum {
 178         cipher   = 0x00,
 179         decipher = 0x80
 180       };
 181   };
 182   class Cipher {
 183    public:
 184     enum { // KM only!!! KMC uses different parmBlk sizes.
 185       _Query              =   0,
 186       _DEA                =   1,
 187       _TDEA128            =   2,
 188       _TDEA192            =   3,
 189       _EncryptedDEA       =   9,
 190       _EncryptedDEA128    =  10,
 191       _EncryptedDEA192    =  11,
 192       _AES128             =  18,
 193       _AES192             =  19,
 194       _AES256             =  20,
 195       _EnccryptedAES128   =  26,
 196       _EnccryptedAES192   =  27,
 197       _EnccryptedAES256   =  28,
 198       _XTSAES128          =  50,
 199       _XTSAES256          =  52,
 200       _EncryptedXTSAES128 =  58,
 201       _EncryptedXTSAES256 =  60,
 202       _PRNG               =  67,
 203       _featureBits        = 128,
 204 
 205       // Parameter block sizes (in bytes) for KM instruction.
 206       _Query_parmBlk              =  16,
 207       _DEA_parmBlk                =   8,
 208       _TDEA128_parmBlk            =  16,
 209       _TDEA192_parmBlk            =  24,
 210       _EncryptedDEA_parmBlk       =  32,
 211       _EncryptedDEA128_parmBlk    =  40,
 212       _EncryptedDEA192_parmBlk    =  48,
 213       _AES128_parmBlk             =  16,
 214       _AES192_parmBlk             =  24,
 215       _AES256_parmBlk             =  32,
 216       _EnccryptedAES128_parmBlk   =  48,
 217       _EnccryptedAES192_parmBlk   =  56,
 218       _EnccryptedAES256_parmBlk   =  64,
 219       _XTSAES128_parmBlk          =  32,
 220       _XTSAES256_parmBlk          =  48,
 221       _EncryptedXTSAES128_parmBlk =  64,
 222       _EncryptedXTSAES256_parmBlk =  80,
 223 
 224       // Parameter block sizes (in bytes) for KMC instruction.
 225       _Query_parmBlk_C              =  16,
 226       _DEA_parmBlk_C                =  16,
 227       _TDEA128_parmBlk_C            =  24,
 228       _TDEA192_parmBlk_C            =  32,
 229       _EncryptedDEA_parmBlk_C       =  40,
 230       _EncryptedDEA128_parmBlk_C    =  48,
 231       _EncryptedDEA192_parmBlk_C    =  56,
 232       _AES128_parmBlk_C             =  32,
 233       _AES192_parmBlk_C             =  40,
 234       _AES256_parmBlk_C             =  48,
 235       _EnccryptedAES128_parmBlk_C   =  64,
 236       _EnccryptedAES192_parmBlk_C   =  72,
 237       _EnccryptedAES256_parmBlk_C   =  80,
 238       _XTSAES128_parmBlk_C          =  32,
 239       _XTSAES256_parmBlk_C          =  48,
 240       _EncryptedXTSAES128_parmBlk_C =  64,
 241       _EncryptedXTSAES256_parmBlk_C =  80,
 242       _PRNG_parmBlk_C               =  32,
 243 
 244       // Data block sizes (in bytes).
 245       _Query_dataBlk              =   0,
 246       _DEA_dataBlk                =   8,
 247       _TDEA128_dataBlk            =   8,
 248       _TDEA192_dataBlk            =   8,
 249       _EncryptedDEA_dataBlk       =   8,
 250       _EncryptedDEA128_dataBlk    =   8,
 251       _EncryptedDEA192_dataBlk    =   8,
 252       _AES128_dataBlk             =  16,
 253       _AES192_dataBlk             =  16,
 254       _AES256_dataBlk             =  16,
 255       _EnccryptedAES128_dataBlk   =  16,
 256       _EnccryptedAES192_dataBlk   =  16,
 257       _EnccryptedAES256_dataBlk   =  16,
 258       _XTSAES128_dataBlk          =  16,
 259       _XTSAES256_dataBlk          =  16,
 260       _EncryptedXTSAES128_dataBlk =  16,
 261       _EncryptedXTSAES256_dataBlk =  16,
 262       _PRNG_dataBlk               =   8,
 263     };
 264   };
 265   class MsgDigest {
 266     public:
 267       enum {
 268         _Query            =   0,
 269         _SHA1             =   1,
 270         _SHA256           =   2,
 271         _SHA512           =   3,
 272         _GHASH            =  65,
 273         _featureBits      = 128,
 274 
 275         // Parameter block sizes (in bytes) for KIMD.
 276         _Query_parmBlk_I  =  16,
 277         _SHA1_parmBlk_I   =  20,
 278         _SHA256_parmBlk_I =  32,
 279         _SHA512_parmBlk_I =  64,
 280         _GHASH_parmBlk_I  =  32,
 281 
 282         // Parameter block sizes (in bytes) for KLMD.
 283         _Query_parmBlk_L  =  16,
 284         _SHA1_parmBlk_L   =  28,
 285         _SHA256_parmBlk_L =  40,
 286         _SHA512_parmBlk_L =  80,
 287 
 288         // Data block sizes (in bytes).
 289         _Query_dataBlk    =   0,
 290         _SHA1_dataBlk     =  64,
 291         _SHA256_dataBlk   =  64,
 292         _SHA512_dataBlk   = 128,
 293         _GHASH_dataBlk    =  16
 294       };
 295   };
 296   class MsgAuthent {
 297     public:
 298       enum {
 299         _Query              =   0,
 300         _DEA                =   1,
 301         _TDEA128            =   2,
 302         _TDEA192            =   3,
 303         _EncryptedDEA       =   9,
 304         _EncryptedDEA128    =  10,
 305         _EncryptedDEA192    =  11,
 306         _AES128             =  18,
 307         _AES192             =  19,
 308         _AES256             =  20,
 309         _EnccryptedAES128   =  26,
 310         _EnccryptedAES192   =  27,
 311         _EnccryptedAES256   =  28,
 312         _featureBits        = 128,
 313 
 314         _Query_parmBlk            =  16,
 315         _DEA_parmBlk              =  16,
 316         _TDEA128_parmBlk          =  24,
 317         _TDEA192_parmBlk          =  32,
 318         _EncryptedDEA_parmBlk     =  40,
 319         _EncryptedDEA128_parmBlk  =  48,
 320         _EncryptedDEA192_parmBlk  =  56,
 321         _AES128_parmBlk           =  32,
 322         _AES192_parmBlk           =  40,
 323         _AES256_parmBlk           =  48,
 324         _EnccryptedAES128_parmBlk =  64,
 325         _EnccryptedAES192_parmBlk =  72,
 326         _EnccryptedAES256_parmBlk =  80,
 327 
 328         _Query_dataBlk            =   0,
 329         _DEA_dataBlk              =   8,
 330         _TDEA128_dataBlk          =   8,
 331         _TDEA192_dataBlk          =   8,
 332         _EncryptedDEA_dataBlk     =   8,
 333         _EncryptedDEA128_dataBlk  =   8,
 334         _EncryptedDEA192_dataBlk  =   8,
 335         _AES128_dataBlk           =  16,
 336         _AES192_dataBlk           =  16,
 337         _AES256_dataBlk           =  16,
 338         _EnccryptedAES128_dataBlk =  16,
 339         _EnccryptedAES192_dataBlk =  16,
 340         _EnccryptedAES256_dataBlk =  16
 341       };
 342   };
 343 
 344   // Initialization
 345   static void initialize();
 346   static void print_features();
 347   static bool is_determine_features_test_running() { return _is_determine_features_test_running; }
 348 
 349   // Override Abstract_VM_Version implementation
 350   static void print_platform_virtualization_info(outputStream*);
 351 
 352   // CPU feature query functions
 353   static const char* get_model_string()       { return _model_string; }
 354   static bool has_StoreFacilityListExtended() { return  (_features[0] & StoreFacilityListExtendedMask) == StoreFacilityListExtendedMask; }
 355   static bool has_Crypto()                    { return  (_features[0] & CryptoFacilityMask)            == CryptoFacilityMask; }
 356   static bool has_ETF2()                      { return  (_features[0] & ETF2Mask)                      == ETF2Mask; }
 357   static bool has_ETF3()                      { return  (_features[0] & ETF3Mask)                      == ETF3Mask; }
 358   static bool has_ETF2Enhancements()          { return  (_features[0] & ETF2EnhancementMask)           == ETF2EnhancementMask; }
 359   static bool has_ETF3Enhancements()          { return  (_features[0] & ETF3EnhancementMask)           == ETF3EnhancementMask; }
 360   static bool has_ParsingEnhancements()       { return  (_features[0] & ParsingEnhancementsMask)       == ParsingEnhancementsMask; }
 361   static bool has_long_displacement()         { return  (_features[0] & LongDispFacilityMask)          == LongDispFacilityMask; }
 362   static bool has_long_displacement_fast()    { return  (_features[0] & LongDispFacilityHighPerfMask)  == LongDispFacilityHighPerfMask; }
 363   static bool has_extended_immediate()        { return  (_features[0] & ExtImmedFacilityMask)          == ExtImmedFacilityMask; }
 364   static bool has_StoreClockFast()            { return  (_features[0] & StoreClockFastMask)            == StoreClockFastMask; }
 365   static bool has_ExtractCPUtime()            { return  (_features[0] & ExtractCPUTimeMask)            == ExtractCPUTimeMask; }
 366   static bool has_CompareSwapStore()          { return  (_features[0] & CompareSwapStoreMask)          == CompareSwapStoreMask; }
 367 
 368   static bool has_HFPMultiplyAndAdd()         { return  (_features[0] & HFPMultiplyAndAddMask)         == HFPMultiplyAndAddMask; }
 369   static bool has_HFPUnnormalized()           { return  (_features[0] & HFPUnnormalizedMask)           == HFPUnnormalizedMask; }
 370 
 371   // Make sure we don't run on older ...
 372   static bool has_GnrlInstrExtensions()       { guarantee((_features[0] & GnrlInstrExtFacilityMask)    == GnrlInstrExtFacilityMask, "We no more support older than z10."); return true; }
 373   static bool has_CompareBranch()             { return  has_GnrlInstrExtensions() && is_z10(); } // Only z10 benefits from these.
 374   static bool has_CompareTrap()               { return  has_GnrlInstrExtensions(); }
 375   static bool has_RelativeLoadStore()         { return  has_GnrlInstrExtensions(); }
 376   static bool has_MultiplySingleImm32()       { return  has_GnrlInstrExtensions(); }
 377   static bool has_Prefetch()                  { return  has_GnrlInstrExtensions() && (AllocatePrefetchStyle > 0); }
 378   static bool has_PrefetchRaw()               { return  has_GnrlInstrExtensions(); }
 379   static bool has_MoveImmToMem()              { return  has_GnrlInstrExtensions(); }
 380   static bool has_ExtractCPUAttributes()      { return  has_GnrlInstrExtensions(); }
 381   static bool has_ExecuteExtensions()         { return  (_features[0] & ExecuteExtensionsMask)         == ExecuteExtensionsMask; }
 382   // Memory-immediate arithmetic instructions. There is no performance penalty in using them.
 383   // Moreover, these memory-immediate instructions are quasi-atomic (>99.99%) on z10
 384   // and 100% atomic from z196 onwards, thanks to the specific operand serialization that comes new with z196.
 385   static bool has_MemWithImmALUOps()          { return  has_GnrlInstrExtensions(); }
 386   static bool has_AtomicMemWithImmALUOps()    { return   has_MemWithImmALUOps() && has_InterlockedAccessV1(); }
 387   static bool has_FPExtensions()              { return  (_features[0] & FPExtensionsMask)              == FPExtensionsMask; }
 388   static bool has_FPSupportEnhancements()     { return  (_features[0] & FPSupportEnhancementsMask)     == FPSupportEnhancementsMask; }
 389   static bool has_DecimalFloatingPoint()      { return  (_features[0] & DecimalFloatingPointMask)      == DecimalFloatingPointMask; }
 390   static bool has_InterlockedAccessV1()       { return  (_features[0] & InterlockedAccess1Mask)        == InterlockedAccess1Mask; }
 391   static bool has_LoadAndALUAtomicV1()        { return  (_features[0] & InterlockedAccess1Mask)        == InterlockedAccess1Mask; }
 392   static bool has_PopCount()                  { return  (_features[0] & PopulationCountMask)           == PopulationCountMask; }
 393   static bool has_LoadStoreConditional()      { return  (_features[0] & LoadStoreConditionalMask)      == LoadStoreConditionalMask; }
 394   static bool has_HighWordInstr()             { return  (_features[0] & HighWordMask)                  == HighWordMask; }
 395   static bool has_FastSync()                  { return  (_features[0] & FastBCRSerializationMask)      == FastBCRSerializationMask; }
 396   static bool has_DistinctOpnds()             { return  (_features[0] & DistinctOpndsMask)             == DistinctOpndsMask; }
 397   static bool has_CryptoExt3()                { return  (_features[1] & CryptoExtension3Mask)          == CryptoExtension3Mask; }
 398   static bool has_CryptoExt4()                { return  (_features[1] & CryptoExtension4Mask)          == CryptoExtension4Mask; }
 399   static bool has_DFPZonedConversion()        { return  (_features[0] & DFPZonedConversionMask)        == DFPZonedConversionMask; }
 400   static bool has_DFPPackedConversion()       { return  (_features[1] & DFPPackedConversionMask)       == DFPPackedConversionMask; }
 401   static bool has_MiscInstrExt()              { return  (_features[0] & MiscInstrExtMask)              == MiscInstrExtMask; }
 402   static bool has_ExecutionHint()             { return  (_features[0] & ExecutionHintMask)             == ExecutionHintMask; }
 403   static bool has_LoadAndTrap()               { return  (_features[0] & LoadAndTrapMask)               == LoadAndTrapMask; }
 404   static bool has_ProcessorAssist()           { return  (_features[0] & ProcessorAssistMask)           == ProcessorAssistMask; }
 405   static bool has_InterlockedAccessV2()       { return  (_features[0] & InterlockedAccess2Mask)        == InterlockedAccess2Mask; }
 406   static bool has_LoadAndALUAtomicV2()        { return  (_features[0] & InterlockedAccess2Mask)        == InterlockedAccess2Mask; }
 407   static bool has_TxMem()                     { return ((_features[1] & TransactionalExecutionMask)    == TransactionalExecutionMask) &&
 408                                                        ((_features[0] & ConstrainedTxExecutionMask)    == ConstrainedTxExecutionMask); }
 409   static bool has_CryptoExt5()                { return  (_features[0] & CryptoExtension5Mask)          == CryptoExtension5Mask; }
 410   static bool has_LoadStoreConditional2()     { return  (_features[0] & LoadStoreConditional2Mask)     == LoadStoreConditional2Mask; }
 411   static bool has_VectorFacility()            { return  (_features[2] & VectorFacilityMask)            == VectorFacilityMask; }
 412 
 413   static bool has_TestFeatureImpl()           { return  (_features[0] & TestFeature1ImplMask)          == TestFeature1ImplMask; }
 414   static bool has_TestFeature1Impl()          { return  (_features[0] & TestFeature1ImplMask)          == TestFeature1ImplMask; }
 415   static bool has_TestFeature2Impl()          { return  (_features[0] & TestFeature2ImplMask)          == TestFeature2ImplMask; }
 416   static bool has_TestFeature4Impl()          { return  (_features[0] & TestFeature4ImplMask)          == TestFeature4ImplMask; }
 417   static bool has_TestFeature8Impl()          { return  (_features[0] & TestFeature8ImplMask)          == TestFeature8ImplMask; }
 418   static bool has_TestFeaturesImpl()          { return  has_TestFeature1Impl() || has_TestFeature2Impl() || has_TestFeature4Impl() || has_TestFeature8Impl(); }
 419 
 420   // Crypto features query functions.
 421   static bool has_Crypto_AES128()             { return has_Crypto() && test_feature_bit(&_cipher_features[0], Cipher::_AES128, Cipher::_featureBits); }
 422   static bool has_Crypto_AES192()             { return has_Crypto() && test_feature_bit(&_cipher_features[0], Cipher::_AES192, Cipher::_featureBits); }
 423   static bool has_Crypto_AES256()             { return has_Crypto() && test_feature_bit(&_cipher_features[0], Cipher::_AES256, Cipher::_featureBits); }
 424   static bool has_Crypto_AES()                { return has_Crypto_AES128() || has_Crypto_AES192() || has_Crypto_AES256(); }
 425 
 426   static bool has_Crypto_SHA1()               { return has_Crypto() && test_feature_bit(&_msgdigest_features[0], MsgDigest::_SHA1,   MsgDigest::_featureBits); }
 427   static bool has_Crypto_SHA256()             { return has_Crypto() && test_feature_bit(&_msgdigest_features[0], MsgDigest::_SHA256, MsgDigest::_featureBits); }
 428   static bool has_Crypto_SHA512()             { return has_Crypto() && test_feature_bit(&_msgdigest_features[0], MsgDigest::_SHA512, MsgDigest::_featureBits); }
 429   static bool has_Crypto_GHASH()              { return has_Crypto() && test_feature_bit(&_msgdigest_features[0], MsgDigest::_GHASH,  MsgDigest::_featureBits); }
 430   static bool has_Crypto_SHA()                { return has_Crypto_SHA1() || has_Crypto_SHA256() || has_Crypto_SHA512() || has_Crypto_GHASH(); }
 431 
 432   // CPU feature setters (to force model-specific behaviour). Test/debugging only.
 433   static void set_has_TestFeature1Impl()          { _features[0] |= TestFeature1ImplMask; }
 434   static void set_has_TestFeature2Impl()          { _features[0] |= TestFeature2ImplMask; }
 435   static void set_has_TestFeature4Impl()          { _features[0] |= TestFeature4ImplMask; }
 436   static void set_has_TestFeature8Impl()          { _features[0] |= TestFeature8ImplMask; }
 437   static void set_has_DecimalFloatingPoint()      { _features[0] |= DecimalFloatingPointMask; }
 438   static void set_has_FPSupportEnhancements()     { _features[0] |= FPSupportEnhancementsMask; }
 439   static void set_has_ExecuteExtensions()         { _features[0] |= ExecuteExtensionsMask; }
 440   static void set_has_MemWithImmALUOps()          { _features[0] |= GnrlInstrExtFacilityMask; }
 441   static void set_has_MoveImmToMem()              { _features[0] |= GnrlInstrExtFacilityMask; }
 442   static void set_has_Prefetch()                  { _features[0] |= GnrlInstrExtFacilityMask; }
 443   static void set_has_MultiplySingleImm32()       { _features[0] |= GnrlInstrExtFacilityMask; }
 444   static void set_has_CompareBranch()             { _features[0] |= GnrlInstrExtFacilityMask; }
 445   static void set_has_CompareTrap()               { _features[0] |= GnrlInstrExtFacilityMask; }
 446   static void set_has_RelativeLoadStore()         { _features[0] |= GnrlInstrExtFacilityMask; }
 447   static void set_has_GnrlInstrExtensions()       { _features[0] |= GnrlInstrExtFacilityMask; }
 448   static void set_has_CompareSwapStore()          { _features[0] |= CompareSwapStoreMask; }
 449   static void set_has_HFPMultiplyAndAdd()         { _features[0] |= HFPMultiplyAndAddMask; }
 450   static void set_has_HFPUnnormalized()           { _features[0] |= HFPUnnormalizedMask; }
 451   static void set_has_ExtractCPUtime()            { _features[0] |= ExtractCPUTimeMask; }
 452   static void set_has_StoreClockFast()            { _features[0] |= StoreClockFastMask; }
 453   static void set_has_extended_immediate()        { _features[0] |= ExtImmedFacilityMask; }
 454   static void set_has_long_displacement_fast()    { _features[0] |= LongDispFacilityHighPerfMask; }
 455   static void set_has_long_displacement()         { _features[0] |= LongDispFacilityMask; }
 456   static void set_has_ETF2()                      { _features[0] |= ETF2Mask; }
 457   static void set_has_ETF3()                      { _features[0] |= ETF3Mask; }
 458   static void set_has_ETF2Enhancements()          { _features[0] |= ETF2EnhancementMask; }
 459   static void set_has_ETF3Enhancements()          { _features[0] |= ETF3EnhancementMask; }
 460   static void set_has_Crypto()                    { _features[0] |= CryptoFacilityMask; }
 461   static void set_has_StoreFacilityListExtended() { _features[0] |= StoreFacilityListExtendedMask; }
 462 
 463   static void set_has_InterlockedAccessV1()       { _features[0] |= InterlockedAccess1Mask; }
 464   static void set_has_PopCount()                  { _features[0] |= PopulationCountMask; }
 465   static void set_has_LoadStoreConditional()      { _features[0] |= LoadStoreConditionalMask; }
 466   static void set_has_HighWordInstr()             { _features[0] |= HighWordMask; }
 467   static void set_has_FastSync()                  { _features[0] |= FastBCRSerializationMask; }
 468   static void set_has_DistinctOpnds()             { _features[0] |= DistinctOpndsMask; }
 469   static void set_has_FPExtensions()              { _features[0] |= FPExtensionsMask; }
 470   static void set_has_MiscInstrExt()              { _features[0] |= MiscInstrExtMask; }
 471   static void set_has_ProcessorAssist()           { _features[0] |= ProcessorAssistMask; }
 472   static void set_has_InterlockedAccessV2()       { _features[0] |= InterlockedAccess2Mask; }
 473   static void set_has_LoadAndALUAtomicV2()        { _features[0] |= InterlockedAccess2Mask; }
 474   static void set_has_TxMem()                     { _features[0] |= ConstrainedTxExecutionMask; _features[1] |= TransactionalExecutionMask; }
 475   static void set_has_CryptoExt3()                { _features[1] |= CryptoExtension3Mask; }
 476   static void set_has_CryptoExt4()                { _features[1] |= CryptoExtension4Mask; }
 477   static void set_has_LoadStoreConditional2()     { _features[0] |= LoadStoreConditional2Mask; }
 478   static void set_has_CryptoExt5()                { _features[0] |= CryptoExtension5Mask; }
 479   static void set_has_VectorFacility()            { _features[2] |= VectorFacilityMask; }
 480 
 481   static void reset_has_VectorFacility()          { _features[2] &= ~VectorFacilityMask; }
 482 
 483   // Assembler testing.
 484   static void allow_all();
 485   static void revert();
 486 
 487   // Generate trapping instructions into C-code.
 488   // Sometimes helpful for debugging.
 489   static unsigned long z_SIGILL();
 490   static unsigned long z_SIGSEGV();
 491 };
 492 
 493 #endif // CPU_S390_VM_VERSION_S390_HPP