1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/cpu/sparc/vm/vm_version_sparc.hpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,204 @@ 1.4 +/* 1.5 + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#ifndef CPU_SPARC_VM_VM_VERSION_SPARC_HPP 1.29 +#define CPU_SPARC_VM_VM_VERSION_SPARC_HPP 1.30 + 1.31 +#include "runtime/globals_extension.hpp" 1.32 +#include "runtime/vm_version.hpp" 1.33 + 1.34 +class VM_Version: public Abstract_VM_Version { 1.35 +protected: 1.36 + enum Feature_Flag { 1.37 + v8_instructions = 0, 1.38 + hardware_mul32 = 1, 1.39 + hardware_div32 = 2, 1.40 + hardware_fsmuld = 3, 1.41 + hardware_popc = 4, 1.42 + v9_instructions = 5, 1.43 + vis1_instructions = 6, 1.44 + vis2_instructions = 7, 1.45 + sun4v_instructions = 8, 1.46 + blk_init_instructions = 9, 1.47 + fmaf_instructions = 10, 1.48 + fmau_instructions = 11, 1.49 + vis3_instructions = 12, 1.50 + cbcond_instructions = 13, 1.51 + sparc64_family = 14, 1.52 + M_family = 15, 1.53 + T_family = 16, 1.54 + T1_model = 17, 1.55 + sparc5_instructions = 18, 1.56 + aes_instructions = 19 1.57 + }; 1.58 + 1.59 + enum Feature_Flag_Set { 1.60 + unknown_m = 0, 1.61 + all_features_m = -1, 1.62 + 1.63 + v8_instructions_m = 1 << v8_instructions, 1.64 + hardware_mul32_m = 1 << hardware_mul32, 1.65 + hardware_div32_m = 1 << hardware_div32, 1.66 + hardware_fsmuld_m = 1 << hardware_fsmuld, 1.67 + hardware_popc_m = 1 << hardware_popc, 1.68 + v9_instructions_m = 1 << v9_instructions, 1.69 + vis1_instructions_m = 1 << vis1_instructions, 1.70 + vis2_instructions_m = 1 << vis2_instructions, 1.71 + sun4v_m = 1 << sun4v_instructions, 1.72 + blk_init_instructions_m = 1 << blk_init_instructions, 1.73 + fmaf_instructions_m = 1 << fmaf_instructions, 1.74 + fmau_instructions_m = 1 << fmau_instructions, 1.75 + vis3_instructions_m = 1 << vis3_instructions, 1.76 + cbcond_instructions_m = 1 << cbcond_instructions, 1.77 + sparc64_family_m = 1 << sparc64_family, 1.78 + M_family_m = 1 << M_family, 1.79 + T_family_m = 1 << T_family, 1.80 + T1_model_m = 1 << T1_model, 1.81 + sparc5_instructions_m = 1 << sparc5_instructions, 1.82 + aes_instructions_m = 1 << aes_instructions, 1.83 + 1.84 + generic_v8_m = v8_instructions_m | hardware_mul32_m | hardware_div32_m | hardware_fsmuld_m, 1.85 + generic_v9_m = generic_v8_m | v9_instructions_m, 1.86 + ultra3_m = generic_v9_m | vis1_instructions_m | vis2_instructions_m, 1.87 + 1.88 + // Temporary until we have something more accurate 1.89 + niagara1_unique_m = sun4v_m, 1.90 + niagara1_m = generic_v9_m | niagara1_unique_m 1.91 + }; 1.92 + 1.93 + static int _features; 1.94 + static const char* _features_str; 1.95 + 1.96 + static void print_features(); 1.97 + static int determine_features(); 1.98 + static int platform_features(int features); 1.99 + 1.100 + // Returns true if the platform is in the niagara line (T series) 1.101 + static bool is_M_family(int features) { return (features & M_family_m) != 0; } 1.102 + static bool is_T_family(int features) { return (features & T_family_m) != 0; } 1.103 + static bool is_niagara() { return is_T_family(_features); } 1.104 +#ifdef ASSERT 1.105 + static bool is_niagara(int features) { 1.106 + // 'sun4v_m' may be defined on both Sun/Oracle Sparc CPUs as well as 1.107 + // on Fujitsu Sparc64 CPUs, but only Sun/Oracle Sparcs can be 'niagaras'. 1.108 + return (features & sun4v_m) != 0 && (features & sparc64_family_m) == 0; 1.109 + } 1.110 +#endif 1.111 + 1.112 + // Returns true if it is niagara1 (T1). 1.113 + static bool is_T1_model(int features) { return is_T_family(features) && ((features & T1_model_m) != 0); } 1.114 + 1.115 + static int maximum_niagara1_processor_count() { return 32; } 1.116 + 1.117 +public: 1.118 + // Initialization 1.119 + static void initialize(); 1.120 + 1.121 + // Instruction support 1.122 + static bool has_v8() { return (_features & v8_instructions_m) != 0; } 1.123 + static bool has_v9() { return (_features & v9_instructions_m) != 0; } 1.124 + static bool has_hardware_mul32() { return (_features & hardware_mul32_m) != 0; } 1.125 + static bool has_hardware_div32() { return (_features & hardware_div32_m) != 0; } 1.126 + static bool has_hardware_fsmuld() { return (_features & hardware_fsmuld_m) != 0; } 1.127 + static bool has_hardware_popc() { return (_features & hardware_popc_m) != 0; } 1.128 + static bool has_vis1() { return (_features & vis1_instructions_m) != 0; } 1.129 + static bool has_vis2() { return (_features & vis2_instructions_m) != 0; } 1.130 + static bool has_vis3() { return (_features & vis3_instructions_m) != 0; } 1.131 + static bool has_blk_init() { return (_features & blk_init_instructions_m) != 0; } 1.132 + static bool has_cbcond() { return (_features & cbcond_instructions_m) != 0; } 1.133 + static bool has_sparc5_instr() { return (_features & sparc5_instructions_m) != 0; } 1.134 + static bool has_aes() { return (_features & aes_instructions_m) != 0; } 1.135 + 1.136 + static bool supports_compare_and_exchange() 1.137 + { return has_v9(); } 1.138 + 1.139 + // Returns true if the platform is in the niagara line (T series) 1.140 + // and newer than the niagara1. 1.141 + static bool is_niagara_plus() { return is_T_family(_features) && !is_T1_model(_features); } 1.142 + 1.143 + static bool is_M_series() { return is_M_family(_features); } 1.144 + static bool is_T4() { return is_T_family(_features) && has_cbcond(); } 1.145 + static bool is_T7() { return is_T_family(_features) && has_sparc5_instr(); } 1.146 + 1.147 + // Fujitsu SPARC64 1.148 + static bool is_sparc64() { return (_features & sparc64_family_m) != 0; } 1.149 + 1.150 + static bool is_sun4v() { return (_features & sun4v_m) != 0; } 1.151 + static bool is_ultra3() { return (_features & ultra3_m) == ultra3_m && !is_sun4v() && !is_sparc64(); } 1.152 + 1.153 + static bool has_fast_fxtof() { return is_niagara() || is_sparc64() || has_v9() && !is_ultra3(); } 1.154 + static bool has_fast_idiv() { return is_niagara_plus() || is_sparc64(); } 1.155 + 1.156 + // T4 and newer Sparc have fast RDPC instruction. 1.157 + static bool has_fast_rdpc() { return is_T4(); } 1.158 + 1.159 + // On T4 and newer Sparc BIS to the beginning of cache line always zeros it. 1.160 + static bool has_block_zeroing() { return has_blk_init() && is_T4(); } 1.161 + 1.162 + static const char* cpu_features() { return _features_str; } 1.163 + 1.164 + static intx prefetch_data_size() { 1.165 + return is_T4() && !is_T7() ? 32 : 64; // default prefetch block size on sparc 1.166 + } 1.167 + 1.168 + // Prefetch 1.169 + static intx prefetch_copy_interval_in_bytes() { 1.170 + intx interval = PrefetchCopyIntervalInBytes; 1.171 + return interval >= 0 ? interval : (has_v9() ? 512 : 0); 1.172 + } 1.173 + static intx prefetch_scan_interval_in_bytes() { 1.174 + intx interval = PrefetchScanIntervalInBytes; 1.175 + return interval >= 0 ? interval : (has_v9() ? 512 : 0); 1.176 + } 1.177 + static intx prefetch_fields_ahead() { 1.178 + intx count = PrefetchFieldsAhead; 1.179 + return count >= 0 ? count : (is_ultra3() ? 1 : 0); 1.180 + } 1.181 + 1.182 + static intx allocate_prefetch_distance() { 1.183 + // This method should be called before allocate_prefetch_style(). 1.184 + intx count = AllocatePrefetchDistance; 1.185 + if (count < 0) { // default is not defined ? 1.186 + count = 512; 1.187 + } 1.188 + return count; 1.189 + } 1.190 + static intx allocate_prefetch_style() { 1.191 + assert(AllocatePrefetchStyle >= 0, "AllocatePrefetchStyle should be positive"); 1.192 + // Return 0 if AllocatePrefetchDistance was not defined. 1.193 + return AllocatePrefetchDistance > 0 ? AllocatePrefetchStyle : 0; 1.194 + } 1.195 + 1.196 + // Assembler testing 1.197 + static void allow_all(); 1.198 + static void revert(); 1.199 + 1.200 + // Override the Abstract_VM_Version implementation. 1.201 + static uint page_size_count() { return is_sun4v() ? 4 : 2; } 1.202 + 1.203 + // Calculates the number of parallel threads 1.204 + static unsigned int calc_parallel_worker_threads(); 1.205 +}; 1.206 + 1.207 +#endif // CPU_SPARC_VM_VM_VERSION_SPARC_HPP