1.1 --- a/src/cpu/ppc/vm/vm_version_ppc.cpp Thu Sep 05 18:40:52 2019 +0800 1.2 +++ b/src/cpu/ppc/vm/vm_version_ppc.cpp Thu Sep 05 18:52:27 2019 +0800 1.3 @@ -1,6 +1,6 @@ 1.4 /* 1.5 - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 1.6 - * Copyright 2012, 2014 SAP AG. All rights reserved. 1.7 + * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. 1.8 + * Copyright 2012, 2018 SAP AG. All rights reserved. 1.9 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.10 * 1.11 * This code is free software; you can redistribute it and/or modify it 1.12 @@ -45,7 +45,7 @@ 1.13 int VM_Version::_measured_cache_line_size = 128; // default value 1.14 const char* VM_Version::_features_str = ""; 1.15 bool VM_Version::_is_determine_features_test_running = false; 1.16 - 1.17 +uint64_t VM_Version::_dscr_val = 0; 1.18 1.19 #define MSG(flag) \ 1.20 if (flag && !FLAG_IS_DEFAULT(flag)) \ 1.21 @@ -60,7 +60,9 @@ 1.22 1.23 // If PowerArchitecturePPC64 hasn't been specified explicitly determine from features. 1.24 if (FLAG_IS_DEFAULT(PowerArchitecturePPC64)) { 1.25 - if (VM_Version::has_popcntw()) { 1.26 + if (VM_Version::has_lqarx()) { 1.27 + FLAG_SET_ERGO(uintx, PowerArchitecturePPC64, 8); 1.28 + } else if (VM_Version::has_popcntw()) { 1.29 FLAG_SET_ERGO(uintx, PowerArchitecturePPC64, 7); 1.30 } else if (VM_Version::has_cmpb()) { 1.31 FLAG_SET_ERGO(uintx, PowerArchitecturePPC64, 6); 1.32 @@ -71,8 +73,14 @@ 1.33 } 1.34 } 1.35 guarantee(PowerArchitecturePPC64 == 0 || PowerArchitecturePPC64 == 5 || 1.36 - PowerArchitecturePPC64 == 6 || PowerArchitecturePPC64 == 7, 1.37 - "PowerArchitecturePPC64 should be 0, 5, 6 or 7"); 1.38 + PowerArchitecturePPC64 == 6 || PowerArchitecturePPC64 == 7 || 1.39 + PowerArchitecturePPC64 == 8, 1.40 + "PowerArchitecturePPC64 should be 0, 5, 6, 7, or 8"); 1.41 + 1.42 + // Power 8: Configure Data Stream Control Register. 1.43 + if (PowerArchitecturePPC64 >= 8) { 1.44 + config_dscr(); 1.45 + } 1.46 1.47 if (!UseSIGTRAP) { 1.48 MSG(TrapBasedICMissChecks); 1.49 @@ -102,7 +110,7 @@ 1.50 // Create and print feature-string. 1.51 char buf[(num_features+1) * 16]; // Max 16 chars per feature. 1.52 jio_snprintf(buf, sizeof(buf), 1.53 - "ppc64%s%s%s%s%s%s%s%s%s%s", 1.54 + "ppc64%s%s%s%s%s%s%s%s%s%s%s%s%s", 1.55 (has_fsqrt() ? " fsqrt" : ""), 1.56 (has_isel() ? " isel" : ""), 1.57 (has_lxarxeh() ? " lxarxeh" : ""), 1.58 @@ -112,12 +120,17 @@ 1.59 (has_popcntw() ? " popcntw" : ""), 1.60 (has_fcfids() ? " fcfids" : ""), 1.61 (has_vand() ? " vand" : ""), 1.62 + (has_lqarx() ? " lqarx" : ""), 1.63 (has_vcipher() ? " aes" : ""), 1.64 - (has_vpmsumb() ? " vpmsumb" : "") 1.65 + (has_vpmsumb() ? " vpmsumb" : ""), 1.66 + (has_mfdscr() ? " mfdscr" : ""), 1.67 + (has_vsx() ? " vsx" : "") 1.68 // Make sure number of %s matches num_features! 1.69 ); 1.70 _features_str = strdup(buf); 1.71 - NOT_PRODUCT(if (Verbose) print_features();); 1.72 + if (Verbose) { 1.73 + print_features(); 1.74 + } 1.75 1.76 // PPC64 supports 8-byte compare-exchange operations (see 1.77 // Atomic::cmpxchg and StubGenerator::generate_atomic_cmpxchg_ptr) 1.78 @@ -485,8 +498,11 @@ 1.79 a->popcntw(R7, R5); // code[7] -> popcntw 1.80 a->fcfids(F3, F4); // code[8] -> fcfids 1.81 a->vand(VR0, VR0, VR0); // code[9] -> vand 1.82 - a->vcipher(VR0, VR1, VR2); // code[10] -> vcipher 1.83 - a->vpmsumb(VR0, VR1, VR2); // code[11] -> vpmsumb 1.84 + a->lqarx_unchecked(R7, R3_ARG1, R4_ARG2, 1); // code[10] -> lqarx_m 1.85 + a->vcipher(VR0, VR1, VR2); // code[11] -> vcipher 1.86 + a->vpmsumb(VR0, VR1, VR2); // code[12] -> vpmsumb 1.87 + a->mfdscr(R0); // code[13] -> mfdscr 1.88 + a->lxvd2x(VSR0, R3_ARG1); // code[14] -> vsx 1.89 a->blr(); 1.90 1.91 // Emit function to set one cache line to zero. Emit function descriptor and get pointer to it. 1.92 @@ -530,8 +546,11 @@ 1.93 if (code[feature_cntr++]) features |= popcntw_m; 1.94 if (code[feature_cntr++]) features |= fcfids_m; 1.95 if (code[feature_cntr++]) features |= vand_m; 1.96 + if (code[feature_cntr++]) features |= lqarx_m; 1.97 if (code[feature_cntr++]) features |= vcipher_m; 1.98 if (code[feature_cntr++]) features |= vpmsumb_m; 1.99 + if (code[feature_cntr++]) features |= mfdscr_m; 1.100 + if (code[feature_cntr++]) features |= vsx_m; 1.101 1.102 // Print the detection code. 1.103 if (PrintAssembly) { 1.104 @@ -543,6 +562,69 @@ 1.105 _features = features; 1.106 } 1.107 1.108 +// Power 8: Configure Data Stream Control Register. 1.109 +void VM_Version::config_dscr() { 1.110 + assert(has_lqarx(), "Only execute on Power 8 or later!"); 1.111 + 1.112 + // 7 InstWords for each call (function descriptor + blr instruction). 1.113 + const int code_size = (2+2*7)*BytesPerInstWord; 1.114 + 1.115 + // Allocate space for the code. 1.116 + ResourceMark rm; 1.117 + CodeBuffer cb("config_dscr", code_size, 0); 1.118 + MacroAssembler* a = new MacroAssembler(&cb); 1.119 + 1.120 + // Emit code. 1.121 + uint64_t (*get_dscr)() = (uint64_t(*)())(void *)a->function_entry(); 1.122 + uint32_t *code = (uint32_t *)a->pc(); 1.123 + a->mfdscr(R3); 1.124 + a->blr(); 1.125 + 1.126 + void (*set_dscr)(long) = (void(*)(long))(void *)a->function_entry(); 1.127 + a->mtdscr(R3); 1.128 + a->blr(); 1.129 + 1.130 + uint32_t *code_end = (uint32_t *)a->pc(); 1.131 + a->flush(); 1.132 + 1.133 + // Print the detection code. 1.134 + if (PrintAssembly) { 1.135 + ttyLocker ttyl; 1.136 + tty->print_cr("Decoding dscr configuration stub at " INTPTR_FORMAT " before execution:", p2i(code)); 1.137 + Disassembler::decode((u_char*)code, (u_char*)code_end, tty); 1.138 + } 1.139 + 1.140 + // Apply the configuration if needed. 1.141 + _dscr_val = (*get_dscr)(); 1.142 + if (Verbose) { 1.143 + tty->print_cr("dscr value was 0x%lx" , _dscr_val); 1.144 + } 1.145 + bool change_requested = false; 1.146 + if (DSCR_PPC64 != (uintx)-1) { 1.147 + _dscr_val = DSCR_PPC64; 1.148 + change_requested = true; 1.149 + } 1.150 + if (DSCR_DPFD_PPC64 <= 7) { 1.151 + uint64_t mask = 0x7; 1.152 + if ((_dscr_val & mask) != DSCR_DPFD_PPC64) { 1.153 + _dscr_val = (_dscr_val & ~mask) | (DSCR_DPFD_PPC64); 1.154 + change_requested = true; 1.155 + } 1.156 + } 1.157 + if (DSCR_URG_PPC64 <= 7) { 1.158 + uint64_t mask = 0x7 << 6; 1.159 + if ((_dscr_val & mask) != DSCR_DPFD_PPC64 << 6) { 1.160 + _dscr_val = (_dscr_val & ~mask) | (DSCR_URG_PPC64 << 6); 1.161 + change_requested = true; 1.162 + } 1.163 + } 1.164 + if (change_requested) { 1.165 + (*set_dscr)(_dscr_val); 1.166 + if (Verbose) { 1.167 + tty->print_cr("dscr was set to 0x%lx" , (*get_dscr)()); 1.168 + } 1.169 + } 1.170 +} 1.171 1.172 static int saved_features = 0; 1.173