1 /*
2  * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
3  * Copyright (c) 2016, 2019 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/abstract_vm_version.hpp"
31 #include "runtime/globals_extension.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.
is_z900()158   static bool is_z900() { return has_long_displacement()      && !has_long_displacement_fast(); }
is_z990()159   static bool is_z990() { return has_long_displacement_fast() && !has_extended_immediate();  }
is_z9()160   static bool is_z9()   { return has_extended_immediate()     && !has_GnrlInstrExtensions(); }
is_z10()161   static bool is_z10()  { return has_GnrlInstrExtensions()    && !has_DistinctOpnds(); }
is_z196()162   static bool is_z196() { return has_DistinctOpnds()          && !has_MiscInstrExt(); }
is_ec12()163   static bool is_ec12() { return has_MiscInstrExt()           && !has_CryptoExt5(); }
is_z13()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.
Dcache_lineSize(unsigned int level=0)168   static unsigned int Dcache_lineSize(unsigned int level = 0) { return _Dcache_lineSize; }
Icache_lineSize(unsigned int level=0)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();
is_determine_features_test_running()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   // s390 supports fast class initialization checks for static methods.
supports_fast_class_init_checks()353   static bool supports_fast_class_init_checks() { return true; }
354 
355   // CPU feature query functions
get_model_string()356   static const char* get_model_string()       { return _model_string; }
has_StoreFacilityListExtended()357   static bool has_StoreFacilityListExtended() { return  (_features[0] & StoreFacilityListExtendedMask) == StoreFacilityListExtendedMask; }
has_Crypto()358   static bool has_Crypto()                    { return  (_features[0] & CryptoFacilityMask)            == CryptoFacilityMask; }
has_ETF2()359   static bool has_ETF2()                      { return  (_features[0] & ETF2Mask)                      == ETF2Mask; }
has_ETF3()360   static bool has_ETF3()                      { return  (_features[0] & ETF3Mask)                      == ETF3Mask; }
has_ETF2Enhancements()361   static bool has_ETF2Enhancements()          { return  (_features[0] & ETF2EnhancementMask)           == ETF2EnhancementMask; }
has_ETF3Enhancements()362   static bool has_ETF3Enhancements()          { return  (_features[0] & ETF3EnhancementMask)           == ETF3EnhancementMask; }
has_ParsingEnhancements()363   static bool has_ParsingEnhancements()       { return  (_features[0] & ParsingEnhancementsMask)       == ParsingEnhancementsMask; }
has_long_displacement()364   static bool has_long_displacement()         { return  (_features[0] & LongDispFacilityMask)          == LongDispFacilityMask; }
has_long_displacement_fast()365   static bool has_long_displacement_fast()    { return  (_features[0] & LongDispFacilityHighPerfMask)  == LongDispFacilityHighPerfMask; }
has_extended_immediate()366   static bool has_extended_immediate()        { return  (_features[0] & ExtImmedFacilityMask)          == ExtImmedFacilityMask; }
has_StoreClockFast()367   static bool has_StoreClockFast()            { return  (_features[0] & StoreClockFastMask)            == StoreClockFastMask; }
has_ExtractCPUtime()368   static bool has_ExtractCPUtime()            { return  (_features[0] & ExtractCPUTimeMask)            == ExtractCPUTimeMask; }
has_CompareSwapStore()369   static bool has_CompareSwapStore()          { return  (_features[0] & CompareSwapStoreMask)          == CompareSwapStoreMask; }
370 
has_HFPMultiplyAndAdd()371   static bool has_HFPMultiplyAndAdd()         { return  (_features[0] & HFPMultiplyAndAddMask)         == HFPMultiplyAndAddMask; }
has_HFPUnnormalized()372   static bool has_HFPUnnormalized()           { return  (_features[0] & HFPUnnormalizedMask)           == HFPUnnormalizedMask; }
373 
374   // Make sure we don't run on older ...
has_GnrlInstrExtensions()375   static bool has_GnrlInstrExtensions()       { guarantee((_features[0] & GnrlInstrExtFacilityMask)    == GnrlInstrExtFacilityMask, "We no more support older than z10."); return true; }
has_CompareBranch()376   static bool has_CompareBranch()             { return  has_GnrlInstrExtensions() && is_z10(); } // Only z10 benefits from these.
has_CompareTrap()377   static bool has_CompareTrap()               { return  has_GnrlInstrExtensions(); }
has_RelativeLoadStore()378   static bool has_RelativeLoadStore()         { return  has_GnrlInstrExtensions(); }
has_MultiplySingleImm32()379   static bool has_MultiplySingleImm32()       { return  has_GnrlInstrExtensions(); }
has_Prefetch()380   static bool has_Prefetch()                  { return  has_GnrlInstrExtensions() && (AllocatePrefetchStyle > 0); }
has_PrefetchRaw()381   static bool has_PrefetchRaw()               { return  has_GnrlInstrExtensions(); }
has_MoveImmToMem()382   static bool has_MoveImmToMem()              { return  has_GnrlInstrExtensions(); }
has_ExtractCPUAttributes()383   static bool has_ExtractCPUAttributes()      { return  has_GnrlInstrExtensions(); }
has_ExecuteExtensions()384   static bool has_ExecuteExtensions()         { return  (_features[0] & ExecuteExtensionsMask)         == ExecuteExtensionsMask; }
385   // Memory-immediate arithmetic instructions. There is no performance penalty in using them.
386   // Moreover, these memory-immediate instructions are quasi-atomic (>99.99%) on z10
387   // and 100% atomic from z196 onwards, thanks to the specific operand serialization that comes new with z196.
has_MemWithImmALUOps()388   static bool has_MemWithImmALUOps()          { return  has_GnrlInstrExtensions(); }
has_AtomicMemWithImmALUOps()389   static bool has_AtomicMemWithImmALUOps()    { return   has_MemWithImmALUOps() && has_InterlockedAccessV1(); }
has_FPExtensions()390   static bool has_FPExtensions()              { return  (_features[0] & FPExtensionsMask)              == FPExtensionsMask; }
has_FPSupportEnhancements()391   static bool has_FPSupportEnhancements()     { return  (_features[0] & FPSupportEnhancementsMask)     == FPSupportEnhancementsMask; }
has_DecimalFloatingPoint()392   static bool has_DecimalFloatingPoint()      { return  (_features[0] & DecimalFloatingPointMask)      == DecimalFloatingPointMask; }
has_InterlockedAccessV1()393   static bool has_InterlockedAccessV1()       { return  (_features[0] & InterlockedAccess1Mask)        == InterlockedAccess1Mask; }
has_LoadAndALUAtomicV1()394   static bool has_LoadAndALUAtomicV1()        { return  (_features[0] & InterlockedAccess1Mask)        == InterlockedAccess1Mask; }
has_PopCount()395   static bool has_PopCount()                  { return  (_features[0] & PopulationCountMask)           == PopulationCountMask; }
has_LoadStoreConditional()396   static bool has_LoadStoreConditional()      { return  (_features[0] & LoadStoreConditionalMask)      == LoadStoreConditionalMask; }
has_HighWordInstr()397   static bool has_HighWordInstr()             { return  (_features[0] & HighWordMask)                  == HighWordMask; }
has_FastSync()398   static bool has_FastSync()                  { return  (_features[0] & FastBCRSerializationMask)      == FastBCRSerializationMask; }
has_DistinctOpnds()399   static bool has_DistinctOpnds()             { return  (_features[0] & DistinctOpndsMask)             == DistinctOpndsMask; }
has_CryptoExt3()400   static bool has_CryptoExt3()                { return  (_features[1] & CryptoExtension3Mask)          == CryptoExtension3Mask; }
has_CryptoExt4()401   static bool has_CryptoExt4()                { return  (_features[1] & CryptoExtension4Mask)          == CryptoExtension4Mask; }
has_DFPZonedConversion()402   static bool has_DFPZonedConversion()        { return  (_features[0] & DFPZonedConversionMask)        == DFPZonedConversionMask; }
has_DFPPackedConversion()403   static bool has_DFPPackedConversion()       { return  (_features[1] & DFPPackedConversionMask)       == DFPPackedConversionMask; }
has_MiscInstrExt()404   static bool has_MiscInstrExt()              { return  (_features[0] & MiscInstrExtMask)              == MiscInstrExtMask; }
has_ExecutionHint()405   static bool has_ExecutionHint()             { return  (_features[0] & ExecutionHintMask)             == ExecutionHintMask; }
has_LoadAndTrap()406   static bool has_LoadAndTrap()               { return  (_features[0] & LoadAndTrapMask)               == LoadAndTrapMask; }
has_ProcessorAssist()407   static bool has_ProcessorAssist()           { return  (_features[0] & ProcessorAssistMask)           == ProcessorAssistMask; }
has_InterlockedAccessV2()408   static bool has_InterlockedAccessV2()       { return  (_features[0] & InterlockedAccess2Mask)        == InterlockedAccess2Mask; }
has_LoadAndALUAtomicV2()409   static bool has_LoadAndALUAtomicV2()        { return  (_features[0] & InterlockedAccess2Mask)        == InterlockedAccess2Mask; }
has_TxMem()410   static bool has_TxMem()                     { return ((_features[1] & TransactionalExecutionMask)    == TransactionalExecutionMask) &&
411                                                        ((_features[0] & ConstrainedTxExecutionMask)    == ConstrainedTxExecutionMask); }
has_CryptoExt5()412   static bool has_CryptoExt5()                { return  (_features[0] & CryptoExtension5Mask)          == CryptoExtension5Mask; }
has_LoadStoreConditional2()413   static bool has_LoadStoreConditional2()     { return  (_features[0] & LoadStoreConditional2Mask)     == LoadStoreConditional2Mask; }
has_VectorFacility()414   static bool has_VectorFacility()            { return  (_features[2] & VectorFacilityMask)            == VectorFacilityMask; }
415 
has_TestFeatureImpl()416   static bool has_TestFeatureImpl()           { return  (_features[0] & TestFeature1ImplMask)          == TestFeature1ImplMask; }
has_TestFeature1Impl()417   static bool has_TestFeature1Impl()          { return  (_features[0] & TestFeature1ImplMask)          == TestFeature1ImplMask; }
has_TestFeature2Impl()418   static bool has_TestFeature2Impl()          { return  (_features[0] & TestFeature2ImplMask)          == TestFeature2ImplMask; }
has_TestFeature4Impl()419   static bool has_TestFeature4Impl()          { return  (_features[0] & TestFeature4ImplMask)          == TestFeature4ImplMask; }
has_TestFeature8Impl()420   static bool has_TestFeature8Impl()          { return  (_features[0] & TestFeature8ImplMask)          == TestFeature8ImplMask; }
has_TestFeaturesImpl()421   static bool has_TestFeaturesImpl()          { return  has_TestFeature1Impl() || has_TestFeature2Impl() || has_TestFeature4Impl() || has_TestFeature8Impl(); }
422 
423   // Crypto features query functions.
has_Crypto_AES128()424   static bool has_Crypto_AES128()             { return has_Crypto() && test_feature_bit(&_cipher_features[0], Cipher::_AES128, Cipher::_featureBits); }
has_Crypto_AES192()425   static bool has_Crypto_AES192()             { return has_Crypto() && test_feature_bit(&_cipher_features[0], Cipher::_AES192, Cipher::_featureBits); }
has_Crypto_AES256()426   static bool has_Crypto_AES256()             { return has_Crypto() && test_feature_bit(&_cipher_features[0], Cipher::_AES256, Cipher::_featureBits); }
has_Crypto_AES()427   static bool has_Crypto_AES()                { return has_Crypto_AES128() || has_Crypto_AES192() || has_Crypto_AES256(); }
428 
has_Crypto_SHA1()429   static bool has_Crypto_SHA1()               { return has_Crypto() && test_feature_bit(&_msgdigest_features[0], MsgDigest::_SHA1,   MsgDigest::_featureBits); }
has_Crypto_SHA256()430   static bool has_Crypto_SHA256()             { return has_Crypto() && test_feature_bit(&_msgdigest_features[0], MsgDigest::_SHA256, MsgDigest::_featureBits); }
has_Crypto_SHA512()431   static bool has_Crypto_SHA512()             { return has_Crypto() && test_feature_bit(&_msgdigest_features[0], MsgDigest::_SHA512, MsgDigest::_featureBits); }
has_Crypto_GHASH()432   static bool has_Crypto_GHASH()              { return has_Crypto() && test_feature_bit(&_msgdigest_features[0], MsgDigest::_GHASH,  MsgDigest::_featureBits); }
has_Crypto_SHA()433   static bool has_Crypto_SHA()                { return has_Crypto_SHA1() || has_Crypto_SHA256() || has_Crypto_SHA512() || has_Crypto_GHASH(); }
434 
435   // CPU feature setters (to force model-specific behaviour). Test/debugging only.
set_has_TestFeature1Impl()436   static void set_has_TestFeature1Impl()          { _features[0] |= TestFeature1ImplMask; }
set_has_TestFeature2Impl()437   static void set_has_TestFeature2Impl()          { _features[0] |= TestFeature2ImplMask; }
set_has_TestFeature4Impl()438   static void set_has_TestFeature4Impl()          { _features[0] |= TestFeature4ImplMask; }
set_has_TestFeature8Impl()439   static void set_has_TestFeature8Impl()          { _features[0] |= TestFeature8ImplMask; }
set_has_DecimalFloatingPoint()440   static void set_has_DecimalFloatingPoint()      { _features[0] |= DecimalFloatingPointMask; }
set_has_FPSupportEnhancements()441   static void set_has_FPSupportEnhancements()     { _features[0] |= FPSupportEnhancementsMask; }
set_has_ExecuteExtensions()442   static void set_has_ExecuteExtensions()         { _features[0] |= ExecuteExtensionsMask; }
set_has_MemWithImmALUOps()443   static void set_has_MemWithImmALUOps()          { _features[0] |= GnrlInstrExtFacilityMask; }
set_has_MoveImmToMem()444   static void set_has_MoveImmToMem()              { _features[0] |= GnrlInstrExtFacilityMask; }
set_has_Prefetch()445   static void set_has_Prefetch()                  { _features[0] |= GnrlInstrExtFacilityMask; }
set_has_MultiplySingleImm32()446   static void set_has_MultiplySingleImm32()       { _features[0] |= GnrlInstrExtFacilityMask; }
set_has_CompareBranch()447   static void set_has_CompareBranch()             { _features[0] |= GnrlInstrExtFacilityMask; }
set_has_CompareTrap()448   static void set_has_CompareTrap()               { _features[0] |= GnrlInstrExtFacilityMask; }
set_has_RelativeLoadStore()449   static void set_has_RelativeLoadStore()         { _features[0] |= GnrlInstrExtFacilityMask; }
set_has_GnrlInstrExtensions()450   static void set_has_GnrlInstrExtensions()       { _features[0] |= GnrlInstrExtFacilityMask; }
set_has_CompareSwapStore()451   static void set_has_CompareSwapStore()          { _features[0] |= CompareSwapStoreMask; }
set_has_HFPMultiplyAndAdd()452   static void set_has_HFPMultiplyAndAdd()         { _features[0] |= HFPMultiplyAndAddMask; }
set_has_HFPUnnormalized()453   static void set_has_HFPUnnormalized()           { _features[0] |= HFPUnnormalizedMask; }
set_has_ExtractCPUtime()454   static void set_has_ExtractCPUtime()            { _features[0] |= ExtractCPUTimeMask; }
set_has_StoreClockFast()455   static void set_has_StoreClockFast()            { _features[0] |= StoreClockFastMask; }
set_has_extended_immediate()456   static void set_has_extended_immediate()        { _features[0] |= ExtImmedFacilityMask; }
set_has_long_displacement_fast()457   static void set_has_long_displacement_fast()    { _features[0] |= LongDispFacilityHighPerfMask; }
set_has_long_displacement()458   static void set_has_long_displacement()         { _features[0] |= LongDispFacilityMask; }
set_has_ETF2()459   static void set_has_ETF2()                      { _features[0] |= ETF2Mask; }
set_has_ETF3()460   static void set_has_ETF3()                      { _features[0] |= ETF3Mask; }
set_has_ETF2Enhancements()461   static void set_has_ETF2Enhancements()          { _features[0] |= ETF2EnhancementMask; }
set_has_ETF3Enhancements()462   static void set_has_ETF3Enhancements()          { _features[0] |= ETF3EnhancementMask; }
set_has_Crypto()463   static void set_has_Crypto()                    { _features[0] |= CryptoFacilityMask; }
set_has_StoreFacilityListExtended()464   static void set_has_StoreFacilityListExtended() { _features[0] |= StoreFacilityListExtendedMask; }
465 
set_has_InterlockedAccessV1()466   static void set_has_InterlockedAccessV1()       { _features[0] |= InterlockedAccess1Mask; }
set_has_PopCount()467   static void set_has_PopCount()                  { _features[0] |= PopulationCountMask; }
set_has_LoadStoreConditional()468   static void set_has_LoadStoreConditional()      { _features[0] |= LoadStoreConditionalMask; }
set_has_HighWordInstr()469   static void set_has_HighWordInstr()             { _features[0] |= HighWordMask; }
set_has_FastSync()470   static void set_has_FastSync()                  { _features[0] |= FastBCRSerializationMask; }
set_has_DistinctOpnds()471   static void set_has_DistinctOpnds()             { _features[0] |= DistinctOpndsMask; }
set_has_FPExtensions()472   static void set_has_FPExtensions()              { _features[0] |= FPExtensionsMask; }
set_has_MiscInstrExt()473   static void set_has_MiscInstrExt()              { _features[0] |= MiscInstrExtMask; }
set_has_ProcessorAssist()474   static void set_has_ProcessorAssist()           { _features[0] |= ProcessorAssistMask; }
set_has_InterlockedAccessV2()475   static void set_has_InterlockedAccessV2()       { _features[0] |= InterlockedAccess2Mask; }
set_has_LoadAndALUAtomicV2()476   static void set_has_LoadAndALUAtomicV2()        { _features[0] |= InterlockedAccess2Mask; }
set_has_TxMem()477   static void set_has_TxMem()                     { _features[0] |= ConstrainedTxExecutionMask; _features[1] |= TransactionalExecutionMask; }
set_has_CryptoExt3()478   static void set_has_CryptoExt3()                { _features[1] |= CryptoExtension3Mask; }
set_has_CryptoExt4()479   static void set_has_CryptoExt4()                { _features[1] |= CryptoExtension4Mask; }
set_has_LoadStoreConditional2()480   static void set_has_LoadStoreConditional2()     { _features[0] |= LoadStoreConditional2Mask; }
set_has_CryptoExt5()481   static void set_has_CryptoExt5()                { _features[0] |= CryptoExtension5Mask; }
set_has_VectorFacility()482   static void set_has_VectorFacility()            { _features[2] |= VectorFacilityMask; }
483 
reset_has_VectorFacility()484   static void reset_has_VectorFacility()          { _features[2] &= ~VectorFacilityMask; }
485 
486   // Assembler testing.
487   static void allow_all();
488   static void revert();
489 
490   // Generate trapping instructions into C-code.
491   // Sometimes helpful for debugging.
492   static unsigned long z_SIGILL();
493   static unsigned long z_SIGSEGV();
494 };
495 
496 #endif // CPU_S390_VM_VERSION_S390_HPP
497