/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "assembler_sparc.inline.hpp"
#include "memory/resourceArea.hpp"
#include "runtime/stubCodeGenerator.hpp"
#include "vm_version_sparc.hpp"
#ifdef TARGET_OS_FAMILY_linux
# include "os_linux.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_solaris
# include "os_solaris.inline.hpp"
#endif
if( AllocatePrefetchInstr < 0 ) AllocatePrefetchInstr = 0;
// Allocation prefetch settings
(AllocatePrefetchDistance > 0), "invalid value");
if ((AllocatePrefetchDistance % AllocatePrefetchStepSize) != 0 ||
(AllocatePrefetchDistance <= 0)) {
}
warning("BIS instructions are not available on this CPU");
}
if (has_v9()) {
if (ArraycopySrcPrefetchDistance >= 4096)
ArraycopySrcPrefetchDistance = 4064;
if (ArraycopyDstPrefetchDistance >= 4096)
ArraycopyDstPrefetchDistance = 4064;
} else {
if (ArraycopySrcPrefetchDistance > 0) {
warning("prefetch instructions are not available on this CPU");
}
if (ArraycopyDstPrefetchDistance > 0) {
warning("prefetch instructions are not available on this CPU");
}
}
UseSSE = 0; // Only on x86 and x64
_supports_cx8 = has_v9();
_supports_atomic_getset4 = true; // swap instruction
if (is_niagara()) {
// Indirect branch is the same cost as direct
if (FLAG_IS_DEFAULT(UseInlineCaches)) {
FLAG_SET_DEFAULT(UseInlineCaches, false);
}
// Align loops on a single instruction boundary.
if (FLAG_IS_DEFAULT(OptoLoopAlignment)) {
}
// When using CMS or G1, we cannot use memset() in BOT updates
// exposes "phantom zeros" to concurrent readers. See 6948537.
FLAG_SET_DEFAULT(UseMemSetInBOT, false);
}
#ifdef _LP64
// 32-bit oops don't make sense for the 64-bit VM on sparc
// since the 32-bit VM has the same registers and smaller objects.
#endif // _LP64
#ifdef COMPILER2
// Indirect branch is the same cost as direct
if (FLAG_IS_DEFAULT(UseJumpTables)) {
FLAG_SET_DEFAULT(UseJumpTables, true);
}
// Single-issue, so entry and loop tops are
// aligned on a single instruction boundary
}
if (is_niagara_plus()) {
if (has_blk_init() && UseTLAB &&
// Use BIS instruction for TLAB allocation prefetch.
if (FLAG_IS_DEFAULT(AllocatePrefetchStyle)) {
}
// Use smaller prefetch distance with BIS
}
}
if (is_T4()) {
// Double number of prefetched cache lines on T4
// since L2 cache line size is smaller (32 bytes).
if (FLAG_IS_DEFAULT(AllocatePrefetchLines)) {
}
}
}
// Use different prefetch distance without BIS
}
if (AllocatePrefetchInstr == 1) {
// Need a space at the end of TLAB for BIS since it
// will fault when accessing memory outside of heap.
// +1 for rounding up to next cache line, +1 to be safe
}
}
#endif
}
// Use hardware population count instruction if available.
if (has_hardware_popc()) {
}
} else if (UsePopCountInstruction) {
warning("POPC instruction is not available on this CPU");
FLAG_SET_DEFAULT(UsePopCountInstruction, false);
}
// T4 and newer Sparc cpus have new compare and branch instruction.
if (has_cbcond()) {
if (FLAG_IS_DEFAULT(UseCBCond)) {
FLAG_SET_DEFAULT(UseCBCond, true);
}
} else if (UseCBCond) {
warning("CBCOND instruction is not available on this CPU");
FLAG_SET_DEFAULT(UseCBCond, false);
}
if (has_block_zeroing()) {
if (FLAG_IS_DEFAULT(UseBlockZeroing)) {
FLAG_SET_DEFAULT(UseBlockZeroing, true);
}
} else if (UseBlockZeroing) {
warning("BIS zeroing instructions are not available on this CPU");
FLAG_SET_DEFAULT(UseBlockZeroing, false);
}
if (has_block_zeroing()) { // has_blk_init() && is_T4(): core's local L2 cache
if (FLAG_IS_DEFAULT(UseBlockCopy)) {
FLAG_SET_DEFAULT(UseBlockCopy, true);
}
} else if (UseBlockCopy) {
warning("BIS instructions are not available or expensive on this CPU");
FLAG_SET_DEFAULT(UseBlockCopy, false);
}
#ifdef COMPILER2
// T4 and newer Sparc cpus have fast RDPC.
}
// Currently not supported anywhere.
FLAG_SET_DEFAULT(UseFPUForSpilling, false);
MaxVectorSize = 8;
assert((InteriorEntryAlignment % relocInfo::addr_unit()) == 0, "alignment is not a multiple of NOP size");
#endif
assert((CodeEntryAlignment % relocInfo::addr_unit()) == 0, "alignment is not a multiple of NOP size");
assert((OptoLoopAlignment % relocInfo::addr_unit()) == 0, "alignment is not a multiple of NOP size");
// buf is started with ", " or is empty
// UseVIS is set to the smallest of what hardware supports and what
// the command line requires. I.e., you cannot set UseVIS to 3 on
// older UltraSparc which do not support it.
if (!has_vis3()) // Drop to 2 if no VIS3 support
if (!has_vis2()) // Drop to 1 if no VIS2 support
if (!has_vis1()) // Drop to 0 if no VIS1 support
UseVIS = 0;
#ifndef PRODUCT
if (PrintMiscellaneous && Verbose) {
if (AllocatePrefetchStyle <= 0) {
} else {
if (AllocatePrefetchInstr == 0) {
} else if (AllocatePrefetchInstr == 1) {
}
if (AllocatePrefetchLines > 1) {
tty->print_cr(" at distance %d, %d lines of %d bytes", AllocatePrefetchDistance, AllocatePrefetchLines, AllocatePrefetchStepSize);
} else {
tty->print_cr(" at distance %d, one line of %d bytes", AllocatePrefetchDistance, AllocatePrefetchStepSize);
}
}
if (PrefetchCopyIntervalInBytes > 0) {
}
if (PrefetchScanIntervalInBytes > 0) {
}
if (PrefetchFieldsAhead > 0) {
}
}
#endif // PRODUCT
}
}
if (UseV8InstrsOnly) {
return generic_v8_m;
}
warning("Cannot recognize SPARC version. Default to V9");
}
if (UseNiagaraInstrs) { // Force code generation for Niagara
if (is_T_family(features)) {
// Happy to accomodate...
} else {
features |= T_family_m;
}
} else {
} else {
// Happy to accomodate...
}
}
return features;
}
static int saved_features = 0;
}
}
unsigned int result;
if (is_M_series()) {
// for now, use same gc thread calculation for M-series as for niagara-plus
// in future, we may want to tweak parameters for nof_parallel_worker_thread
} else if (is_niagara_plus()) {
} else {
}
return result;
}