Merge
This commit is contained in:
commit
b836b5b512
hotspot/src
cpu/sparc/vm
abstractInterpreter_sparc.cppassembler_sparc.cppassembler_sparc.hppassembler_sparc.inline.hppc1_LIRAssembler_sparc.cppc1_LIRGenerator_sparc.cppc2_globals_sparc.hppglobals_sparc.hppmacroAssembler_sparc.cppmacroAssembler_sparc.hppmacroAssembler_sparc.inline.hppmethodHandles_sparc.hppnativeInst_sparc.hppsparc.adtemplateInterpreterGenerator_sparc.cppvmStructs_sparc.hppvm_version_sparc.cppvm_version_sparc.hppvmreg_sparc.hpp
jdk.internal.vm.ci/share/classes
jdk.vm.ci.hotspot.sparc/src/jdk/vm/ci/hotspot/sparc
jdk.vm.ci.sparc/src/jdk/vm/ci/sparc
os_cpu/solaris_sparc/vm
share/vm
@ -52,8 +52,16 @@ int AbstractInterpreter::BasicType_as_index(BasicType type) {
|
||||
return i;
|
||||
}
|
||||
|
||||
// These should never be compiled since the interpreter will prefer the compiled
|
||||
// version to the intrinsic version.
|
||||
bool AbstractInterpreter::can_be_compiled(methodHandle m) {
|
||||
// No special entry points that preclude compilation
|
||||
switch (method_kind(m)) {
|
||||
case Interpreter::java_lang_math_fmaD:
|
||||
case Interpreter::java_lang_math_fmaF:
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,36 @@
|
||||
#include "asm/assembler.hpp"
|
||||
#include "asm/assembler.inline.hpp"
|
||||
|
||||
#include "assembler_sparc.hpp"
|
||||
|
||||
int AbstractAssembler::code_fill_byte() {
|
||||
return 0x00; // illegal instruction 0x00000000
|
||||
}
|
||||
|
||||
#ifdef VALIDATE_PIPELINE
|
||||
/* Walk over the current code section and verify that there are no obvious
|
||||
* pipeline hazards exposed in the code generated.
|
||||
*/
|
||||
void Assembler::validate_no_pipeline_hazards() {
|
||||
const CodeSection* csect = code_section();
|
||||
|
||||
address addr0 = csect->start();
|
||||
address addrN = csect->end();
|
||||
uint32_t prev = 0;
|
||||
|
||||
assert((addrN - addr0) % BytesPerInstWord == 0, "must be");
|
||||
|
||||
for (address pc = addr0; pc != addrN; pc += BytesPerInstWord) {
|
||||
uint32_t insn = *reinterpret_cast<uint32_t*>(pc);
|
||||
|
||||
// 1. General case: No CTI immediately after other CTI
|
||||
assert(!(is_cti(prev) && is_cti(insn)), "CTI-CTI not allowed.");
|
||||
|
||||
// 2. Special case: No CTI immediately after/before RDPC
|
||||
assert(!(is_cti(prev) && is_rdpc(insn)), "CTI-RDPC not allowed.");
|
||||
assert(!(is_rdpc(prev) && is_cti(insn)), "RDPC-CTI not allowed.");
|
||||
|
||||
prev = insn;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -440,6 +440,31 @@ void LIR_Assembler::klass2reg_with_patching(Register reg, CodeEmitInfo *info) {
|
||||
}
|
||||
|
||||
void LIR_Assembler::emit_op3(LIR_Op3* op) {
|
||||
switch (op->code()) {
|
||||
case lir_idiv:
|
||||
case lir_irem: // Both idiv & irem are handled after the switch (below).
|
||||
break;
|
||||
case lir_fmaf:
|
||||
__ fmadd(FloatRegisterImpl::S,
|
||||
op->in_opr1()->as_float_reg(),
|
||||
op->in_opr2()->as_float_reg(),
|
||||
op->in_opr3()->as_float_reg(),
|
||||
op->result_opr()->as_float_reg());
|
||||
return;
|
||||
case lir_fmad:
|
||||
__ fmadd(FloatRegisterImpl::D,
|
||||
op->in_opr1()->as_double_reg(),
|
||||
op->in_opr2()->as_double_reg(),
|
||||
op->in_opr3()->as_double_reg(),
|
||||
op->result_opr()->as_double_reg());
|
||||
return;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
break;
|
||||
}
|
||||
|
||||
// Handle idiv & irem:
|
||||
|
||||
Register Rdividend = op->in_opr1()->as_register();
|
||||
Register Rdivisor = noreg;
|
||||
Register Rscratch = op->in_opr3()->as_register();
|
||||
|
@ -953,7 +953,29 @@ void LIRGenerator::do_update_CRC32C(Intrinsic* x) {
|
||||
}
|
||||
|
||||
void LIRGenerator::do_FmaIntrinsic(Intrinsic* x) {
|
||||
fatal("FMA intrinsic is not implemented on this platform");
|
||||
assert(x->number_of_arguments() == 3, "wrong type");
|
||||
assert(UseFMA, "Needs FMA instructions support.");
|
||||
|
||||
LIRItem a(x->argument_at(0), this);
|
||||
LIRItem b(x->argument_at(1), this);
|
||||
LIRItem c(x->argument_at(2), this);
|
||||
|
||||
a.load_item();
|
||||
b.load_item();
|
||||
c.load_item();
|
||||
|
||||
LIR_Opr ina = a.result();
|
||||
LIR_Opr inb = b.result();
|
||||
LIR_Opr inc = c.result();
|
||||
LIR_Opr res = rlock_result(x);
|
||||
|
||||
switch (x->id()) {
|
||||
case vmIntrinsics::_fmaF: __ fmaf(ina, inb, inc, res); break;
|
||||
case vmIntrinsics::_fmaD: __ fmad(ina, inb, inc, res); break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void LIRGenerator::do_vectorizedMismatch(Intrinsic* x) {
|
||||
|
@ -33,7 +33,7 @@
|
||||
|
||||
define_pd_global(bool, BackgroundCompilation, true);
|
||||
define_pd_global(bool, CICompileOSR, true);
|
||||
define_pd_global(bool, InlineIntrinsics, false);
|
||||
define_pd_global(bool, InlineIntrinsics, true);
|
||||
define_pd_global(bool, PreferInterpreterNativeStubs, false);
|
||||
define_pd_global(bool, ProfileTraps, true);
|
||||
define_pd_global(bool, UseOnStackReplacement, true);
|
||||
|
@ -117,9 +117,6 @@ define_pd_global(intx, InitArrayShortSize, 8*BytesPerLong);
|
||||
"Minimum size in bytes when block copy will be used") \
|
||||
range(1, max_jint) \
|
||||
\
|
||||
develop(bool, UseV8InstrsOnly, false, \
|
||||
"Use SPARC-V8 Compliant instruction subset") \
|
||||
\
|
||||
product(bool, UseNiagaraInstrs, false, \
|
||||
"Use Niagara-efficient instruction subset") \
|
||||
\
|
||||
|
@ -651,9 +651,9 @@ void MacroAssembler::card_table_write(jbyte* byte_map_base,
|
||||
void MacroAssembler::internal_sethi(const AddressLiteral& addrlit, Register d, bool ForceRelocatable) {
|
||||
address save_pc;
|
||||
int shiftcnt;
|
||||
# ifdef CHECK_DELAY
|
||||
assert_not_delayed((char*) "cannot put two instructions in delay slot");
|
||||
# endif
|
||||
#ifdef VALIDATE_PIPELINE
|
||||
assert_no_delay("Cannot put two instructions in delay-slot.");
|
||||
#endif
|
||||
v9_dep();
|
||||
save_pc = pc();
|
||||
|
||||
@ -752,7 +752,7 @@ void MacroAssembler::internal_set(const AddressLiteral& addrlit, Register d, boo
|
||||
return;
|
||||
}
|
||||
}
|
||||
assert_not_delayed((char*) "cannot put two instructions in delay slot");
|
||||
assert_no_delay("Cannot put two instructions in delay-slot.");
|
||||
internal_sethi(addrlit, d, ForceRelocatable);
|
||||
if (ForceRelocatable || addrlit.rspec().type() != relocInfo::none || addrlit.low10() != 0) {
|
||||
add(d, addrlit.low10(), d, addrlit.rspec());
|
||||
@ -4613,7 +4613,7 @@ void MacroAssembler::has_negatives(Register inp, Register size, Register result,
|
||||
|
||||
// Use BIS for zeroing (count is in bytes).
|
||||
void MacroAssembler::bis_zeroing(Register to, Register count, Register temp, Label& Ldone) {
|
||||
assert(UseBlockZeroing && VM_Version::has_block_zeroing(), "only works with BIS zeroing");
|
||||
assert(UseBlockZeroing && VM_Version::has_blk_zeroing(), "only works with BIS zeroing");
|
||||
Register end = count;
|
||||
int cache_line_size = VM_Version::prefetch_data_size();
|
||||
assert(cache_line_size > 0, "cache line size should be known for this code");
|
||||
|
@ -662,9 +662,6 @@ class MacroAssembler : public Assembler {
|
||||
inline void fbp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt = relocInfo::none );
|
||||
inline void fbp( Condition c, bool a, CC cc, Predict p, Label& L );
|
||||
|
||||
// get PC the best way
|
||||
inline int get_pc( Register d );
|
||||
|
||||
// Sparc shorthands(pp 85, V8 manual, pp 289 V9 manual)
|
||||
inline void cmp( Register s1, Register s2 );
|
||||
inline void cmp( Register s1, int simm13a );
|
||||
@ -1396,7 +1393,7 @@ public:
|
||||
void movitof_revbytes(Register src, FloatRegister dst, Register tmp1, Register tmp2);
|
||||
void movftoi_revbytes(FloatRegister src, Register dst, Register tmp1, Register tmp2);
|
||||
|
||||
// CRC32 code for java.util.zip.CRC32::updateBytes0() instrinsic.
|
||||
// CRC32 code for java.util.zip.CRC32::updateBytes0() intrinsic.
|
||||
void kernel_crc32(Register crc, Register buf, Register len, Register table);
|
||||
// Fold 128-bit data chunk
|
||||
void fold_128bit_crc32(Register xcrc_hi, Register xcrc_lo, Register xK_hi, Register xK_lo, Register xtmp_hi, Register xtmp_lo, Register buf, int offset);
|
||||
@ -1404,7 +1401,7 @@ public:
|
||||
// Fold 8-bit data
|
||||
void fold_8bit_crc32(Register xcrc, Register table, Register xtmp, Register tmp);
|
||||
void fold_8bit_crc32(Register crc, Register table, Register tmp);
|
||||
// CRC32C code for java.util.zip.CRC32C::updateBytes/updateDirectByteBuffer instrinsic.
|
||||
// CRC32C code for java.util.zip.CRC32C::updateBytes/updateDirectByteBuffer intrinsic.
|
||||
void kernel_crc32c(Register crc, Register buf, Register len, Register table);
|
||||
|
||||
};
|
||||
|
@ -185,7 +185,8 @@ inline void MacroAssembler::br( Condition c, bool a, Predict p, address d, reloc
|
||||
}
|
||||
|
||||
inline void MacroAssembler::br( Condition c, bool a, Predict p, Label& L ) {
|
||||
insert_nop_after_cbcond();
|
||||
// See note[+] on 'avoid_pipeline_stalls()', in "assembler_sparc.inline.hpp".
|
||||
avoid_pipeline_stall();
|
||||
br(c, a, p, target(L));
|
||||
}
|
||||
|
||||
@ -197,7 +198,7 @@ inline void MacroAssembler::brx( Condition c, bool a, Predict p, address d, relo
|
||||
}
|
||||
|
||||
inline void MacroAssembler::brx( Condition c, bool a, Predict p, Label& L ) {
|
||||
insert_nop_after_cbcond();
|
||||
avoid_pipeline_stall();
|
||||
brx(c, a, p, target(L));
|
||||
}
|
||||
|
||||
@ -219,7 +220,7 @@ inline void MacroAssembler::fb( Condition c, bool a, Predict p, address d, reloc
|
||||
}
|
||||
|
||||
inline void MacroAssembler::fb( Condition c, bool a, Predict p, Label& L ) {
|
||||
insert_nop_after_cbcond();
|
||||
avoid_pipeline_stall();
|
||||
fb(c, a, p, target(L));
|
||||
}
|
||||
|
||||
@ -268,13 +269,12 @@ inline void MacroAssembler::call( address d, RelocationHolder const& rspec ) {
|
||||
}
|
||||
}
|
||||
|
||||
inline void MacroAssembler::call( Label& L, relocInfo::relocType rt ) {
|
||||
insert_nop_after_cbcond();
|
||||
MacroAssembler::call( target(L), rt);
|
||||
inline void MacroAssembler::call( Label& L, relocInfo::relocType rt ) {
|
||||
avoid_pipeline_stall();
|
||||
MacroAssembler::call(target(L), rt);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline void MacroAssembler::callr( Register s1, Register s2 ) { jmpl( s1, s2, O7 ); }
|
||||
inline void MacroAssembler::callr( Register s1, int simm13a, RelocationHolder const& rspec ) { jmpl( s1, simm13a, O7, rspec); }
|
||||
|
||||
@ -304,13 +304,6 @@ inline void MacroAssembler::retl( bool trace ) {
|
||||
}
|
||||
}
|
||||
|
||||
// clobbers o7 on V8!!
|
||||
// returns delta from gotten pc to addr after
|
||||
inline int MacroAssembler::get_pc( Register d ) {
|
||||
int x = offset();
|
||||
rdpc(d);
|
||||
return offset() - x;
|
||||
}
|
||||
|
||||
inline void MacroAssembler::cmp( Register s1, Register s2 ) { subcc( s1, s2, G0 ); }
|
||||
inline void MacroAssembler::cmp( Register s1, int simm13a ) { subcc( s1, simm13a, G0 ); }
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -27,7 +27,7 @@
|
||||
|
||||
// Adapters
|
||||
enum /* platform_dependent_constants */ {
|
||||
adapter_code_size = NOT_LP64(23000 DEBUG_ONLY(+ 40000)) LP64_ONLY(35000 DEBUG_ONLY(+ 50000))
|
||||
adapter_code_size = 35000 DEBUG_ONLY(+ 50000)
|
||||
};
|
||||
|
||||
// Additional helper methods for MethodHandles code generation:
|
||||
|
@ -67,11 +67,8 @@ class NativeInstruction VALUE_OBJ_CLASS_SPEC {
|
||||
bool is_illegal();
|
||||
bool is_zombie() {
|
||||
int x = long_at(0);
|
||||
return is_op3(x,
|
||||
Assembler::ldsw_op3,
|
||||
Assembler::ldst_op)
|
||||
&& Assembler::inv_rs1(x) == G0
|
||||
&& Assembler::inv_rd(x) == O7;
|
||||
return (is_op3(x, Assembler::ldsw_op3, Assembler::ldst_op) &&
|
||||
inv_rs1(x) == G0 && inv_rd(x) == O7);
|
||||
}
|
||||
bool is_ic_miss_trap(); // Inline-cache uses a trap to detect a miss
|
||||
bool is_return() {
|
||||
@ -129,29 +126,11 @@ class NativeInstruction VALUE_OBJ_CLASS_SPEC {
|
||||
bool is_load_store_with_small_offset(Register reg);
|
||||
|
||||
public:
|
||||
#ifdef ASSERT
|
||||
static int rdpc_instruction() { return Assembler::op(Assembler::arith_op ) | Assembler::op3(Assembler::rdreg_op3) | Assembler::u_field(5, 18, 14) | Assembler::rd(O7); }
|
||||
#else
|
||||
// Temporary fix: in optimized mode, u_field is a macro for efficiency reasons (see Assembler::u_field) - needs to be fixed
|
||||
static int rdpc_instruction() { return Assembler::op(Assembler::arith_op ) | Assembler::op3(Assembler::rdreg_op3) | u_field(5, 18, 14) | Assembler::rd(O7); }
|
||||
#endif
|
||||
static int nop_instruction() { return Assembler::op(Assembler::branch_op) | Assembler::op2(Assembler::sethi_op2); }
|
||||
static int illegal_instruction(); // the output of __ breakpoint_trap()
|
||||
static int call_instruction(address destination, address pc) { return Assembler::op(Assembler::call_op) | Assembler::wdisp((intptr_t)destination, (intptr_t)pc, 30); }
|
||||
|
||||
static int branch_instruction(Assembler::op2s op2val, Assembler::Condition c, bool a) {
|
||||
return Assembler::op(Assembler::branch_op) | Assembler::op2(op2val) | Assembler::annul(a) | Assembler::cond(c);
|
||||
}
|
||||
|
||||
static int op3_instruction(Assembler::ops opval, Register rd, Assembler::op3s op3val, Register rs1, int simm13a) {
|
||||
return Assembler::op(opval) | Assembler::rd(rd) | Assembler::op3(op3val) | Assembler::rs1(rs1) | Assembler::immed(true) | Assembler::simm(simm13a, 13);
|
||||
}
|
||||
|
||||
static int sethi_instruction(Register rd, int imm22a) {
|
||||
return Assembler::op(Assembler::branch_op) | Assembler::rd(rd) | Assembler::op2(Assembler::sethi_op2) | Assembler::hi22(imm22a);
|
||||
}
|
||||
|
||||
protected:
|
||||
protected:
|
||||
address addr_at(int offset) const { return address(this) + offset; }
|
||||
int long_at(int offset) const { return *(int*)addr_at(offset); }
|
||||
void set_long_at(int offset, int i); /* deals with I-cache */
|
||||
|
@ -1072,7 +1072,13 @@ void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
|
||||
|
||||
__ rdpc(r);
|
||||
|
||||
if (disp != 0) {
|
||||
if (disp == 0) {
|
||||
// Emitting an additional 'nop' instruction in order not to cause a code
|
||||
// size adjustment in the code following the table setup (if the instruction
|
||||
// immediately following after this section is a CTI).
|
||||
__ nop();
|
||||
}
|
||||
else {
|
||||
assert(r != O7, "need temporary");
|
||||
__ sub(r, __ ensure_simm13_or_reg(disp, O7), r);
|
||||
}
|
||||
@ -1760,10 +1766,8 @@ const bool Matcher::pass_original_key_for_aes() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// USII supports fxtof through the whole range of number, USIII doesn't
|
||||
const bool Matcher::convL2FSupported(void) {
|
||||
return VM_Version::has_fast_fxtof();
|
||||
}
|
||||
// NOTE: All currently supported SPARC HW provides fast conversion.
|
||||
const bool Matcher::convL2FSupported(void) { return true; }
|
||||
|
||||
// Is this branch offset short enough that a short branch can be used?
|
||||
//
|
||||
@ -1789,9 +1793,9 @@ const bool Matcher::init_array_count_is_in_bytes = true;
|
||||
// No additional cost for CMOVL.
|
||||
const int Matcher::long_cmove_cost() { return 0; }
|
||||
|
||||
// CMOVF/CMOVD are expensive on T4 and on SPARC64.
|
||||
// CMOVF/CMOVD are expensive on e.g., T4 and SPARC64.
|
||||
const int Matcher::float_cmove_cost() {
|
||||
return (VM_Version::is_T4() || VM_Version::is_sparc64()) ? ConditionalMoveLimit : 0;
|
||||
return VM_Version::has_fast_cmove() ? 0 : ConditionalMoveLimit;
|
||||
}
|
||||
|
||||
// Does the CPU require late expand (see block.cpp for description of late expand)?
|
||||
@ -2623,6 +2627,33 @@ enc_class fsqrtd (dflt_reg dst, dflt_reg src) %{
|
||||
__ fsqrt(FloatRegisterImpl::D, Fsrc, Fdst);
|
||||
%}
|
||||
|
||||
|
||||
|
||||
enc_class fmadds (sflt_reg dst, sflt_reg a, sflt_reg b, sflt_reg c) %{
|
||||
MacroAssembler _masm(&cbuf);
|
||||
|
||||
FloatRegister Frd = reg_to_SingleFloatRegister_object($dst$$reg);
|
||||
FloatRegister Fra = reg_to_SingleFloatRegister_object($a$$reg);
|
||||
FloatRegister Frb = reg_to_SingleFloatRegister_object($b$$reg);
|
||||
FloatRegister Frc = reg_to_SingleFloatRegister_object($c$$reg);
|
||||
|
||||
__ fmadd(FloatRegisterImpl::S, Fra, Frb, Frc, Frd);
|
||||
%}
|
||||
|
||||
enc_class fmaddd (dflt_reg dst, dflt_reg a, dflt_reg b, dflt_reg c) %{
|
||||
MacroAssembler _masm(&cbuf);
|
||||
|
||||
FloatRegister Frd = reg_to_DoubleFloatRegister_object($dst$$reg);
|
||||
FloatRegister Fra = reg_to_DoubleFloatRegister_object($a$$reg);
|
||||
FloatRegister Frb = reg_to_DoubleFloatRegister_object($b$$reg);
|
||||
FloatRegister Frc = reg_to_DoubleFloatRegister_object($c$$reg);
|
||||
|
||||
__ fmadd(FloatRegisterImpl::D, Fra, Frb, Frc, Frd);
|
||||
%}
|
||||
|
||||
|
||||
|
||||
|
||||
enc_class fmovs (dflt_reg dst, dflt_reg src) %{
|
||||
MacroAssembler _masm(&cbuf);
|
||||
|
||||
@ -3194,7 +3225,7 @@ operand immP() %{
|
||||
|
||||
// Pointer Immediate: 64-bit
|
||||
operand immP_set() %{
|
||||
predicate(!VM_Version::is_niagara_plus());
|
||||
predicate(!VM_Version::has_fast_ld());
|
||||
match(ConP);
|
||||
|
||||
op_cost(5);
|
||||
@ -3206,7 +3237,7 @@ operand immP_set() %{
|
||||
// Pointer Immediate: 64-bit
|
||||
// From Niagara2 processors on a load should be better than materializing.
|
||||
operand immP_load() %{
|
||||
predicate(VM_Version::is_niagara_plus() && (n->bottom_type()->isa_oop_ptr() || (MacroAssembler::insts_for_set(n->get_ptr()) > 3)));
|
||||
predicate(VM_Version::has_fast_ld() && (n->bottom_type()->isa_oop_ptr() || (MacroAssembler::insts_for_set(n->get_ptr()) > 3)));
|
||||
match(ConP);
|
||||
|
||||
op_cost(5);
|
||||
@ -3217,7 +3248,7 @@ operand immP_load() %{
|
||||
|
||||
// Pointer Immediate: 64-bit
|
||||
operand immP_no_oop_cheap() %{
|
||||
predicate(VM_Version::is_niagara_plus() && !n->bottom_type()->isa_oop_ptr() && (MacroAssembler::insts_for_set(n->get_ptr()) <= 3));
|
||||
predicate(VM_Version::has_fast_ld() && !n->bottom_type()->isa_oop_ptr() && (MacroAssembler::insts_for_set(n->get_ptr()) <= 3));
|
||||
match(ConP);
|
||||
|
||||
op_cost(5);
|
||||
@ -3341,7 +3372,7 @@ operand immL_32bits() %{
|
||||
|
||||
// Long Immediate: cheap (materialize in <= 3 instructions)
|
||||
operand immL_cheap() %{
|
||||
predicate(!VM_Version::is_niagara_plus() || MacroAssembler::insts_for_set64(n->get_long()) <= 3);
|
||||
predicate(!VM_Version::has_fast_ld() || MacroAssembler::insts_for_set64(n->get_long()) <= 3);
|
||||
match(ConL);
|
||||
op_cost(0);
|
||||
|
||||
@ -3351,7 +3382,7 @@ operand immL_cheap() %{
|
||||
|
||||
// Long Immediate: expensive (materialize in > 3 instructions)
|
||||
operand immL_expensive() %{
|
||||
predicate(VM_Version::is_niagara_plus() && MacroAssembler::insts_for_set64(n->get_long()) > 3);
|
||||
predicate(VM_Version::has_fast_ld() && MacroAssembler::insts_for_set64(n->get_long()) > 3);
|
||||
match(ConL);
|
||||
op_cost(0);
|
||||
|
||||
@ -4536,6 +4567,26 @@ pipe_class fdivD_reg_reg(regD dst, regD src1, regD src2) %{
|
||||
FDIV : C(17);
|
||||
%}
|
||||
|
||||
// Fused floating-point multiply-add float.
|
||||
pipe_class fmaF_regx4(regF dst, regF src1, regF src2, regF src3) %{
|
||||
single_instruction;
|
||||
dst : X(write);
|
||||
src1 : E(read);
|
||||
src2 : E(read);
|
||||
src3 : E(read);
|
||||
FM : R;
|
||||
%}
|
||||
|
||||
// Fused gloating-point multiply-add double.
|
||||
pipe_class fmaD_regx4(regD dst, regD src1, regD src2, regD src3) %{
|
||||
single_instruction;
|
||||
dst : X(write);
|
||||
src1 : E(read);
|
||||
src2 : E(read);
|
||||
src3 : E(read);
|
||||
FM : R;
|
||||
%}
|
||||
|
||||
// Floating Point Move/Negate/Abs Float
|
||||
pipe_class faddF_reg(regF dst, regF src) %{
|
||||
single_instruction;
|
||||
@ -7527,6 +7578,24 @@ instruct sqrtD_reg_reg(regD dst, regD src) %{
|
||||
ins_pipe(fdivD_reg_reg);
|
||||
%}
|
||||
|
||||
// Single precision fused floating-point multiply-add (d = a * b + c).
|
||||
instruct fmaF_regx4(regF dst, regF a, regF b, regF c) %{
|
||||
predicate(UseFMA);
|
||||
match(Set dst (FmaF c (Binary a b)));
|
||||
format %{ "fmadds $a,$b,$c,$dst\t# $dst = $a * $b + $c" %}
|
||||
ins_encode(fmadds(dst, a, b, c));
|
||||
ins_pipe(fmaF_regx4);
|
||||
%}
|
||||
|
||||
// Double precision fused floating-point multiply-add (d = a * b + c).
|
||||
instruct fmaD_regx4(regD dst, regD a, regD b, regD c) %{
|
||||
predicate(UseFMA);
|
||||
match(Set dst (FmaD c (Binary a b)));
|
||||
format %{ "fmaddd $a,$b,$c,$dst\t# $dst = $a * $b + $c" %}
|
||||
ins_encode(fmaddd(dst, a, b, c));
|
||||
ins_pipe(fmaD_regx4);
|
||||
%}
|
||||
|
||||
//----------Logical Instructions-----------------------------------------------
|
||||
// And Instructions
|
||||
// Register And
|
||||
@ -8241,40 +8310,6 @@ instruct mulD_regD_regD(regD dst, regD src1, regD src2) %{
|
||||
ins_pipe(fmulD_reg_reg);
|
||||
%}
|
||||
|
||||
instruct convL2D_reg_slow_fxtof(regD dst, stackSlotL src) %{
|
||||
match(Set dst (ConvL2D src));
|
||||
ins_cost(DEFAULT_COST*8 + MEMORY_REF_COST*6);
|
||||
|
||||
expand %{
|
||||
regD_low tmpsrc;
|
||||
iRegI ix43300000;
|
||||
iRegI ix41f00000;
|
||||
stackSlotL lx43300000;
|
||||
stackSlotL lx41f00000;
|
||||
regD_low dx43300000;
|
||||
regD dx41f00000;
|
||||
regD tmp1;
|
||||
regD_low tmp2;
|
||||
regD tmp3;
|
||||
regD tmp4;
|
||||
|
||||
stkL_to_regD(tmpsrc, src);
|
||||
|
||||
loadConI_x43300000(ix43300000);
|
||||
loadConI_x41f00000(ix41f00000);
|
||||
regI_to_stkLHi(lx43300000, ix43300000);
|
||||
regI_to_stkLHi(lx41f00000, ix41f00000);
|
||||
stkL_to_regD(dx43300000, lx43300000);
|
||||
stkL_to_regD(dx41f00000, lx41f00000);
|
||||
|
||||
convI2D_regDHi_regD(tmp1, tmpsrc);
|
||||
regDHi_regDLo_to_regD(tmp2, dx43300000, tmpsrc);
|
||||
subD_regD_regD(tmp3, tmp2, dx43300000);
|
||||
mulD_regD_regD(tmp4, tmp1, dx41f00000);
|
||||
addD_regD_regD(dst, tmp3, tmp4);
|
||||
%}
|
||||
%}
|
||||
|
||||
// Long to Double conversion using fast fxtof
|
||||
instruct convL2D_helper(regD dst, regD tmp) %{
|
||||
effect(DEF dst, USE tmp);
|
||||
@ -8286,7 +8321,6 @@ instruct convL2D_helper(regD dst, regD tmp) %{
|
||||
%}
|
||||
|
||||
instruct convL2D_stk_fast_fxtof(regD dst, stackSlotL src) %{
|
||||
predicate(VM_Version::has_fast_fxtof());
|
||||
match(Set dst (ConvL2D src));
|
||||
ins_cost(DEFAULT_COST + 3 * MEMORY_REF_COST);
|
||||
expand %{
|
||||
@ -8661,7 +8695,7 @@ instruct branch_short(label labl) %{
|
||||
predicate(UseCBCond);
|
||||
effect(USE labl);
|
||||
|
||||
size(4);
|
||||
size(4); // Assuming no NOP inserted.
|
||||
ins_cost(BRANCH_COST);
|
||||
format %{ "BA $labl\t! short branch" %}
|
||||
ins_encode %{
|
||||
@ -9002,7 +9036,7 @@ instruct cmpI_reg_branch_short(cmpOp cmp, iRegI op1, iRegI op2, label labl, flag
|
||||
predicate(UseCBCond);
|
||||
effect(USE labl, KILL icc);
|
||||
|
||||
size(4);
|
||||
size(4); // Assuming no NOP inserted.
|
||||
ins_cost(BRANCH_COST);
|
||||
format %{ "CWB$cmp $op1,$op2,$labl\t! int" %}
|
||||
ins_encode %{
|
||||
@ -9020,7 +9054,7 @@ instruct cmpI_imm_branch_short(cmpOp cmp, iRegI op1, immI5 op2, label labl, flag
|
||||
predicate(UseCBCond);
|
||||
effect(USE labl, KILL icc);
|
||||
|
||||
size(4);
|
||||
size(4); // Assuming no NOP inserted.
|
||||
ins_cost(BRANCH_COST);
|
||||
format %{ "CWB$cmp $op1,$op2,$labl\t! int" %}
|
||||
ins_encode %{
|
||||
@ -9038,7 +9072,7 @@ instruct cmpU_reg_branch_short(cmpOpU cmp, iRegI op1, iRegI op2, label labl, fla
|
||||
predicate(UseCBCond);
|
||||
effect(USE labl, KILL icc);
|
||||
|
||||
size(4);
|
||||
size(4); // Assuming no NOP inserted.
|
||||
ins_cost(BRANCH_COST);
|
||||
format %{ "CWB$cmp $op1,$op2,$labl\t! unsigned" %}
|
||||
ins_encode %{
|
||||
@ -9056,7 +9090,7 @@ instruct cmpU_imm_branch_short(cmpOpU cmp, iRegI op1, immI5 op2, label labl, fla
|
||||
predicate(UseCBCond);
|
||||
effect(USE labl, KILL icc);
|
||||
|
||||
size(4);
|
||||
size(4); // Assuming no NOP inserted.
|
||||
ins_cost(BRANCH_COST);
|
||||
format %{ "CWB$cmp $op1,$op2,$labl\t! unsigned" %}
|
||||
ins_encode %{
|
||||
@ -9074,7 +9108,7 @@ instruct cmpL_reg_branch_short(cmpOp cmp, iRegL op1, iRegL op2, label labl, flag
|
||||
predicate(UseCBCond);
|
||||
effect(USE labl, KILL xcc);
|
||||
|
||||
size(4);
|
||||
size(4); // Assuming no NOP inserted.
|
||||
ins_cost(BRANCH_COST);
|
||||
format %{ "CXB$cmp $op1,$op2,$labl\t! long" %}
|
||||
ins_encode %{
|
||||
@ -9092,7 +9126,7 @@ instruct cmpL_imm_branch_short(cmpOp cmp, iRegL op1, immL5 op2, label labl, flag
|
||||
predicate(UseCBCond);
|
||||
effect(USE labl, KILL xcc);
|
||||
|
||||
size(4);
|
||||
size(4); // Assuming no NOP inserted.
|
||||
ins_cost(BRANCH_COST);
|
||||
format %{ "CXB$cmp $op1,$op2,$labl\t! long" %}
|
||||
ins_encode %{
|
||||
@ -9111,7 +9145,7 @@ instruct cmpP_reg_branch_short(cmpOpP cmp, iRegP op1, iRegP op2, label labl, fla
|
||||
predicate(UseCBCond);
|
||||
effect(USE labl, KILL pcc);
|
||||
|
||||
size(4);
|
||||
size(4); // Assuming no NOP inserted.
|
||||
ins_cost(BRANCH_COST);
|
||||
format %{ "CXB$cmp $op1,$op2,$labl\t! ptr" %}
|
||||
ins_encode %{
|
||||
@ -9129,7 +9163,7 @@ instruct cmpP_null_branch_short(cmpOpP cmp, iRegP op1, immP0 null, label labl, f
|
||||
predicate(UseCBCond);
|
||||
effect(USE labl, KILL pcc);
|
||||
|
||||
size(4);
|
||||
size(4); // Assuming no NOP inserted.
|
||||
ins_cost(BRANCH_COST);
|
||||
format %{ "CXB$cmp $op1,0,$labl\t! ptr" %}
|
||||
ins_encode %{
|
||||
@ -9147,7 +9181,7 @@ instruct cmpN_reg_branch_short(cmpOp cmp, iRegN op1, iRegN op2, label labl, flag
|
||||
predicate(UseCBCond);
|
||||
effect(USE labl, KILL icc);
|
||||
|
||||
size(4);
|
||||
size(4); // Assuming no NOP inserted.
|
||||
ins_cost(BRANCH_COST);
|
||||
format %{ "CWB$cmp $op1,$op2,$labl\t! compressed ptr" %}
|
||||
ins_encode %{
|
||||
@ -9165,7 +9199,7 @@ instruct cmpN_null_branch_short(cmpOp cmp, iRegN op1, immN0 null, label labl, fl
|
||||
predicate(UseCBCond);
|
||||
effect(USE labl, KILL icc);
|
||||
|
||||
size(4);
|
||||
size(4); // Assuming no NOP inserted.
|
||||
ins_cost(BRANCH_COST);
|
||||
format %{ "CWB$cmp $op1,0,$labl\t! compressed ptr" %}
|
||||
ins_encode %{
|
||||
@ -9184,7 +9218,7 @@ instruct cmpI_reg_branchLoopEnd_short(cmpOp cmp, iRegI op1, iRegI op2, label lab
|
||||
predicate(UseCBCond);
|
||||
effect(USE labl, KILL icc);
|
||||
|
||||
size(4);
|
||||
size(4); // Assuming no NOP inserted.
|
||||
ins_cost(BRANCH_COST);
|
||||
format %{ "CWB$cmp $op1,$op2,$labl\t! Loop end" %}
|
||||
ins_encode %{
|
||||
@ -9202,7 +9236,7 @@ instruct cmpI_imm_branchLoopEnd_short(cmpOp cmp, iRegI op1, immI5 op2, label lab
|
||||
predicate(UseCBCond);
|
||||
effect(USE labl, KILL icc);
|
||||
|
||||
size(4);
|
||||
size(4); // Assuming no NOP inserted.
|
||||
ins_cost(BRANCH_COST);
|
||||
format %{ "CWB$cmp $op1,$op2,$labl\t! Loop end" %}
|
||||
ins_encode %{
|
||||
|
@ -153,13 +153,12 @@ address TemplateInterpreterGenerator::generate_slow_signature_handler() {
|
||||
__ delayed()->srl( G4_scratch, 2, G4_scratch );
|
||||
|
||||
__ bind(NextArg);
|
||||
|
||||
}
|
||||
|
||||
__ bind(done);
|
||||
__ ret();
|
||||
__ delayed()->
|
||||
restore(O0, 0, Lscratch); // caller's Lscratch gets the result handler
|
||||
__ delayed()->restore(O0, 0, Lscratch); // caller's Lscratch gets the result handler
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
@ -177,7 +176,6 @@ void TemplateInterpreterGenerator::generate_counter_overflow(Label& Lcontinue) {
|
||||
// returns verified_entry_point or NULL
|
||||
// we ignore it in any case
|
||||
__ ba_short(Lcontinue);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -196,7 +194,6 @@ address TemplateInterpreterGenerator::generate_abstract_entry(void) {
|
||||
// the call_VM checks for exception, so we should never return here.
|
||||
__ should_not_reach_here();
|
||||
return entry;
|
||||
|
||||
}
|
||||
|
||||
void TemplateInterpreterGenerator::save_native_result(void) {
|
||||
@ -474,7 +471,6 @@ void TemplateInterpreterGenerator::generate_counter_incr(Label* overflow, Label*
|
||||
__ delayed()->nop();
|
||||
__ bind(done);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Allocate monitor and lock method (asm interpreter)
|
||||
@ -590,7 +586,7 @@ void TemplateInterpreterGenerator::generate_stack_overflow_check(Register Rframe
|
||||
// pop parameters from the callers stack by adjusting Lesp
|
||||
// set O0 to Lesp
|
||||
// compute X = (max_locals - num_parameters)
|
||||
// bump SP up by X to accomadate the extra locals
|
||||
// bump SP up by X to accommodate the extra locals
|
||||
// compute X = max_expression_stack
|
||||
// + vm_local_words
|
||||
// + 16 words of register save area
|
||||
@ -688,7 +684,7 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) {
|
||||
// 1) Increase caller's SP by for the extra local space needed:
|
||||
// (check for overflow)
|
||||
// Efficient implementation of xload/xstore bytecodes requires
|
||||
// that arguments and non-argument locals are in a contigously
|
||||
// that arguments and non-argument locals are in a contiguously
|
||||
// addressable memory block => non-argument locals must be
|
||||
// allocated in the caller's frame.
|
||||
//
|
||||
@ -782,7 +778,7 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) {
|
||||
__ sub(Gframe_size, Glocals_size, Gframe_size);
|
||||
|
||||
//
|
||||
// bump SP to accomodate the extra locals
|
||||
// bump SP to accommodate the extra locals
|
||||
//
|
||||
__ sub(SP, Glocals_size, SP);
|
||||
}
|
||||
@ -810,9 +806,9 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) {
|
||||
Register mirror = LcpoolCache;
|
||||
__ load_mirror(mirror, Lmethod);
|
||||
__ st_ptr(mirror, FP, (frame::interpreter_frame_mirror_offset * wordSize) + STACK_BIAS);
|
||||
__ get_constant_pool_cache( LcpoolCache ); // set LcpoolCache
|
||||
__ get_constant_pool_cache(LcpoolCache); // set LcpoolCache
|
||||
__ sub(FP, rounded_vm_local_words * BytesPerWord, Lmonitors ); // set Lmonitors
|
||||
__ add( Lmonitors, STACK_BIAS, Lmonitors ); // Account for 64 bit stack bias
|
||||
__ add(Lmonitors, STACK_BIAS, Lmonitors); // Account for 64 bit stack bias
|
||||
__ sub(Lmonitors, BytesPerWord, Lesp); // set Lesp
|
||||
|
||||
// setup interpreter activation registers
|
||||
@ -984,7 +980,7 @@ address TemplateInterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractI
|
||||
__ ldx( Gargs, 16, buf);
|
||||
__ lduw(Gargs, 24, crc);
|
||||
__ add(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE), buf); // account for the header size
|
||||
__ add(buf ,offset, buf);
|
||||
__ add(buf, offset, buf);
|
||||
}
|
||||
|
||||
// Call the crc32 kernel
|
||||
@ -1057,8 +1053,58 @@ address TemplateInterpreterGenerator::generate_CRC32C_updateBytes_entry(Abstract
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Not supported
|
||||
address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKind kind) {
|
||||
/* Math routines only partially supported.
|
||||
*
|
||||
* Providing support for fma (float/double) only.
|
||||
*/
|
||||
address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKind kind)
|
||||
{
|
||||
if (!InlineIntrinsics) return NULL; // Generate a vanilla entry
|
||||
|
||||
address entry = __ pc();
|
||||
|
||||
switch (kind) {
|
||||
case Interpreter::java_lang_math_fmaF:
|
||||
if (UseFMA) {
|
||||
// float .fma(float a, float b, float c)
|
||||
const FloatRegister ra = F1;
|
||||
const FloatRegister rb = F2;
|
||||
const FloatRegister rc = F3;
|
||||
const FloatRegister rd = F0; // Result.
|
||||
|
||||
__ ldf(FloatRegisterImpl::S, Gargs, 0, rc);
|
||||
__ ldf(FloatRegisterImpl::S, Gargs, 8, rb);
|
||||
__ ldf(FloatRegisterImpl::S, Gargs, 16, ra);
|
||||
|
||||
__ fmadd(FloatRegisterImpl::S, ra, rb, rc, rd);
|
||||
__ retl(); // Result in F0 (rd).
|
||||
__ delayed()->mov(O5_savedSP, SP);
|
||||
|
||||
return entry;
|
||||
}
|
||||
break;
|
||||
case Interpreter::java_lang_math_fmaD:
|
||||
if (UseFMA) {
|
||||
// double .fma(double a, double b, double c)
|
||||
const FloatRegister ra = F2; // D1
|
||||
const FloatRegister rb = F4; // D2
|
||||
const FloatRegister rc = F6; // D3
|
||||
const FloatRegister rd = F0; // D0 Result.
|
||||
|
||||
__ ldf(FloatRegisterImpl::D, Gargs, 0, rc);
|
||||
__ ldf(FloatRegisterImpl::D, Gargs, 16, rb);
|
||||
__ ldf(FloatRegisterImpl::D, Gargs, 32, ra);
|
||||
|
||||
__ fmadd(FloatRegisterImpl::D, ra, rb, rc, rd);
|
||||
__ retl(); // Result in D0 (rd).
|
||||
__ delayed()->mov(O5_savedSP, SP);
|
||||
|
||||
return entry;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1071,7 +1117,7 @@ void TemplateInterpreterGenerator::bang_stack_shadow_pages(bool native_call) {
|
||||
// Doing the banging earlier fails if the caller frame is not an interpreter
|
||||
// frame.
|
||||
// (Also, the exception throwing code expects to unlock any synchronized
|
||||
// method receiever, so do the banging after locking the receiver.)
|
||||
// method receiver, so do the banging after locking the receiver.)
|
||||
|
||||
// Bang each page in the shadow zone. We can't assume it's been done for
|
||||
// an interpreter frame with greater than a page of locals, so each page
|
||||
@ -1112,8 +1158,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
|
||||
// rethink these assertions - they can be simplified and shared (gri 2/25/2000)
|
||||
#ifdef ASSERT
|
||||
__ ld(G5_method, Method::access_flags_offset(), Gtmp1);
|
||||
{
|
||||
Label L;
|
||||
{ Label L;
|
||||
__ btst(JVM_ACC_NATIVE, Gtmp1);
|
||||
__ br(Assembler::notZero, false, Assembler::pt, L);
|
||||
__ delayed()->nop();
|
||||
@ -1362,7 +1407,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
|
||||
// didn't see any synchronization is progress, and escapes.
|
||||
__ set(_thread_in_native_trans, G3_scratch);
|
||||
__ st(G3_scratch, thread_state);
|
||||
if(os::is_MP()) {
|
||||
if (os::is_MP()) {
|
||||
if (UseMembar) {
|
||||
// Force this write out before the read below
|
||||
__ membar(Assembler::StoreLoad);
|
||||
@ -1425,8 +1470,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
|
||||
// If we have an oop result store it where it will be safe for any further gc
|
||||
// until we return now that we've released the handle it might be protected by
|
||||
|
||||
{
|
||||
Label no_oop, store_result;
|
||||
{ Label no_oop, store_result;
|
||||
|
||||
__ set((intptr_t)AbstractInterpreter::result_handler(T_OBJECT), G3_scratch);
|
||||
__ cmp_and_brx_short(G3_scratch, Lscratch, Assembler::notEqual, Assembler::pt, no_oop);
|
||||
@ -1484,8 +1528,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
|
||||
|
||||
// dispose of return address and remove activation
|
||||
#ifdef ASSERT
|
||||
{
|
||||
Label ok;
|
||||
{ Label ok;
|
||||
__ cmp_and_brx_short(I5_savedSP, FP, Assembler::greaterEqualUnsigned, Assembler::pt, ok);
|
||||
__ stop("bad I5_savedSP value");
|
||||
__ should_not_reach_here();
|
||||
@ -1495,15 +1538,12 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
|
||||
__ jmp(Lscratch, 0);
|
||||
__ delayed()->nop();
|
||||
|
||||
|
||||
if (inc_counter) {
|
||||
// handle invocation counter overflow
|
||||
__ bind(invocation_counter_overflow);
|
||||
generate_counter_overflow(Lcontinue);
|
||||
}
|
||||
|
||||
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
@ -1533,8 +1573,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) {
|
||||
// rethink these assertions - they can be simplified and shared (gri 2/25/2000)
|
||||
#ifdef ASSERT
|
||||
__ ld(G5_method, Method::access_flags_offset(), Gtmp1);
|
||||
{
|
||||
Label L;
|
||||
{ Label L;
|
||||
__ btst(JVM_ACC_NATIVE, Gtmp1);
|
||||
__ br(Assembler::zero, false, Assembler::pt, L);
|
||||
__ delayed()->nop();
|
||||
@ -1666,7 +1705,6 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) {
|
||||
generate_counter_overflow(Lcontinue);
|
||||
}
|
||||
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
@ -1786,8 +1824,7 @@ void TemplateInterpreterGenerator::generate_throw_exception() {
|
||||
}
|
||||
|
||||
#if INCLUDE_JVMTI
|
||||
{
|
||||
Label L_done;
|
||||
{ Label L_done;
|
||||
|
||||
__ ldub(Address(Lbcp, 0), G1_scratch); // Load current bytecode
|
||||
__ cmp_and_br_short(G1_scratch, Bytecodes::_invokestatic, Assembler::notEqual, Assembler::pn, L_done);
|
||||
@ -1827,7 +1864,7 @@ void TemplateInterpreterGenerator::generate_throw_exception() {
|
||||
__ get_vm_result(Oexception);
|
||||
__ verify_oop(Oexception);
|
||||
|
||||
const int return_reg_adjustment = frame::pc_return_offset;
|
||||
const int return_reg_adjustment = frame::pc_return_offset;
|
||||
Address issuing_pc_addr(I7, return_reg_adjustment);
|
||||
|
||||
// We are done with this activation frame; find out where to go next.
|
||||
|
@ -71,28 +71,43 @@
|
||||
declare_c2_constant(R_G5_num) \
|
||||
declare_c2_constant(R_G6_num) \
|
||||
declare_c2_constant(R_G7_num) \
|
||||
declare_constant(VM_Version::vis1_instructions_m) \
|
||||
declare_constant(VM_Version::vis2_instructions_m) \
|
||||
declare_constant(VM_Version::vis3_instructions_m) \
|
||||
declare_constant(VM_Version::cbcond_instructions_m) \
|
||||
declare_constant(VM_Version::v8_instructions_m) \
|
||||
declare_constant(VM_Version::hardware_mul32_m) \
|
||||
declare_constant(VM_Version::hardware_div32_m) \
|
||||
declare_constant(VM_Version::hardware_fsmuld_m) \
|
||||
declare_constant(VM_Version::hardware_popc_m) \
|
||||
declare_constant(VM_Version::v9_instructions_m) \
|
||||
declare_constant(VM_Version::sun4v_m) \
|
||||
declare_constant(VM_Version::blk_init_instructions_m) \
|
||||
declare_constant(VM_Version::fmaf_instructions_m) \
|
||||
declare_constant(VM_Version::sparc64_family_m) \
|
||||
declare_constant(VM_Version::M_family_m) \
|
||||
declare_constant(VM_Version::T_family_m) \
|
||||
declare_constant(VM_Version::T1_model_m) \
|
||||
declare_constant(VM_Version::sparc5_instructions_m) \
|
||||
declare_constant(VM_Version::aes_instructions_m) \
|
||||
declare_constant(VM_Version::sha1_instruction_m) \
|
||||
declare_constant(VM_Version::sha256_instruction_m) \
|
||||
declare_constant(VM_Version::sha512_instruction_m)
|
||||
declare_constant(VM_Version::ISA_V9) \
|
||||
declare_constant(VM_Version::ISA_POPC) \
|
||||
declare_constant(VM_Version::ISA_VIS1) \
|
||||
declare_constant(VM_Version::ISA_VIS2) \
|
||||
declare_constant(VM_Version::ISA_BLK_INIT) \
|
||||
declare_constant(VM_Version::ISA_FMAF) \
|
||||
declare_constant(VM_Version::ISA_VIS3) \
|
||||
declare_constant(VM_Version::ISA_HPC) \
|
||||
declare_constant(VM_Version::ISA_IMA) \
|
||||
declare_constant(VM_Version::ISA_AES) \
|
||||
declare_constant(VM_Version::ISA_DES) \
|
||||
declare_constant(VM_Version::ISA_KASUMI) \
|
||||
declare_constant(VM_Version::ISA_CAMELLIA) \
|
||||
declare_constant(VM_Version::ISA_MD5) \
|
||||
declare_constant(VM_Version::ISA_SHA1) \
|
||||
declare_constant(VM_Version::ISA_SHA256) \
|
||||
declare_constant(VM_Version::ISA_SHA512) \
|
||||
declare_constant(VM_Version::ISA_MPMUL) \
|
||||
declare_constant(VM_Version::ISA_MONT) \
|
||||
declare_constant(VM_Version::ISA_PAUSE) \
|
||||
declare_constant(VM_Version::ISA_CBCOND) \
|
||||
declare_constant(VM_Version::ISA_CRC32C) \
|
||||
declare_constant(VM_Version::ISA_VIS3B) \
|
||||
declare_constant(VM_Version::ISA_ADI) \
|
||||
declare_constant(VM_Version::ISA_SPARC5) \
|
||||
declare_constant(VM_Version::ISA_MWAIT) \
|
||||
declare_constant(VM_Version::ISA_XMPMUL) \
|
||||
declare_constant(VM_Version::ISA_XMONT) \
|
||||
declare_constant(VM_Version::ISA_PAUSE_NSEC) \
|
||||
declare_constant(VM_Version::ISA_VAMASK) \
|
||||
declare_constant(VM_Version::CPU_FAST_IDIV) \
|
||||
declare_constant(VM_Version::CPU_FAST_RDPC) \
|
||||
declare_constant(VM_Version::CPU_FAST_BIS) \
|
||||
declare_constant(VM_Version::CPU_FAST_LD) \
|
||||
declare_constant(VM_Version::CPU_FAST_CMOVE) \
|
||||
declare_constant(VM_Version::CPU_FAST_IND_BR) \
|
||||
declare_constant(VM_Version::CPU_BLK_ZEROING)
|
||||
|
||||
#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
|
||||
|
||||
|
@ -32,124 +32,123 @@
|
||||
#include "runtime/stubCodeGenerator.hpp"
|
||||
#include "vm_version_sparc.hpp"
|
||||
|
||||
unsigned int VM_Version::_L2_data_cache_line_size = 0;
|
||||
#include <sys/mman.h>
|
||||
|
||||
uint VM_Version::_L2_data_cache_line_size = 0;
|
||||
|
||||
void VM_Version::initialize() {
|
||||
assert(_features != 0, "System pre-initialization is not complete.");
|
||||
guarantee(VM_Version::has_v9(), "only SPARC v9 is supported");
|
||||
|
||||
if (FLAG_IS_DEFAULT(PrefetchCopyIntervalInBytes)) {
|
||||
FLAG_SET_DEFAULT(PrefetchCopyIntervalInBytes, prefetch_copy_interval_in_bytes());
|
||||
}
|
||||
if (FLAG_IS_DEFAULT(PrefetchScanIntervalInBytes)) {
|
||||
FLAG_SET_DEFAULT(PrefetchScanIntervalInBytes, prefetch_scan_interval_in_bytes());
|
||||
}
|
||||
if (FLAG_IS_DEFAULT(PrefetchFieldsAhead)) {
|
||||
FLAG_SET_DEFAULT(PrefetchFieldsAhead, prefetch_fields_ahead());
|
||||
}
|
||||
PrefetchCopyIntervalInBytes = prefetch_copy_interval_in_bytes();
|
||||
PrefetchScanIntervalInBytes = prefetch_scan_interval_in_bytes();
|
||||
PrefetchFieldsAhead = prefetch_fields_ahead();
|
||||
|
||||
// Allocation prefetch settings
|
||||
|
||||
AllocatePrefetchDistance = allocate_prefetch_distance();
|
||||
AllocatePrefetchStyle = allocate_prefetch_style();
|
||||
|
||||
intx cache_line_size = prefetch_data_size();
|
||||
if (FLAG_IS_DEFAULT(AllocatePrefetchStepSize) &&
|
||||
(cache_line_size > AllocatePrefetchStepSize)) {
|
||||
FLAG_SET_DEFAULT(AllocatePrefetchStepSize, cache_line_size);
|
||||
|
||||
if (FLAG_IS_DEFAULT(AllocatePrefetchStepSize)) {
|
||||
AllocatePrefetchStepSize = MAX2(AllocatePrefetchStepSize, cache_line_size);
|
||||
}
|
||||
|
||||
if (FLAG_IS_DEFAULT(AllocatePrefetchDistance)) {
|
||||
FLAG_SET_DEFAULT(AllocatePrefetchDistance, 512);
|
||||
}
|
||||
|
||||
if ((AllocatePrefetchDistance == 0) && (AllocatePrefetchStyle != 0)) {
|
||||
assert(!FLAG_IS_DEFAULT(AllocatePrefetchDistance), "default value should not be 0");
|
||||
if (!FLAG_IS_DEFAULT(AllocatePrefetchStyle)) {
|
||||
warning("AllocatePrefetchDistance is set to 0 which disable prefetching. Ignoring AllocatePrefetchStyle flag.");
|
||||
}
|
||||
FLAG_SET_DEFAULT(AllocatePrefetchStyle, 0);
|
||||
}
|
||||
|
||||
if ((AllocatePrefetchInstr == 1) && (!has_blk_init() || cache_line_size <= 0)) {
|
||||
if (!FLAG_IS_DEFAULT(AllocatePrefetchInstr)) {
|
||||
if (AllocatePrefetchInstr == 1) {
|
||||
if (!has_blk_init()) {
|
||||
warning("BIS instructions required for AllocatePrefetchInstr 1 unavailable");
|
||||
FLAG_SET_DEFAULT(AllocatePrefetchInstr, 0);
|
||||
}
|
||||
if (cache_line_size <= 0) {
|
||||
warning("Cache-line size must be known for AllocatePrefetchInstr 1 to work");
|
||||
FLAG_SET_DEFAULT(AllocatePrefetchInstr, 0);
|
||||
}
|
||||
FLAG_SET_DEFAULT(AllocatePrefetchInstr, 0);
|
||||
}
|
||||
|
||||
UseSSE = 0; // Only on x86 and x64
|
||||
UseSSE = false; // Only used on x86 and x64.
|
||||
|
||||
_supports_cx8 = has_v9();
|
||||
_supports_atomic_getset4 = true; // swap instruction
|
||||
_supports_cx8 = true; // All SPARC V9 implementations.
|
||||
_supports_atomic_getset4 = true; // Using the 'swap' instruction.
|
||||
|
||||
if (has_fast_ind_br() && FLAG_IS_DEFAULT(UseInlineCaches)) {
|
||||
// Indirect and direct branches are cost equivalent.
|
||||
FLAG_SET_DEFAULT(UseInlineCaches, false);
|
||||
}
|
||||
// Align loops on the proper instruction boundary to fill the instruction
|
||||
// fetch buffer.
|
||||
if (FLAG_IS_DEFAULT(OptoLoopAlignment)) {
|
||||
FLAG_SET_DEFAULT(OptoLoopAlignment, VM_Version::insn_fetch_alignment);
|
||||
}
|
||||
|
||||
// 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.
|
||||
Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes);
|
||||
Universe::set_narrow_klass_shift(LogKlassAlignmentInBytes);
|
||||
|
||||
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)) {
|
||||
FLAG_SET_DEFAULT(OptoLoopAlignment, 4);
|
||||
}
|
||||
// 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.
|
||||
Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes);
|
||||
Universe::set_narrow_klass_shift(LogKlassAlignmentInBytes);
|
||||
#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 (FLAG_IS_DEFAULT(InteriorEntryAlignment)) {
|
||||
FLAG_SET_DEFAULT(InteriorEntryAlignment, 4);
|
||||
}
|
||||
if (is_niagara_plus()) {
|
||||
if (has_blk_init() && (cache_line_size > 0) && UseTLAB &&
|
||||
FLAG_IS_DEFAULT(AllocatePrefetchInstr)) {
|
||||
if (!has_sparc5_instr()) {
|
||||
// Use BIS instruction for TLAB allocation prefetch
|
||||
// on Niagara plus processors other than those based on CoreS4
|
||||
FLAG_SET_DEFAULT(AllocatePrefetchInstr, 1);
|
||||
} else {
|
||||
// On CoreS4 processors use prefetch instruction
|
||||
// to avoid partial RAW issue, also use prefetch style 3
|
||||
FLAG_SET_DEFAULT(AllocatePrefetchInstr, 0);
|
||||
if (FLAG_IS_DEFAULT(AllocatePrefetchStyle)) {
|
||||
FLAG_SET_DEFAULT(AllocatePrefetchStyle, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (FLAG_IS_DEFAULT(AllocatePrefetchDistance)) {
|
||||
if (AllocatePrefetchInstr == 0) {
|
||||
// Use different prefetch distance without BIS
|
||||
FLAG_SET_DEFAULT(AllocatePrefetchDistance, 256);
|
||||
} else {
|
||||
// Use smaller prefetch distance with BIS
|
||||
FLAG_SET_DEFAULT(AllocatePrefetchDistance, 64);
|
||||
}
|
||||
}
|
||||
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)) {
|
||||
FLAG_SET_ERGO(intx, AllocatePrefetchLines, AllocatePrefetchLines*2);
|
||||
}
|
||||
if (FLAG_IS_DEFAULT(AllocateInstancePrefetchLines)) {
|
||||
FLAG_SET_ERGO(intx, AllocateInstancePrefetchLines, AllocateInstancePrefetchLines*2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((AllocatePrefetchInstr == 1) && (AllocatePrefetchStyle != 3)) {
|
||||
if (!FLAG_IS_DEFAULT(AllocatePrefetchStyle)) {
|
||||
warning("AllocatePrefetchStyle set to 3 because BIS instructions require aligned memory addresses");
|
||||
}
|
||||
FLAG_SET_DEFAULT(AllocatePrefetchStyle, 3);
|
||||
}
|
||||
#endif /* COMPILER2 */
|
||||
if (has_fast_ind_br() && FLAG_IS_DEFAULT(UseJumpTables)) {
|
||||
// Indirect and direct branches are cost equivalent.
|
||||
FLAG_SET_DEFAULT(UseJumpTables, true);
|
||||
}
|
||||
// Entry and loop tops are aligned to fill the instruction fetch buffer.
|
||||
if (FLAG_IS_DEFAULT(InteriorEntryAlignment)) {
|
||||
FLAG_SET_DEFAULT(InteriorEntryAlignment, VM_Version::insn_fetch_alignment);
|
||||
}
|
||||
if (UseTLAB && cache_line_size > 0 &&
|
||||
FLAG_IS_DEFAULT(AllocatePrefetchInstr)) {
|
||||
if (has_fast_bis()) {
|
||||
// Use BIS instruction for TLAB allocation prefetch.
|
||||
FLAG_SET_DEFAULT(AllocatePrefetchInstr, 1);
|
||||
}
|
||||
else if (has_sparc5()) {
|
||||
// Use prefetch instruction to avoid partial RAW issue on Core S4 processors,
|
||||
// also use prefetch style 3.
|
||||
FLAG_SET_DEFAULT(AllocatePrefetchInstr, 0);
|
||||
if (FLAG_IS_DEFAULT(AllocatePrefetchStyle)) {
|
||||
FLAG_SET_DEFAULT(AllocatePrefetchStyle, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (AllocatePrefetchInstr == 1) {
|
||||
// Use allocation prefetch style 3 because BIS instructions require
|
||||
// aligned memory addresses.
|
||||
FLAG_SET_DEFAULT(AllocatePrefetchStyle, 3);
|
||||
}
|
||||
if (FLAG_IS_DEFAULT(AllocatePrefetchDistance)) {
|
||||
if (AllocatePrefetchInstr == 0) {
|
||||
// Use different prefetch distance without BIS
|
||||
FLAG_SET_DEFAULT(AllocatePrefetchDistance, 256);
|
||||
} else {
|
||||
// Use smaller prefetch distance with BIS
|
||||
FLAG_SET_DEFAULT(AllocatePrefetchDistance, 64);
|
||||
}
|
||||
}
|
||||
|
||||
// We increase the number of prefetched cache lines, to use just a bit more
|
||||
// aggressive approach, when the L2-cache line size is small (32 bytes), or
|
||||
// when running on newer processor implementations, such as the Core S4.
|
||||
bool inc_prefetch = cache_line_size > 0 && (cache_line_size < 64 || has_sparc5());
|
||||
|
||||
if (inc_prefetch) {
|
||||
// We use a factor two for small cache line sizes (as before) but a slightly
|
||||
// more conservative increase when running on more recent hardware that will
|
||||
// benefit from just a bit more aggressive prefetching.
|
||||
if (FLAG_IS_DEFAULT(AllocatePrefetchLines)) {
|
||||
const int ap_lns = AllocatePrefetchLines;
|
||||
const int ap_inc = cache_line_size < 64 ? ap_lns : (ap_lns + 1) / 2;
|
||||
FLAG_SET_ERGO(intx, AllocatePrefetchLines, ap_lns + ap_inc);
|
||||
}
|
||||
if (FLAG_IS_DEFAULT(AllocateInstancePrefetchLines)) {
|
||||
const int ip_lns = AllocateInstancePrefetchLines;
|
||||
const int ip_inc = cache_line_size < 64 ? ip_lns : (ip_lns + 1) / 2;
|
||||
FLAG_SET_ERGO(intx, AllocateInstancePrefetchLines, ip_lns + ip_inc);
|
||||
}
|
||||
}
|
||||
#endif /* COMPILER2 */
|
||||
|
||||
// Use hardware population count instruction if available.
|
||||
if (has_hardware_popc()) {
|
||||
if (has_popc()) {
|
||||
if (FLAG_IS_DEFAULT(UsePopCountInstruction)) {
|
||||
FLAG_SET_DEFAULT(UsePopCountInstruction, true);
|
||||
}
|
||||
@ -158,7 +157,7 @@ void VM_Version::initialize() {
|
||||
FLAG_SET_DEFAULT(UsePopCountInstruction, false);
|
||||
}
|
||||
|
||||
// T4 and newer Sparc cpus have new compare and branch instruction.
|
||||
// Use compare and branch instructions if available.
|
||||
if (has_cbcond()) {
|
||||
if (FLAG_IS_DEFAULT(UseCBCond)) {
|
||||
FLAG_SET_DEFAULT(UseCBCond, true);
|
||||
@ -169,7 +168,8 @@ void VM_Version::initialize() {
|
||||
}
|
||||
|
||||
assert(BlockZeroingLowLimit > 0, "invalid value");
|
||||
if (has_block_zeroing() && cache_line_size > 0) {
|
||||
|
||||
if (has_blk_zeroing() && cache_line_size > 0) {
|
||||
if (FLAG_IS_DEFAULT(UseBlockZeroing)) {
|
||||
FLAG_SET_DEFAULT(UseBlockZeroing, true);
|
||||
}
|
||||
@ -179,7 +179,8 @@ void VM_Version::initialize() {
|
||||
}
|
||||
|
||||
assert(BlockCopyLowLimit > 0, "invalid value");
|
||||
if (has_block_zeroing() && cache_line_size > 0) { // has_blk_init() && is_T4(): core's local L2 cache
|
||||
|
||||
if (has_blk_zeroing() && cache_line_size > 0) {
|
||||
if (FLAG_IS_DEFAULT(UseBlockCopy)) {
|
||||
FLAG_SET_DEFAULT(UseBlockCopy, true);
|
||||
}
|
||||
@ -189,7 +190,6 @@ void VM_Version::initialize() {
|
||||
}
|
||||
|
||||
#ifdef COMPILER2
|
||||
// T4 and newer Sparc cpus have fast RDPC.
|
||||
if (has_fast_rdpc() && FLAG_IS_DEFAULT(UseRDPCForConstantTableBase)) {
|
||||
FLAG_SET_DEFAULT(UseRDPCForConstantTableBase, true);
|
||||
}
|
||||
@ -206,44 +206,67 @@ void VM_Version::initialize() {
|
||||
assert((OptoLoopAlignment % relocInfo::addr_unit()) == 0, "alignment is not a multiple of NOP size");
|
||||
|
||||
char buf[512];
|
||||
jio_snprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
|
||||
(has_v9() ? ", v9" : (has_v8() ? ", v8" : "")),
|
||||
(has_hardware_popc() ? ", popc" : ""),
|
||||
(has_vis1() ? ", vis1" : ""),
|
||||
(has_vis2() ? ", vis2" : ""),
|
||||
(has_vis3() ? ", vis3" : ""),
|
||||
(has_blk_init() ? ", blk_init" : ""),
|
||||
(has_cbcond() ? ", cbcond" : ""),
|
||||
(has_aes() ? ", aes" : ""),
|
||||
(has_sha1() ? ", sha1" : ""),
|
||||
(has_sha256() ? ", sha256" : ""),
|
||||
(has_sha512() ? ", sha512" : ""),
|
||||
(has_crc32c() ? ", crc32c" : ""),
|
||||
(is_ultra3() ? ", ultra3" : ""),
|
||||
(has_sparc5_instr() ? ", sparc5" : ""),
|
||||
(is_sun4v() ? ", sun4v" : ""),
|
||||
(is_niagara_plus() ? ", niagara_plus" : (is_niagara() ? ", niagara" : "")),
|
||||
(is_sparc64() ? ", sparc64" : ""),
|
||||
(!has_hardware_mul32() ? ", no-mul32" : ""),
|
||||
(!has_hardware_div32() ? ", no-div32" : ""),
|
||||
(!has_hardware_fsmuld() ? ", no-fsmuld" : ""));
|
||||
jio_snprintf(buf, sizeof(buf),
|
||||
"%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
|
||||
(has_v9() ? "v9" : ""),
|
||||
(has_popc() ? ", popc" : ""),
|
||||
(has_vis1() ? ", vis1" : ""),
|
||||
(has_vis2() ? ", vis2" : ""),
|
||||
(has_blk_init() ? ", blk_init" : ""),
|
||||
(has_fmaf() ? ", fmaf" : ""),
|
||||
(has_hpc() ? ", hpc" : ""),
|
||||
(has_ima() ? ", ima" : ""),
|
||||
(has_aes() ? ", aes" : ""),
|
||||
(has_des() ? ", des" : ""),
|
||||
(has_kasumi() ? ", kas" : ""),
|
||||
(has_camellia() ? ", cam" : ""),
|
||||
(has_md5() ? ", md5" : ""),
|
||||
(has_sha1() ? ", sha1" : ""),
|
||||
(has_sha256() ? ", sha256" : ""),
|
||||
(has_sha512() ? ", sha512" : ""),
|
||||
(has_mpmul() ? ", mpmul" : ""),
|
||||
(has_mont() ? ", mont" : ""),
|
||||
(has_pause() ? ", pause" : ""),
|
||||
(has_cbcond() ? ", cbcond" : ""),
|
||||
(has_crc32c() ? ", crc32c" : ""),
|
||||
|
||||
// buf is started with ", " or is empty
|
||||
_features_string = os::strdup(strlen(buf) > 2 ? buf + 2 : buf);
|
||||
(has_athena_plus() ? ", athena_plus" : ""),
|
||||
(has_vis3b() ? ", vis3b" : ""),
|
||||
(has_adi() ? ", adi" : ""),
|
||||
(has_sparc5() ? ", sparc5" : ""),
|
||||
(has_mwait() ? ", mwait" : ""),
|
||||
(has_xmpmul() ? ", xmpmul" : ""),
|
||||
(has_xmont() ? ", xmont" : ""),
|
||||
(has_pause_nsec() ? ", pause_nsec" : ""),
|
||||
(has_vamask() ? ", vamask" : ""),
|
||||
|
||||
// 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 (UseVIS > 3) UseVIS=3;
|
||||
if (UseVIS < 0) UseVIS=0;
|
||||
(has_fast_idiv() ? ", *idiv" : ""),
|
||||
(has_fast_rdpc() ? ", *rdpc" : ""),
|
||||
(has_fast_bis() ? ", *bis" : ""),
|
||||
(has_fast_ld() ? ", *ld" : ""),
|
||||
(has_fast_cmove() ? ", *cmove" : ""),
|
||||
(has_fast_ind_br() ? ", *ind_br" : ""),
|
||||
(has_blk_zeroing() ? ", *blk_zeroing" : ""));
|
||||
|
||||
assert(strlen(buf) >= 2, "must be");
|
||||
|
||||
_features_string = os::strdup(buf);
|
||||
|
||||
log_info(os, cpu)("SPARC features detected: %s", _features_string);
|
||||
|
||||
// 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 (UseVIS > 3) UseVIS = 3;
|
||||
if (UseVIS < 0) UseVIS = 0;
|
||||
if (!has_vis3()) // Drop to 2 if no VIS3 support
|
||||
UseVIS = MIN2((intx)2,UseVIS);
|
||||
UseVIS = MIN2((intx)2, UseVIS);
|
||||
if (!has_vis2()) // Drop to 1 if no VIS2 support
|
||||
UseVIS = MIN2((intx)1,UseVIS);
|
||||
UseVIS = MIN2((intx)1, UseVIS);
|
||||
if (!has_vis1()) // Drop to 0 if no VIS1 support
|
||||
UseVIS = 0;
|
||||
|
||||
// SPARC T4 and above should have support for AES instructions
|
||||
if (has_aes()) {
|
||||
if (FLAG_IS_DEFAULT(UseAES)) {
|
||||
FLAG_SET_DEFAULT(UseAES, true);
|
||||
@ -294,12 +317,16 @@ void VM_Version::initialize() {
|
||||
FLAG_SET_DEFAULT(UseGHASHIntrinsics, false);
|
||||
}
|
||||
|
||||
if (UseFMA) {
|
||||
if (has_fmaf()) {
|
||||
if (FLAG_IS_DEFAULT(UseFMA)) {
|
||||
UseFMA = true;
|
||||
}
|
||||
} else if (UseFMA) {
|
||||
warning("FMA instructions are not available on this CPU");
|
||||
FLAG_SET_DEFAULT(UseFMA, false);
|
||||
}
|
||||
|
||||
// SHA1, SHA256, and SHA512 instructions were added to SPARC T-series at different times
|
||||
// SHA1, SHA256, and SHA512 instructions were added to SPARC at different times
|
||||
if (has_sha1() || has_sha256() || has_sha512()) {
|
||||
if (UseVIS > 0) { // SHA intrinsics use VIS1 instructions
|
||||
if (FLAG_IS_DEFAULT(UseSHA)) {
|
||||
@ -347,7 +374,6 @@ void VM_Version::initialize() {
|
||||
FLAG_SET_DEFAULT(UseSHA, false);
|
||||
}
|
||||
|
||||
// SPARC T4 and above should have support for CRC32C instruction
|
||||
if (has_crc32c()) {
|
||||
if (UseVIS > 2) { // CRC32C intrinsics use VIS3 instructions
|
||||
if (FLAG_IS_DEFAULT(UseCRC32CIntrinsics)) {
|
||||
@ -435,96 +461,42 @@ void VM_Version::initialize() {
|
||||
}
|
||||
|
||||
void VM_Version::print_features() {
|
||||
tty->print_cr("Version:%s", _features);
|
||||
tty->print("ISA features [0x%0" PRIx64 "]:", _features);
|
||||
if (_features_string != NULL) {
|
||||
tty->print(" %s", _features_string);
|
||||
}
|
||||
tty->cr();
|
||||
}
|
||||
|
||||
int VM_Version::determine_features() {
|
||||
if (UseV8InstrsOnly) {
|
||||
log_info(os, cpu)("Version is Forced-V8");
|
||||
return generic_v8_m;
|
||||
void VM_Version::determine_features() {
|
||||
platform_features(); // platform_features() is os_arch specific.
|
||||
|
||||
assert(has_v9(), "must be");
|
||||
|
||||
if (UseNiagaraInstrs) { // Limit code generation to Niagara.
|
||||
_features &= niagara1_msk;
|
||||
}
|
||||
|
||||
int features = platform_features(unknown_m); // platform_features() is os_arch specific
|
||||
|
||||
if (features == unknown_m) {
|
||||
features = generic_v9_m;
|
||||
log_info(os)("Cannot recognize SPARC version. Default to V9");
|
||||
}
|
||||
|
||||
assert(is_T_family(features) == is_niagara(features), "Niagara should be T series");
|
||||
if (UseNiagaraInstrs) { // Force code generation for Niagara
|
||||
if (is_T_family(features)) {
|
||||
// Happy to accomodate...
|
||||
} else {
|
||||
log_info(os, cpu)("Version is Forced-Niagara");
|
||||
features |= T_family_m;
|
||||
}
|
||||
} else {
|
||||
if (is_T_family(features) && !FLAG_IS_DEFAULT(UseNiagaraInstrs)) {
|
||||
log_info(os, cpu)("Version is Forced-Not-Niagara");
|
||||
features &= ~(T_family_m | T1_model_m);
|
||||
} else {
|
||||
// Happy to accomodate...
|
||||
}
|
||||
}
|
||||
|
||||
return features;
|
||||
}
|
||||
|
||||
static uint64_t saved_features = 0;
|
||||
|
||||
void VM_Version::allow_all() {
|
||||
saved_features = _features;
|
||||
_features = all_features_m;
|
||||
_features = full_feature_msk;
|
||||
}
|
||||
|
||||
void VM_Version::revert() {
|
||||
_features = saved_features;
|
||||
}
|
||||
|
||||
/* Determine a suitable number of threads on this particular machine.
|
||||
*
|
||||
* FIXME: Simply checking the processor family is insufficient.
|
||||
*/
|
||||
unsigned int VM_Version::calc_parallel_worker_threads() {
|
||||
unsigned int result;
|
||||
if (is_M_series() || is_S_series()) {
|
||||
// for now, use same gc thread calculation for M-series and S-series as for
|
||||
// niagara-plus. In future, we may want to tweak parameters for
|
||||
// nof_parallel_worker_thread
|
||||
result = nof_parallel_worker_threads(5, 16, 8);
|
||||
} else if (is_niagara_plus()) {
|
||||
result = nof_parallel_worker_threads(5, 16, 8);
|
||||
} else {
|
||||
result = nof_parallel_worker_threads(5, 8, 8);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int VM_Version::parse_features(const char* implementation) {
|
||||
int features = unknown_m;
|
||||
// Convert to UPPER case before compare.
|
||||
char* impl = os::strdup_check_oom(implementation);
|
||||
|
||||
for (int i = 0; impl[i] != 0; i++)
|
||||
impl[i] = (char)toupper((uint)impl[i]);
|
||||
|
||||
if (strstr(impl, "SPARC64") != NULL) {
|
||||
features |= sparc64_family_m;
|
||||
} else if (strstr(impl, "SPARC-M") != NULL) {
|
||||
// M-series SPARC is based on T-series.
|
||||
features |= (M_family_m | T_family_m);
|
||||
} else if (strstr(impl, "SPARC-S") != NULL) {
|
||||
// S-series SPARC is based on T-series.
|
||||
features |= (S_family_m | T_family_m);
|
||||
} else if (strstr(impl, "SPARC-T") != NULL) {
|
||||
features |= T_family_m;
|
||||
if (strstr(impl, "SPARC-T1") != NULL) {
|
||||
features |= T1_model_m;
|
||||
}
|
||||
} else if (strstr(impl, "SUN4V-CPU") != NULL) {
|
||||
// Generic or migration class LDOM
|
||||
features |= T_family_m;
|
||||
} else {
|
||||
log_info(os, cpu)("Failed to parse CPU implementation = '%s'", impl);
|
||||
}
|
||||
os::free((void*)impl);
|
||||
return features;
|
||||
const int num = 5;
|
||||
const int den = is_post_niagara() ? 16 : 8;
|
||||
const int threshold = 8;
|
||||
|
||||
return nof_parallel_worker_threads(num, den, threshold);
|
||||
}
|
||||
|
@ -33,168 +33,296 @@ class VM_Version: public Abstract_VM_Version {
|
||||
friend class JVMCIVMStructs;
|
||||
|
||||
protected:
|
||||
enum Feature_Flag {
|
||||
v8_instructions = 0,
|
||||
hardware_mul32 = 1,
|
||||
hardware_div32 = 2,
|
||||
hardware_fsmuld = 3,
|
||||
hardware_popc = 4,
|
||||
v9_instructions = 5,
|
||||
vis1_instructions = 6,
|
||||
vis2_instructions = 7,
|
||||
sun4v_instructions = 8,
|
||||
blk_init_instructions = 9,
|
||||
fmaf_instructions = 10,
|
||||
vis3_instructions = 11,
|
||||
cbcond_instructions = 12,
|
||||
sparc64_family = 13,
|
||||
M_family = 14,
|
||||
S_family = 15,
|
||||
T_family = 16,
|
||||
T1_model = 17,
|
||||
sparc5_instructions = 18,
|
||||
aes_instructions = 19,
|
||||
sha1_instruction = 20,
|
||||
sha256_instruction = 21,
|
||||
sha512_instruction = 22,
|
||||
crc32c_instruction = 23
|
||||
enum {
|
||||
ISA_V9,
|
||||
ISA_POPC,
|
||||
ISA_VIS1,
|
||||
ISA_VIS2,
|
||||
ISA_BLK_INIT,
|
||||
ISA_FMAF,
|
||||
ISA_VIS3,
|
||||
ISA_HPC,
|
||||
ISA_IMA,
|
||||
ISA_AES,
|
||||
ISA_DES,
|
||||
ISA_KASUMI,
|
||||
ISA_CAMELLIA,
|
||||
ISA_MD5,
|
||||
ISA_SHA1,
|
||||
ISA_SHA256,
|
||||
ISA_SHA512,
|
||||
ISA_MPMUL,
|
||||
ISA_MONT,
|
||||
ISA_PAUSE,
|
||||
ISA_CBCOND,
|
||||
ISA_CRC32C,
|
||||
|
||||
ISA_FJATHPLUS,
|
||||
ISA_VIS3B,
|
||||
ISA_ADI,
|
||||
ISA_SPARC5,
|
||||
ISA_MWAIT,
|
||||
ISA_XMPMUL,
|
||||
ISA_XMONT,
|
||||
ISA_PAUSE_NSEC,
|
||||
ISA_VAMASK,
|
||||
|
||||
// Synthesised properties:
|
||||
|
||||
CPU_FAST_IDIV,
|
||||
CPU_FAST_RDPC,
|
||||
CPU_FAST_BIS,
|
||||
CPU_FAST_LD,
|
||||
CPU_FAST_CMOVE,
|
||||
CPU_FAST_IND_BR,
|
||||
CPU_BLK_ZEROING
|
||||
};
|
||||
|
||||
enum Feature_Flag_Set {
|
||||
unknown_m = 0,
|
||||
all_features_m = -1,
|
||||
private:
|
||||
enum { ISA_last_feature = ISA_VAMASK,
|
||||
CPU_last_feature = CPU_BLK_ZEROING };
|
||||
|
||||
v8_instructions_m = 1 << v8_instructions,
|
||||
hardware_mul32_m = 1 << hardware_mul32,
|
||||
hardware_div32_m = 1 << hardware_div32,
|
||||
hardware_fsmuld_m = 1 << hardware_fsmuld,
|
||||
hardware_popc_m = 1 << hardware_popc,
|
||||
v9_instructions_m = 1 << v9_instructions,
|
||||
vis1_instructions_m = 1 << vis1_instructions,
|
||||
vis2_instructions_m = 1 << vis2_instructions,
|
||||
sun4v_m = 1 << sun4v_instructions,
|
||||
blk_init_instructions_m = 1 << blk_init_instructions,
|
||||
fmaf_instructions_m = 1 << fmaf_instructions,
|
||||
vis3_instructions_m = 1 << vis3_instructions,
|
||||
cbcond_instructions_m = 1 << cbcond_instructions,
|
||||
sparc64_family_m = 1 << sparc64_family,
|
||||
M_family_m = 1 << M_family,
|
||||
S_family_m = 1 << S_family,
|
||||
T_family_m = 1 << T_family,
|
||||
T1_model_m = 1 << T1_model,
|
||||
sparc5_instructions_m = 1 << sparc5_instructions,
|
||||
aes_instructions_m = 1 << aes_instructions,
|
||||
sha1_instruction_m = 1 << sha1_instruction,
|
||||
sha256_instruction_m = 1 << sha256_instruction,
|
||||
sha512_instruction_m = 1 << sha512_instruction,
|
||||
crc32c_instruction_m = 1 << crc32c_instruction,
|
||||
enum {
|
||||
ISA_unknown_msk = 0,
|
||||
|
||||
generic_v8_m = v8_instructions_m | hardware_mul32_m | hardware_div32_m | hardware_fsmuld_m,
|
||||
generic_v9_m = generic_v8_m | v9_instructions_m,
|
||||
ultra3_m = generic_v9_m | vis1_instructions_m | vis2_instructions_m,
|
||||
ISA_v9_msk = UINT64_C(1) << ISA_V9,
|
||||
|
||||
// Temporary until we have something more accurate
|
||||
niagara1_unique_m = sun4v_m,
|
||||
niagara1_m = generic_v9_m | niagara1_unique_m
|
||||
ISA_popc_msk = UINT64_C(1) << ISA_POPC,
|
||||
ISA_vis1_msk = UINT64_C(1) << ISA_VIS1,
|
||||
ISA_vis2_msk = UINT64_C(1) << ISA_VIS2,
|
||||
ISA_blk_init_msk = UINT64_C(1) << ISA_BLK_INIT,
|
||||
ISA_fmaf_msk = UINT64_C(1) << ISA_FMAF,
|
||||
ISA_vis3_msk = UINT64_C(1) << ISA_VIS3,
|
||||
ISA_hpc_msk = UINT64_C(1) << ISA_HPC,
|
||||
ISA_ima_msk = UINT64_C(1) << ISA_IMA,
|
||||
ISA_aes_msk = UINT64_C(1) << ISA_AES,
|
||||
ISA_des_msk = UINT64_C(1) << ISA_DES,
|
||||
ISA_kasumi_msk = UINT64_C(1) << ISA_KASUMI,
|
||||
ISA_camellia_msk = UINT64_C(1) << ISA_CAMELLIA,
|
||||
ISA_md5_msk = UINT64_C(1) << ISA_MD5,
|
||||
ISA_sha1_msk = UINT64_C(1) << ISA_SHA1,
|
||||
ISA_sha256_msk = UINT64_C(1) << ISA_SHA256,
|
||||
ISA_sha512_msk = UINT64_C(1) << ISA_SHA512,
|
||||
ISA_mpmul_msk = UINT64_C(1) << ISA_MPMUL,
|
||||
ISA_mont_msk = UINT64_C(1) << ISA_MONT,
|
||||
ISA_pause_msk = UINT64_C(1) << ISA_PAUSE,
|
||||
ISA_cbcond_msk = UINT64_C(1) << ISA_CBCOND,
|
||||
ISA_crc32c_msk = UINT64_C(1) << ISA_CRC32C,
|
||||
|
||||
ISA_fjathplus_msk = UINT64_C(1) << ISA_FJATHPLUS,
|
||||
ISA_vis3b_msk = UINT64_C(1) << ISA_VIS3B,
|
||||
ISA_adi_msk = UINT64_C(1) << ISA_ADI,
|
||||
ISA_sparc5_msk = UINT64_C(1) << ISA_SPARC5,
|
||||
ISA_mwait_msk = UINT64_C(1) << ISA_MWAIT,
|
||||
ISA_xmpmul_msk = UINT64_C(1) << ISA_XMPMUL,
|
||||
ISA_xmont_msk = UINT64_C(1) << ISA_XMONT,
|
||||
ISA_pause_nsec_msk = UINT64_C(1) << ISA_PAUSE_NSEC,
|
||||
ISA_vamask_msk = UINT64_C(1) << ISA_VAMASK,
|
||||
|
||||
CPU_fast_idiv_msk = UINT64_C(1) << CPU_FAST_IDIV,
|
||||
CPU_fast_rdpc_msk = UINT64_C(1) << CPU_FAST_RDPC,
|
||||
CPU_fast_bis_msk = UINT64_C(1) << CPU_FAST_BIS,
|
||||
CPU_fast_ld_msk = UINT64_C(1) << CPU_FAST_LD,
|
||||
CPU_fast_cmove_msk = UINT64_C(1) << CPU_FAST_CMOVE,
|
||||
CPU_fast_ind_br_msk = UINT64_C(1) << CPU_FAST_IND_BR,
|
||||
CPU_blk_zeroing_msk = UINT64_C(1) << CPU_BLK_ZEROING,
|
||||
|
||||
last_feature_msk = CPU_blk_zeroing_msk,
|
||||
full_feature_msk = (last_feature_msk << 1) - 1
|
||||
};
|
||||
|
||||
static unsigned int _L2_data_cache_line_size;
|
||||
static unsigned int L2_data_cache_line_size() { return _L2_data_cache_line_size; }
|
||||
/* The following, previously supported, SPARC implementations are no longer
|
||||
* supported.
|
||||
*
|
||||
* UltraSPARC I/II:
|
||||
* SPARC-V9, VIS
|
||||
* UltraSPARC III/+: (Cheetah/+)
|
||||
* SPARC-V9, VIS
|
||||
* UltraSPARC IV: (Jaguar)
|
||||
* SPARC-V9, VIS
|
||||
* UltraSPARC IV+: (Panther)
|
||||
* SPARC-V9, VIS, POPC
|
||||
*
|
||||
* The currently supported SPARC implementations are listed below (including
|
||||
* generic V9 support).
|
||||
*
|
||||
* UltraSPARC T1: (Niagara)
|
||||
* SPARC-V9, VIS, ASI_BIS (Crypto/hash in SPU)
|
||||
* UltraSPARC T2: (Niagara-2)
|
||||
* SPARC-V9, VIS, ASI_BIS, POPC (Crypto/hash in SPU)
|
||||
* UltraSPARC T2+: (Victoria Falls, etc.)
|
||||
* SPARC-V9, VIS, VIS2, ASI_BIS, POPC (Crypto/hash in SPU)
|
||||
*
|
||||
* UltraSPARC T3: (Rainbow Falls/S2)
|
||||
* SPARC-V9, VIS, VIS2, ASI_BIS, POPC (Crypto/hash in SPU)
|
||||
*
|
||||
* Oracle SPARC T4/T5/M5: (Core S3)
|
||||
* SPARC-V9, VIS, VIS2, VIS3, ASI_BIS, HPC, POPC, FMAF, IMA, PAUSE, CBCOND,
|
||||
* AES, DES, Kasumi, Camellia, MD5, SHA1, SHA256, SHA512, CRC32C, MONT, MPMUL
|
||||
*
|
||||
* Oracle SPARC M7: (Core S4)
|
||||
* SPARC-V9, VIS, VIS2, VIS3, ASI_BIS, HPC, POPC, FMAF, IMA, PAUSE, CBCOND,
|
||||
* AES, DES, Camellia, MD5, SHA1, SHA256, SHA512, CRC32C, MONT, MPMUL, VIS3b,
|
||||
* ADI, SPARC5, MWAIT, XMPMUL, XMONT, PAUSE_NSEC, VAMASK
|
||||
*
|
||||
*/
|
||||
enum {
|
||||
niagara1_msk = ISA_v9_msk | ISA_vis1_msk | ISA_blk_init_msk,
|
||||
niagara2_msk = niagara1_msk | ISA_popc_msk,
|
||||
|
||||
core_S2_msk = niagara2_msk | ISA_vis2_msk,
|
||||
|
||||
core_S3_msk = core_S2_msk | ISA_fmaf_msk | ISA_vis3_msk | ISA_hpc_msk |
|
||||
ISA_ima_msk | ISA_aes_msk | ISA_des_msk | ISA_kasumi_msk |
|
||||
ISA_camellia_msk | ISA_md5_msk | ISA_sha1_msk | ISA_sha256_msk |
|
||||
ISA_sha512_msk | ISA_mpmul_msk | ISA_mont_msk | ISA_pause_msk |
|
||||
ISA_cbcond_msk | ISA_crc32c_msk,
|
||||
|
||||
core_S4_msk = core_S3_msk - ISA_kasumi_msk |
|
||||
ISA_vis3b_msk | ISA_adi_msk | ISA_sparc5_msk | ISA_mwait_msk |
|
||||
ISA_xmpmul_msk | ISA_xmont_msk | ISA_pause_nsec_msk | ISA_vamask_msk,
|
||||
|
||||
ultra_sparc_t1_msk = niagara1_msk,
|
||||
ultra_sparc_t2_msk = niagara2_msk,
|
||||
ultra_sparc_t3_msk = core_S2_msk,
|
||||
ultra_sparc_m5_msk = core_S3_msk, // NOTE: First out-of-order pipeline.
|
||||
ultra_sparc_m7_msk = core_S4_msk
|
||||
};
|
||||
|
||||
static uint _L2_data_cache_line_size;
|
||||
static uint L2_data_cache_line_size() { return _L2_data_cache_line_size; }
|
||||
|
||||
static void determine_features();
|
||||
static void platform_features();
|
||||
static void print_features();
|
||||
static int determine_features();
|
||||
static int platform_features(int features);
|
||||
|
||||
// Returns true if the platform is in the niagara line (T series)
|
||||
static bool is_M_family(int features) { return (features & M_family_m) != 0; }
|
||||
static bool is_S_family(int features) { return (features & S_family_m) != 0; }
|
||||
static bool is_T_family(int features) { return (features & T_family_m) != 0; }
|
||||
static bool is_niagara() { return is_T_family(_features); }
|
||||
#ifdef ASSERT
|
||||
static bool is_niagara(int features) {
|
||||
// 'sun4v_m' may be defined on both Sun/Oracle Sparc CPUs as well as
|
||||
// on Fujitsu Sparc64 CPUs, but only Sun/Oracle Sparcs can be 'niagaras'.
|
||||
return (features & sun4v_m) != 0 && (features & sparc64_family_m) == 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Returns true if it is niagara1 (T1).
|
||||
static bool is_T1_model(int features) { return is_T_family(features) && ((features & T1_model_m) != 0); }
|
||||
|
||||
static int maximum_niagara1_processor_count() { return 32; }
|
||||
static int parse_features(const char* implementation);
|
||||
public:
|
||||
// Initialization
|
||||
enum {
|
||||
// Adopt a conservative behaviour (modelling single-insn-fetch-n-issue) for
|
||||
// Niagara (and SPARC64). While there are at least two entries/slots in the
|
||||
// instruction fetch buffer on any Niagara core (and as many as eight on a
|
||||
// SPARC64), the performance improvement from keeping hot branch targets on
|
||||
// optimally aligned addresses is such a small one (if any) that we choose
|
||||
// not to use the extra code space required.
|
||||
|
||||
insn_fetch_alignment = 4 // Byte alignment in L1 insn. cache.
|
||||
};
|
||||
|
||||
static void initialize();
|
||||
|
||||
static void init_before_ergo() { _features = determine_features(); }
|
||||
static void init_before_ergo() { determine_features(); }
|
||||
|
||||
// Instruction support
|
||||
static bool has_v8() { return (_features & v8_instructions_m) != 0; }
|
||||
static bool has_v9() { return (_features & v9_instructions_m) != 0; }
|
||||
static bool has_hardware_mul32() { return (_features & hardware_mul32_m) != 0; }
|
||||
static bool has_hardware_div32() { return (_features & hardware_div32_m) != 0; }
|
||||
static bool has_hardware_fsmuld() { return (_features & hardware_fsmuld_m) != 0; }
|
||||
static bool has_hardware_popc() { return (_features & hardware_popc_m) != 0; }
|
||||
static bool has_vis1() { return (_features & vis1_instructions_m) != 0; }
|
||||
static bool has_vis2() { return (_features & vis2_instructions_m) != 0; }
|
||||
static bool has_vis3() { return (_features & vis3_instructions_m) != 0; }
|
||||
static bool has_blk_init() { return (_features & blk_init_instructions_m) != 0; }
|
||||
static bool has_cbcond() { return (_features & cbcond_instructions_m) != 0; }
|
||||
static bool has_sparc5_instr() { return (_features & sparc5_instructions_m) != 0; }
|
||||
static bool has_aes() { return (_features & aes_instructions_m) != 0; }
|
||||
static bool has_sha1() { return (_features & sha1_instruction_m) != 0; }
|
||||
static bool has_sha256() { return (_features & sha256_instruction_m) != 0; }
|
||||
static bool has_sha512() { return (_features & sha512_instruction_m) != 0; }
|
||||
static bool has_crc32c() { return (_features & crc32c_instruction_m) != 0; }
|
||||
// Instruction feature support:
|
||||
|
||||
static bool supports_compare_and_exchange()
|
||||
{ return has_v9(); }
|
||||
static bool has_v9() { return (_features & ISA_v9_msk) != 0; }
|
||||
static bool has_popc() { return (_features & ISA_popc_msk) != 0; }
|
||||
static bool has_vis1() { return (_features & ISA_vis1_msk) != 0; }
|
||||
static bool has_vis2() { return (_features & ISA_vis2_msk) != 0; }
|
||||
static bool has_blk_init() { return (_features & ISA_blk_init_msk) != 0; }
|
||||
static bool has_fmaf() { return (_features & ISA_fmaf_msk) != 0; }
|
||||
static bool has_vis3() { return (_features & ISA_vis3_msk) != 0; }
|
||||
static bool has_hpc() { return (_features & ISA_hpc_msk) != 0; }
|
||||
static bool has_ima() { return (_features & ISA_ima_msk) != 0; }
|
||||
static bool has_aes() { return (_features & ISA_aes_msk) != 0; }
|
||||
static bool has_des() { return (_features & ISA_des_msk) != 0; }
|
||||
static bool has_kasumi() { return (_features & ISA_kasumi_msk) != 0; }
|
||||
static bool has_camellia() { return (_features & ISA_camellia_msk) != 0; }
|
||||
static bool has_md5() { return (_features & ISA_md5_msk) != 0; }
|
||||
static bool has_sha1() { return (_features & ISA_sha1_msk) != 0; }
|
||||
static bool has_sha256() { return (_features & ISA_sha256_msk) != 0; }
|
||||
static bool has_sha512() { return (_features & ISA_sha512_msk) != 0; }
|
||||
static bool has_mpmul() { return (_features & ISA_mpmul_msk) != 0; }
|
||||
static bool has_mont() { return (_features & ISA_mont_msk) != 0; }
|
||||
static bool has_pause() { return (_features & ISA_pause_msk) != 0; }
|
||||
static bool has_cbcond() { return (_features & ISA_cbcond_msk) != 0; }
|
||||
static bool has_crc32c() { return (_features & ISA_crc32c_msk) != 0; }
|
||||
|
||||
// Returns true if the platform is in the niagara line (T series)
|
||||
// and newer than the niagara1.
|
||||
static bool is_niagara_plus() { return is_T_family(_features) && !is_T1_model(_features); }
|
||||
static bool has_athena_plus() { return (_features & ISA_fjathplus_msk) != 0; }
|
||||
static bool has_vis3b() { return (_features & ISA_vis3b_msk) != 0; }
|
||||
static bool has_adi() { return (_features & ISA_adi_msk) != 0; }
|
||||
static bool has_sparc5() { return (_features & ISA_sparc5_msk) != 0; }
|
||||
static bool has_mwait() { return (_features & ISA_mwait_msk) != 0; }
|
||||
static bool has_xmpmul() { return (_features & ISA_xmpmul_msk) != 0; }
|
||||
static bool has_xmont() { return (_features & ISA_xmont_msk) != 0; }
|
||||
static bool has_pause_nsec() { return (_features & ISA_pause_nsec_msk) != 0; }
|
||||
static bool has_vamask() { return (_features & ISA_vamask_msk) != 0; }
|
||||
|
||||
static bool is_M_series() { return is_M_family(_features); }
|
||||
static bool is_S_series() { return is_S_family(_features); }
|
||||
static bool is_T4() { return is_T_family(_features) && has_cbcond(); }
|
||||
static bool is_T7() { return is_T_family(_features) && has_sparc5_instr(); }
|
||||
static bool has_fast_idiv() { return (_features & CPU_fast_idiv_msk) != 0; }
|
||||
static bool has_fast_rdpc() { return (_features & CPU_fast_rdpc_msk) != 0; }
|
||||
static bool has_fast_bis() { return (_features & CPU_fast_bis_msk) != 0; }
|
||||
static bool has_fast_ld() { return (_features & CPU_fast_ld_msk) != 0; }
|
||||
static bool has_fast_cmove() { return (_features & CPU_fast_cmove_msk) != 0; }
|
||||
|
||||
// Fujitsu SPARC64
|
||||
static bool is_sparc64() { return (_features & sparc64_family_m) != 0; }
|
||||
// If indirect and direct branching is equally fast.
|
||||
static bool has_fast_ind_br() { return (_features & CPU_fast_ind_br_msk) != 0; }
|
||||
// If SPARC BIS to the beginning of cache line always zeros it.
|
||||
static bool has_blk_zeroing() { return (_features & CPU_blk_zeroing_msk) != 0; }
|
||||
|
||||
static bool is_sun4v() { return (_features & sun4v_m) != 0; }
|
||||
static bool is_ultra3() { return (_features & ultra3_m) == ultra3_m && !is_sun4v() && !is_sparc64(); }
|
||||
static bool supports_compare_and_exchange() { return true; }
|
||||
|
||||
static bool has_fast_fxtof() { return is_niagara() || is_sparc64() || has_v9() && !is_ultra3(); }
|
||||
static bool has_fast_idiv() { return is_niagara_plus() || is_sparc64(); }
|
||||
// FIXME: To be removed.
|
||||
static bool is_post_niagara() {
|
||||
return (_features & niagara2_msk) == niagara2_msk;
|
||||
}
|
||||
|
||||
// T4 and newer Sparc have fast RDPC instruction.
|
||||
static bool has_fast_rdpc() { return is_T4(); }
|
||||
// Default prefetch block size on SPARC.
|
||||
static uint prefetch_data_size() { return L2_data_cache_line_size(); }
|
||||
|
||||
// On T4 and newer Sparc BIS to the beginning of cache line always zeros it.
|
||||
static bool has_block_zeroing() { return has_blk_init() && is_T4(); }
|
||||
|
||||
// default prefetch block size on sparc
|
||||
static intx prefetch_data_size() { return L2_data_cache_line_size(); }
|
||||
|
||||
// Prefetch
|
||||
private:
|
||||
// Prefetch policy and characteristics:
|
||||
//
|
||||
// These support routines are used in order to isolate any CPU/core specific
|
||||
// logic from the actual flag/option processing. They should reflect the HW
|
||||
// characteristics for the associated options on the current platform.
|
||||
//
|
||||
// The three Prefetch* options below (assigned -1 in the configuration) are
|
||||
// treated according to (given the accepted range [-1..<maxint>]):
|
||||
// -1: Determine a proper HW-specific value for the current HW.
|
||||
// 0: Off
|
||||
// >0: Command-line supplied value to use.
|
||||
//
|
||||
// FIXME: The documentation string in the configuration is wrong, saying that
|
||||
// -1 is also interpreted as off.
|
||||
//
|
||||
static intx prefetch_copy_interval_in_bytes() {
|
||||
return (has_v9() ? 512 : 0);
|
||||
intx bytes = PrefetchCopyIntervalInBytes;
|
||||
return bytes < 0 ? 512 : bytes;
|
||||
}
|
||||
static intx prefetch_scan_interval_in_bytes() {
|
||||
return (has_v9() ? 512 : 0);
|
||||
intx bytes = PrefetchScanIntervalInBytes;
|
||||
return bytes < 0 ? 512 : bytes;
|
||||
}
|
||||
static intx prefetch_fields_ahead() {
|
||||
return (is_ultra3() ? 1 : 0);
|
||||
intx count = PrefetchFieldsAhead;
|
||||
return count < 0 ? 0 : count;
|
||||
}
|
||||
|
||||
// AllocatePrefetchDistance is treated under the same interpretation as the
|
||||
// Prefetch* options above (i.e., -1, 0, >0).
|
||||
static intx allocate_prefetch_distance() {
|
||||
intx count = AllocatePrefetchDistance;
|
||||
return count < 0 ? 512 : count;
|
||||
}
|
||||
|
||||
// AllocatePrefetchStyle is guaranteed to be in range [0..3] defined by the
|
||||
// configuration.
|
||||
static intx allocate_prefetch_style() {
|
||||
intx distance = allocate_prefetch_distance();
|
||||
// Return 0 (off/none) if AllocatePrefetchDistance was not defined.
|
||||
return distance > 0 ? AllocatePrefetchStyle : 0;
|
||||
}
|
||||
|
||||
public:
|
||||
// Assembler testing
|
||||
static void allow_all();
|
||||
static void revert();
|
||||
|
||||
// Override the Abstract_VM_Version implementation.
|
||||
static uint page_size_count() { return is_sun4v() ? 4 : 2; }
|
||||
//
|
||||
// FIXME: Removed broken test on sun4v (always false when invoked prior to the
|
||||
// proper capability setup), thus always returning 2. Still need to fix
|
||||
// this properly in order to enable complete page size support.
|
||||
static uint page_size_count() { return 2; }
|
||||
|
||||
// Calculates the number of parallel threads
|
||||
static unsigned int calc_parallel_worker_threads();
|
||||
|
@ -27,9 +27,8 @@
|
||||
|
||||
inline bool is_Register() { return value() >= 0 && value() < ConcreteRegisterImpl::max_gpr; }
|
||||
inline bool is_FloatRegister() { return value() >= ConcreteRegisterImpl::max_gpr &&
|
||||
value() < ConcreteRegisterImpl::max_fpr; }
|
||||
value() < ConcreteRegisterImpl::max_fpr; }
|
||||
inline Register as_Register() {
|
||||
|
||||
assert( is_Register() && is_even(value()), "even-aligned GPR name" );
|
||||
// Yuk
|
||||
return ::as_Register(value()>>1);
|
||||
|
@ -57,72 +57,120 @@ public class SPARCHotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFacto
|
||||
|
||||
protected EnumSet<CPUFeature> computeFeatures(SPARCHotSpotVMConfig config) {
|
||||
EnumSet<CPUFeature> features = EnumSet.noneOf(CPUFeature.class);
|
||||
if ((config.vmVersionFeatures & config.sparcVis1Instructions) != 0) {
|
||||
features.add(CPUFeature.VIS1);
|
||||
|
||||
if ((config.vmVersionFeatures & 1L << config.sparc_ADI) != 0) {
|
||||
features.add(CPUFeature.ADI);
|
||||
}
|
||||
if ((config.vmVersionFeatures & config.sparcVis2Instructions) != 0) {
|
||||
features.add(CPUFeature.VIS2);
|
||||
if ((config.vmVersionFeatures & 1L << config.sparc_AES) != 0) {
|
||||
features.add(CPUFeature.AES);
|
||||
}
|
||||
if ((config.vmVersionFeatures & config.sparcVis3Instructions) != 0) {
|
||||
features.add(CPUFeature.VIS3);
|
||||
if ((config.vmVersionFeatures & 1L << config.sparc_BLK_INIT) != 0) {
|
||||
features.add(CPUFeature.BLK_INIT);
|
||||
}
|
||||
if ((config.vmVersionFeatures & config.sparcCbcondInstructions) != 0) {
|
||||
if ((config.vmVersionFeatures & 1L << config.sparc_CAMELLIA) != 0) {
|
||||
features.add(CPUFeature.CAMELLIA);
|
||||
}
|
||||
if ((config.vmVersionFeatures & 1L << config.sparc_CBCOND) != 0) {
|
||||
features.add(CPUFeature.CBCOND);
|
||||
}
|
||||
if ((config.vmVersionFeatures & config.sparcV8Instructions) != 0) {
|
||||
features.add(CPUFeature.V8);
|
||||
if ((config.vmVersionFeatures & 1L << config.sparc_CRC32C) != 0) {
|
||||
features.add(CPUFeature.CRC32C);
|
||||
}
|
||||
if ((config.vmVersionFeatures & config.sparcHardwareMul32) != 0) {
|
||||
features.add(CPUFeature.HARDWARE_MUL32);
|
||||
if ((config.vmVersionFeatures & 1L << config.sparc_DES) != 0) {
|
||||
features.add(CPUFeature.DES);
|
||||
}
|
||||
if ((config.vmVersionFeatures & config.sparcHardwareDiv32) != 0) {
|
||||
features.add(CPUFeature.HARDWARE_DIV32);
|
||||
}
|
||||
if ((config.vmVersionFeatures & config.sparcHardwareFsmuld) != 0) {
|
||||
features.add(CPUFeature.HARDWARE_FSMULD);
|
||||
}
|
||||
if ((config.vmVersionFeatures & config.sparcHardwarePopc) != 0) {
|
||||
features.add(CPUFeature.HARDWARE_POPC);
|
||||
}
|
||||
if ((config.vmVersionFeatures & config.sparcV9Instructions) != 0) {
|
||||
features.add(CPUFeature.V9);
|
||||
}
|
||||
if ((config.vmVersionFeatures & config.sparcSun4v) != 0) {
|
||||
features.add(CPUFeature.SUN4V);
|
||||
}
|
||||
if ((config.vmVersionFeatures & config.sparcBlkInitInstructions) != 0) {
|
||||
features.add(CPUFeature.BLK_INIT_INSTRUCTIONS);
|
||||
}
|
||||
if ((config.vmVersionFeatures & config.sparcFmafInstructions) != 0) {
|
||||
if ((config.vmVersionFeatures & 1L << config.sparc_FMAF) != 0) {
|
||||
features.add(CPUFeature.FMAF);
|
||||
}
|
||||
if ((config.vmVersionFeatures & config.sparcSparc64Family) != 0) {
|
||||
features.add(CPUFeature.SPARC64_FAMILY);
|
||||
if ((config.vmVersionFeatures & 1L << config.sparc_HPC) != 0) {
|
||||
features.add(CPUFeature.HPC);
|
||||
}
|
||||
if ((config.vmVersionFeatures & config.sparcMFamily) != 0) {
|
||||
features.add(CPUFeature.M_FAMILY);
|
||||
if ((config.vmVersionFeatures & 1L << config.sparc_IMA) != 0) {
|
||||
features.add(CPUFeature.IMA);
|
||||
}
|
||||
if ((config.vmVersionFeatures & config.sparcTFamily) != 0) {
|
||||
features.add(CPUFeature.T_FAMILY);
|
||||
if ((config.vmVersionFeatures & 1L << config.sparc_KASUMI) != 0) {
|
||||
features.add(CPUFeature.KASUMI);
|
||||
}
|
||||
if ((config.vmVersionFeatures & config.sparcT1Model) != 0) {
|
||||
features.add(CPUFeature.T1_MODEL);
|
||||
if ((config.vmVersionFeatures & 1L << config.sparc_MD5) != 0) {
|
||||
features.add(CPUFeature.MD5);
|
||||
}
|
||||
if ((config.vmVersionFeatures & config.sparcSparc5Instructions) != 0) {
|
||||
features.add(CPUFeature.SPARC5);
|
||||
if ((config.vmVersionFeatures & 1L << config.sparc_MONT) != 0) {
|
||||
features.add(CPUFeature.MONT);
|
||||
}
|
||||
if ((config.vmVersionFeatures & config.sparcAesInstructions) != 0) {
|
||||
features.add(CPUFeature.SPARC64_FAMILY);
|
||||
if ((config.vmVersionFeatures & 1L << config.sparc_MPMUL) != 0) {
|
||||
features.add(CPUFeature.MPMUL);
|
||||
}
|
||||
if ((config.vmVersionFeatures & config.sparcSha1Instruction) != 0) {
|
||||
if ((config.vmVersionFeatures & 1L << config.sparc_MWAIT) != 0) {
|
||||
features.add(CPUFeature.MWAIT);
|
||||
}
|
||||
if ((config.vmVersionFeatures & 1L << config.sparc_PAUSE) != 0) {
|
||||
features.add(CPUFeature.PAUSE);
|
||||
}
|
||||
if ((config.vmVersionFeatures & 1L << config.sparc_PAUSE_NSEC) != 0) {
|
||||
features.add(CPUFeature.PAUSE_NSEC);
|
||||
}
|
||||
if ((config.vmVersionFeatures & 1L << config.sparc_POPC) != 0) {
|
||||
features.add(CPUFeature.POPC);
|
||||
}
|
||||
if ((config.vmVersionFeatures & 1L << config.sparc_SHA1) != 0) {
|
||||
features.add(CPUFeature.SHA1);
|
||||
}
|
||||
if ((config.vmVersionFeatures & config.sparcSha256Instruction) != 0) {
|
||||
if ((config.vmVersionFeatures & 1L << config.sparc_SHA256) != 0) {
|
||||
features.add(CPUFeature.SHA256);
|
||||
}
|
||||
if ((config.vmVersionFeatures & config.sparcSha512Instruction) != 0) {
|
||||
if ((config.vmVersionFeatures & 1L << config.sparc_SHA512) != 0) {
|
||||
features.add(CPUFeature.SHA512);
|
||||
}
|
||||
if ((config.vmVersionFeatures & 1L << config.sparc_SPARC5) != 0) {
|
||||
features.add(CPUFeature.SPARC5);
|
||||
}
|
||||
if ((config.vmVersionFeatures & 1L << config.sparc_V9) != 0) {
|
||||
features.add(CPUFeature.V9);
|
||||
}
|
||||
if ((config.vmVersionFeatures & 1L << config.sparc_VAMASK) != 0) {
|
||||
features.add(CPUFeature.VAMASK);
|
||||
}
|
||||
if ((config.vmVersionFeatures & 1L << config.sparc_VIS1) != 0) {
|
||||
features.add(CPUFeature.VIS1);
|
||||
}
|
||||
if ((config.vmVersionFeatures & 1L << config.sparc_VIS2) != 0) {
|
||||
features.add(CPUFeature.VIS2);
|
||||
}
|
||||
if ((config.vmVersionFeatures & 1L << config.sparc_VIS3) != 0) {
|
||||
features.add(CPUFeature.VIS3);
|
||||
}
|
||||
if ((config.vmVersionFeatures & 1L << config.sparc_VIS3B) != 0) {
|
||||
features.add(CPUFeature.VIS3B);
|
||||
}
|
||||
if ((config.vmVersionFeatures & 1L << config.sparc_XMONT) != 0) {
|
||||
features.add(CPUFeature.XMONT);
|
||||
}
|
||||
if ((config.vmVersionFeatures & 1L << config.sparc_XMPMUL) != 0) {
|
||||
features.add(CPUFeature.XMPMUL);
|
||||
}
|
||||
|
||||
if ((config.vmVersionFeatures & 1L << config.sparc_BLK_ZEROING) != 0) {
|
||||
features.add(CPUFeature.BLK_ZEROING);
|
||||
}
|
||||
if ((config.vmVersionFeatures & 1L << config.sparc_FAST_BIS) != 0) {
|
||||
features.add(CPUFeature.FAST_BIS);
|
||||
}
|
||||
if ((config.vmVersionFeatures & 1L << config.sparc_FAST_CMOVE) != 0) {
|
||||
features.add(CPUFeature.FAST_CMOVE);
|
||||
}
|
||||
if ((config.vmVersionFeatures & 1L << config.sparc_FAST_IDIV) != 0) {
|
||||
features.add(CPUFeature.FAST_IDIV);
|
||||
}
|
||||
if ((config.vmVersionFeatures & 1L << config.sparc_FAST_IND_BR) != 0) {
|
||||
features.add(CPUFeature.FAST_IND_BR);
|
||||
}
|
||||
if ((config.vmVersionFeatures & 1L << config.sparc_FAST_LD) != 0) {
|
||||
features.add(CPUFeature.FAST_LD);
|
||||
}
|
||||
if ((config.vmVersionFeatures & 1L << config.sparc_FAST_RDPC) != 0) {
|
||||
features.add(CPUFeature.FAST_RDPC);
|
||||
}
|
||||
|
||||
return features;
|
||||
}
|
||||
|
||||
|
@ -38,32 +38,54 @@ class SPARCHotSpotVMConfig extends HotSpotVMConfigAccess {
|
||||
|
||||
final boolean useCompressedOops = getFlag("UseCompressedOops", Boolean.class);
|
||||
|
||||
// CPU capabilities
|
||||
// CPU capabilities:
|
||||
//
|
||||
// FIXME: Using a 64-bit value is insufficient to support future capability
|
||||
// sets (including co-processor capabilities such as DAX).
|
||||
final long vmVersionFeatures = getFieldValue("Abstract_VM_Version::_features", Long.class, "uint64_t");
|
||||
|
||||
// SPARC specific values
|
||||
final int sparcVis3Instructions = getConstant("VM_Version::vis3_instructions_m", Integer.class);
|
||||
final int sparcVis2Instructions = getConstant("VM_Version::vis2_instructions_m", Integer.class);
|
||||
final int sparcVis1Instructions = getConstant("VM_Version::vis1_instructions_m", Integer.class);
|
||||
final int sparcCbcondInstructions = getConstant("VM_Version::cbcond_instructions_m", Integer.class);
|
||||
final int sparcV8Instructions = getConstant("VM_Version::v8_instructions_m", Integer.class);
|
||||
final int sparcHardwareMul32 = getConstant("VM_Version::hardware_mul32_m", Integer.class);
|
||||
final int sparcHardwareDiv32 = getConstant("VM_Version::hardware_div32_m", Integer.class);
|
||||
final int sparcHardwareFsmuld = getConstant("VM_Version::hardware_fsmuld_m", Integer.class);
|
||||
final int sparcHardwarePopc = getConstant("VM_Version::hardware_popc_m", Integer.class);
|
||||
final int sparcV9Instructions = getConstant("VM_Version::v9_instructions_m", Integer.class);
|
||||
final int sparcSun4v = getConstant("VM_Version::sun4v_m", Integer.class);
|
||||
final int sparcBlkInitInstructions = getConstant("VM_Version::blk_init_instructions_m", Integer.class);
|
||||
final int sparcFmafInstructions = getConstant("VM_Version::fmaf_instructions_m", Integer.class);
|
||||
final int sparcSparc64Family = getConstant("VM_Version::sparc64_family_m", Integer.class);
|
||||
final int sparcMFamily = getConstant("VM_Version::M_family_m", Integer.class);
|
||||
final int sparcTFamily = getConstant("VM_Version::T_family_m", Integer.class);
|
||||
final int sparcT1Model = getConstant("VM_Version::T1_model_m", Integer.class);
|
||||
final int sparcSparc5Instructions = getConstant("VM_Version::sparc5_instructions_m", Integer.class);
|
||||
final int sparcAesInstructions = getConstant("VM_Version::aes_instructions_m", Integer.class);
|
||||
final int sparcSha1Instruction = getConstant("VM_Version::sha1_instruction_m", Integer.class);
|
||||
final int sparcSha256Instruction = getConstant("VM_Version::sha256_instruction_m", Integer.class);
|
||||
final int sparcSha512Instruction = getConstant("VM_Version::sha512_instruction_m", Integer.class);
|
||||
// SPARC specific values:
|
||||
//
|
||||
// NOTE: Values changed into an enumeration (that do indeed fit within a
|
||||
// 32-bit integer) instead of the exported (64-bit wide) bit-masks.
|
||||
final int sparc_ADI = getConstant("VM_Version::ISA_ADI", Integer.class);
|
||||
final int sparc_AES = getConstant("VM_Version::ISA_AES", Integer.class);
|
||||
final int sparc_BLK_INIT = getConstant("VM_Version::ISA_BLK_INIT", Integer.class);
|
||||
final int sparc_CAMELLIA = getConstant("VM_Version::ISA_CAMELLIA", Integer.class);
|
||||
final int sparc_CBCOND = getConstant("VM_Version::ISA_CBCOND", Integer.class);
|
||||
final int sparc_CRC32C = getConstant("VM_Version::ISA_CRC32C", Integer.class);
|
||||
final int sparc_DES = getConstant("VM_Version::ISA_DES", Integer.class);
|
||||
final int sparc_FMAF = getConstant("VM_Version::ISA_FMAF", Integer.class);
|
||||
final int sparc_HPC = getConstant("VM_Version::ISA_HPC", Integer.class);
|
||||
final int sparc_IMA = getConstant("VM_Version::ISA_IMA", Integer.class);
|
||||
final int sparc_KASUMI = getConstant("VM_Version::ISA_KASUMI", Integer.class);
|
||||
final int sparc_MD5 = getConstant("VM_Version::ISA_MD5", Integer.class);
|
||||
final int sparc_MONT = getConstant("VM_Version::ISA_MONT", Integer.class);
|
||||
final int sparc_MPMUL = getConstant("VM_Version::ISA_MPMUL", Integer.class);
|
||||
final int sparc_MWAIT = getConstant("VM_Version::ISA_MWAIT", Integer.class);
|
||||
final int sparc_PAUSE = getConstant("VM_Version::ISA_PAUSE", Integer.class);
|
||||
final int sparc_PAUSE_NSEC = getConstant("VM_Version::ISA_PAUSE_NSEC", Integer.class);
|
||||
final int sparc_POPC = getConstant("VM_Version::ISA_POPC", Integer.class);
|
||||
final int sparc_SHA1 = getConstant("VM_Version::ISA_SHA1", Integer.class);
|
||||
final int sparc_SHA256 = getConstant("VM_Version::ISA_SHA256", Integer.class);
|
||||
final int sparc_SHA512 = getConstant("VM_Version::ISA_SHA512", Integer.class);
|
||||
final int sparc_SPARC5 = getConstant("VM_Version::ISA_SPARC5", Integer.class);
|
||||
final int sparc_V9 = getConstant("VM_Version::ISA_V9", Integer.class);
|
||||
final int sparc_VAMASK = getConstant("VM_Version::ISA_VAMASK", Integer.class);
|
||||
final int sparc_VIS1 = getConstant("VM_Version::ISA_VIS1", Integer.class);
|
||||
final int sparc_VIS2 = getConstant("VM_Version::ISA_VIS2", Integer.class);
|
||||
final int sparc_VIS3 = getConstant("VM_Version::ISA_VIS3", Integer.class);
|
||||
final int sparc_VIS3B = getConstant("VM_Version::ISA_VIS3B", Integer.class);
|
||||
final int sparc_XMONT = getConstant("VM_Version::ISA_XMONT", Integer.class);
|
||||
final int sparc_XMPMUL = getConstant("VM_Version::ISA_XMPMUL", Integer.class);
|
||||
|
||||
final int sparc_BLK_ZEROING = getConstant("VM_Version::CPU_BLK_ZEROING", Integer.class);
|
||||
final int sparc_FAST_BIS = getConstant("VM_Version::CPU_FAST_BIS", Integer.class);
|
||||
final int sparc_FAST_CMOVE = getConstant("VM_Version::CPU_FAST_CMOVE", Integer.class);
|
||||
final int sparc_FAST_IDIV = getConstant("VM_Version::CPU_FAST_IDIV", Integer.class);
|
||||
final int sparc_FAST_IND_BR = getConstant("VM_Version::CPU_FAST_IND_BR", Integer.class);
|
||||
final int sparc_FAST_LD = getConstant("VM_Version::CPU_FAST_LD", Integer.class);
|
||||
final int sparc_FAST_RDPC = getConstant("VM_Version::CPU_FAST_RDPC", Integer.class);
|
||||
|
||||
final boolean useBlockZeroing = getFlag("UseBlockZeroing", Boolean.class);
|
||||
final int blockZeroingLowLimit = getFlag("BlockZeroingLowLimit", Integer.class);
|
||||
|
@ -336,27 +336,44 @@ public class SPARC extends Architecture {
|
||||
}
|
||||
|
||||
public enum CPUFeature {
|
||||
// ISA determined properties:
|
||||
ADI,
|
||||
AES,
|
||||
BLK_INIT,
|
||||
CAMELLIA,
|
||||
CBCOND,
|
||||
CRC32C,
|
||||
DES,
|
||||
FMAF,
|
||||
HPC,
|
||||
IMA,
|
||||
KASUMI,
|
||||
MD5,
|
||||
MONT,
|
||||
MPMUL,
|
||||
MWAIT,
|
||||
PAUSE,
|
||||
PAUSE_NSEC,
|
||||
POPC,
|
||||
SHA1,
|
||||
SHA256,
|
||||
SHA512,
|
||||
SPARC5,
|
||||
V9,
|
||||
VAMASK,
|
||||
VIS1,
|
||||
VIS2,
|
||||
VIS3,
|
||||
CBCOND,
|
||||
V8,
|
||||
HARDWARE_MUL32,
|
||||
HARDWARE_DIV32,
|
||||
HARDWARE_FSMULD,
|
||||
HARDWARE_POPC,
|
||||
V9,
|
||||
SUN4V,
|
||||
BLK_INIT_INSTRUCTIONS,
|
||||
FMAF,
|
||||
SPARC64_FAMILY,
|
||||
M_FAMILY,
|
||||
T_FAMILY,
|
||||
T1_MODEL,
|
||||
SPARC5,
|
||||
AES,
|
||||
SHA1,
|
||||
SHA256,
|
||||
SHA512
|
||||
VIS3B,
|
||||
XMONT,
|
||||
XMPMUL,
|
||||
// Synthesised CPU properties:
|
||||
BLK_ZEROING,
|
||||
FAST_BIS,
|
||||
FAST_CMOVE,
|
||||
FAST_IDIV,
|
||||
FAST_IND_BR,
|
||||
FAST_LD,
|
||||
FAST_RDPC
|
||||
}
|
||||
}
|
||||
|
@ -30,9 +30,7 @@
|
||||
#include "vm_version_sparc.hpp"
|
||||
|
||||
#include <sys/auxv.h>
|
||||
#include <sys/auxv_SPARC.h>
|
||||
#include <sys/systeminfo.h>
|
||||
#include <kstat.h>
|
||||
#include <picl.h>
|
||||
#include <dlfcn.h>
|
||||
#include <link.h>
|
||||
@ -263,21 +261,6 @@ void PICL::close_library() {
|
||||
_dl_handle = NULL;
|
||||
}
|
||||
|
||||
// We need to keep these here as long as we have to build on Solaris
|
||||
// versions before 10.
|
||||
|
||||
#ifndef SI_ARCHITECTURE_32
|
||||
#define SI_ARCHITECTURE_32 516 /* basic 32-bit SI_ARCHITECTURE */
|
||||
#endif
|
||||
|
||||
#ifndef SI_ARCHITECTURE_64
|
||||
#define SI_ARCHITECTURE_64 517 /* basic 64-bit SI_ARCHITECTURE */
|
||||
#endif
|
||||
|
||||
#ifndef SI_CPUBRAND
|
||||
#define SI_CPUBRAND 523 /* return cpu brand string */
|
||||
#endif
|
||||
|
||||
class Sysinfo {
|
||||
char* _string;
|
||||
public:
|
||||
@ -343,115 +326,156 @@ public:
|
||||
#define _SC_L2CACHE_LINESZ 527 /* Size of L2 cache line */
|
||||
#endif
|
||||
|
||||
// Hardware capability bits that appeared after Solaris 11.1
|
||||
#ifndef AV_SPARC_FMAF
|
||||
#define AV_SPARC_FMAF 0x00000100 /* Fused Multiply-Add */
|
||||
#endif
|
||||
#ifndef AV2_SPARC_SPARC5
|
||||
#define AV2_SPARC_SPARC5 0x00000008 /* The 29 new fp and sub instructions */
|
||||
#endif
|
||||
void VM_Version::platform_features() {
|
||||
uint64_t features = ISA_v9_msk; // Basic SPARC-V9 required (V8 not supported).
|
||||
|
||||
int VM_Version::platform_features(int features) {
|
||||
|
||||
// Check 32-bit architecture.
|
||||
if (Sysinfo(SI_ARCHITECTURE_32).match("sparc")) {
|
||||
features |= v8_instructions_m;
|
||||
}
|
||||
|
||||
// Check 64-bit architecture.
|
||||
if (Sysinfo(SI_ARCHITECTURE_64).match("sparcv9")) {
|
||||
features |= generic_v9_m;
|
||||
}
|
||||
assert(Sysinfo(SI_ARCHITECTURE_64).match("sparcv9"), "must be");
|
||||
|
||||
// Extract valid instruction set extensions.
|
||||
uint_t avs[AV_HW2_IDX + 1];
|
||||
uint_t avn = getisax(avs, ARRAY_SIZE(avs));
|
||||
uint32_t avs[AV_HW2_IDX + 1];
|
||||
uint_t avn = getisax(avs, AV_HW2_IDX + 1);
|
||||
assert(avn <= 2, "should return two or less av's");
|
||||
|
||||
log_info(os, cpu)("getisax(2) returned %d words:", avn);
|
||||
for (int i = 0; i < avn; i++) {
|
||||
log_info(os, cpu)(" word %d: " PTR32_FORMAT, i, avs[i]);
|
||||
}
|
||||
|
||||
uint_t av1 = avs[AV_HW1_IDX];
|
||||
if (av1 & AV_SPARC_MUL32) features |= hardware_mul32_m;
|
||||
if (av1 & AV_SPARC_DIV32) features |= hardware_div32_m;
|
||||
if (av1 & AV_SPARC_FSMULD) features |= hardware_fsmuld_m;
|
||||
if (av1 & AV_SPARC_V8PLUS) features |= v9_instructions_m;
|
||||
if (av1 & AV_SPARC_POPC) features |= hardware_popc_m;
|
||||
if (av1 & AV_SPARC_VIS) features |= vis1_instructions_m;
|
||||
if (av1 & AV_SPARC_VIS2) features |= vis2_instructions_m;
|
||||
if (av1 & AV_SPARC_ASI_BLK_INIT) features |= blk_init_instructions_m;
|
||||
if (av1 & AV_SPARC_FMAF) features |= fmaf_instructions_m;
|
||||
if (av1 & AV_SPARC_VIS3) features |= vis3_instructions_m;
|
||||
if (av1 & AV_SPARC_CBCOND) features |= cbcond_instructions_m;
|
||||
if (av1 & AV_SPARC_CRC32C) features |= crc32c_instruction_m;
|
||||
if (av1 & AV_SPARC_AES) features |= aes_instructions_m;
|
||||
if (av1 & AV_SPARC_SHA1) features |= sha1_instruction_m;
|
||||
if (av1 & AV_SPARC_SHA256) features |= sha256_instruction_m;
|
||||
if (av1 & AV_SPARC_SHA512) features |= sha512_instruction_m;
|
||||
uint32_t av = avs[AV_HW1_IDX];
|
||||
|
||||
if (avn > AV_HW2_IDX) {
|
||||
uint_t av2 = avs[AV_HW2_IDX];
|
||||
if (av2 & AV2_SPARC_SPARC5) features |= sparc5_instructions_m;
|
||||
// These are SPARC V8 legacy features.
|
||||
|
||||
assert((av & AV_SPARC_MUL32) == 0, "unsupported V8");
|
||||
assert((av & AV_SPARC_DIV32) == 0, "unsupported V8");
|
||||
assert((av & AV_SPARC_FSMULD) == 0, "unsupported V8");
|
||||
assert((av & AV_SPARC_V8PLUS) == 0, "unsupported V8");
|
||||
|
||||
if (av & AV_SPARC_POPC) features |= ISA_popc_msk;
|
||||
if (av & AV_SPARC_VIS) features |= ISA_vis1_msk;
|
||||
if (av & AV_SPARC_VIS2) features |= ISA_vis2_msk;
|
||||
|
||||
// Hardware capability defines introduced after Solaris 11.1:
|
||||
|
||||
#ifndef AV_SPARC_FMAF
|
||||
#define AV_SPARC_FMAF 0x00000100 // Fused Multiply-Add
|
||||
#endif
|
||||
|
||||
if (av & AV_SPARC_ASI_BLK_INIT) features |= ISA_blk_init_msk;
|
||||
if (av & AV_SPARC_FMAF) features |= ISA_fmaf_msk;
|
||||
if (av & AV_SPARC_VIS3) features |= ISA_vis3_msk;
|
||||
if (av & AV_SPARC_HPC) features |= ISA_hpc_msk;
|
||||
if (av & AV_SPARC_IMA) features |= ISA_ima_msk;
|
||||
if (av & AV_SPARC_AES) features |= ISA_aes_msk;
|
||||
if (av & AV_SPARC_DES) features |= ISA_des_msk;
|
||||
if (av & AV_SPARC_KASUMI) features |= ISA_kasumi_msk;
|
||||
if (av & AV_SPARC_CAMELLIA) features |= ISA_camellia_msk;
|
||||
if (av & AV_SPARC_MD5) features |= ISA_md5_msk;
|
||||
if (av & AV_SPARC_SHA1) features |= ISA_sha1_msk;
|
||||
if (av & AV_SPARC_SHA256) features |= ISA_sha256_msk;
|
||||
if (av & AV_SPARC_SHA512) features |= ISA_sha512_msk;
|
||||
if (av & AV_SPARC_MPMUL) features |= ISA_mpmul_msk;
|
||||
if (av & AV_SPARC_MONT) features |= ISA_mont_msk;
|
||||
if (av & AV_SPARC_PAUSE) features |= ISA_pause_msk;
|
||||
if (av & AV_SPARC_CBCOND) features |= ISA_cbcond_msk;
|
||||
if (av & AV_SPARC_CRC32C) features |= ISA_crc32c_msk;
|
||||
|
||||
#ifndef AV2_SPARC_FJATHPLUS
|
||||
#define AV2_SPARC_FJATHPLUS 0x00000001 // Fujitsu Athena+
|
||||
#endif
|
||||
#ifndef AV2_SPARC_VIS3B
|
||||
#define AV2_SPARC_VIS3B 0x00000002 // VIS3 present on multiple chips
|
||||
#endif
|
||||
#ifndef AV2_SPARC_ADI
|
||||
#define AV2_SPARC_ADI 0x00000004 // Application Data Integrity
|
||||
#endif
|
||||
#ifndef AV2_SPARC_SPARC5
|
||||
#define AV2_SPARC_SPARC5 0x00000008 // The 29 new fp and sub instructions
|
||||
#endif
|
||||
#ifndef AV2_SPARC_MWAIT
|
||||
#define AV2_SPARC_MWAIT 0x00000010 // mwait instruction and load/monitor ASIs
|
||||
#endif
|
||||
#ifndef AV2_SPARC_XMPMUL
|
||||
#define AV2_SPARC_XMPMUL 0x00000020 // XOR multiple precision multiply
|
||||
#endif
|
||||
#ifndef AV2_SPARC_XMONT
|
||||
#define AV2_SPARC_XMONT 0x00000040 // XOR Montgomery mult/sqr instructions
|
||||
#endif
|
||||
#ifndef AV2_SPARC_PAUSE_NSEC
|
||||
#define AV2_SPARC_PAUSE_NSEC 0x00000080 // pause instruction with support for nsec timings
|
||||
#endif
|
||||
#ifndef AV2_SPARC_VAMASK
|
||||
#define AV2_SPARC_VAMASK 0x00000100 // Virtual Address masking
|
||||
#endif
|
||||
|
||||
if (avn > 1) {
|
||||
uint32_t av2 = avs[AV_HW2_IDX];
|
||||
|
||||
if (av2 & AV2_SPARC_FJATHPLUS) features |= ISA_fjathplus_msk;
|
||||
if (av2 & AV2_SPARC_VIS3B) features |= ISA_vis3b_msk;
|
||||
if (av2 & AV2_SPARC_ADI) features |= ISA_adi_msk;
|
||||
if (av2 & AV2_SPARC_SPARC5) features |= ISA_sparc5_msk;
|
||||
if (av2 & AV2_SPARC_MWAIT) features |= ISA_mwait_msk;
|
||||
if (av2 & AV2_SPARC_XMPMUL) features |= ISA_xmpmul_msk;
|
||||
if (av2 & AV2_SPARC_XMONT) features |= ISA_xmont_msk;
|
||||
if (av2 & AV2_SPARC_PAUSE_NSEC) features |= ISA_pause_nsec_msk;
|
||||
if (av2 & AV2_SPARC_VAMASK) features |= ISA_vamask_msk;
|
||||
}
|
||||
|
||||
// Determine the machine type.
|
||||
if (Sysinfo(SI_MACHINE).match("sun4v")) {
|
||||
features |= sun4v_m;
|
||||
}
|
||||
_features = features; // ISA feature set completed, update state.
|
||||
|
||||
// If SI_CPUBRAND works, that means Solaris 12 API to get the cache line sizes
|
||||
// is available to us as well
|
||||
Sysinfo cpu_info(SI_CPUBRAND);
|
||||
bool use_solaris_12_api = cpu_info.valid();
|
||||
const char* impl = "unknown";
|
||||
int impl_m = 0;
|
||||
if (use_solaris_12_api) {
|
||||
impl = cpu_info.value();
|
||||
log_info(os, cpu)("Parsing CPU implementation from %s", impl);
|
||||
impl_m = parse_features(impl);
|
||||
} else {
|
||||
// Otherwise use kstat to determine the machine type.
|
||||
kstat_ctl_t* kc = kstat_open();
|
||||
if (kc != NULL) {
|
||||
kstat_t* ksp = kstat_lookup(kc, (char*)"cpu_info", -1, NULL);
|
||||
if (ksp != NULL) {
|
||||
if (kstat_read(kc, ksp, NULL) != -1 && ksp->ks_data != NULL) {
|
||||
kstat_named_t* knm = (kstat_named_t *)ksp->ks_data;
|
||||
for (int i = 0; i < ksp->ks_ndata; i++) {
|
||||
if (strcmp((const char*)&(knm[i].name), "implementation") == 0) {
|
||||
impl = KSTAT_NAMED_STR_PTR(&knm[i]);
|
||||
log_info(os, cpu)("Parsing CPU implementation from %s", impl);
|
||||
impl_m = parse_features(impl);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Sysinfo machine(SI_MACHINE);
|
||||
|
||||
bool is_sun4v = machine.match("sun4v"); // All Oracle SPARC + Fujitsu Athena+
|
||||
bool is_sun4u = machine.match("sun4u"); // All other Fujitsu
|
||||
|
||||
// Handle Athena+ conservatively (simply because we are lacking info.).
|
||||
|
||||
bool do_sun4v = is_sun4v && !has_athena_plus();
|
||||
bool do_sun4u = is_sun4u || has_athena_plus();
|
||||
|
||||
uint64_t synthetic = 0;
|
||||
|
||||
if (do_sun4v) {
|
||||
// Indirect and direct branches are equally fast.
|
||||
synthetic = CPU_fast_ind_br_msk;
|
||||
// Fast IDIV, BIS and LD available on Niagara Plus.
|
||||
if (has_vis2()) {
|
||||
synthetic |= (CPU_fast_idiv_msk | CPU_fast_ld_msk);
|
||||
// ...on Core S4 however, we prefer not to use BIS.
|
||||
if (!has_sparc5()) {
|
||||
synthetic |= CPU_fast_bis_msk;
|
||||
}
|
||||
kstat_close(kc);
|
||||
}
|
||||
}
|
||||
assert(impl_m != 0, "Unrecognized CPU implementation: %s", impl);
|
||||
features |= impl_m;
|
||||
|
||||
bool is_sun4v = (features & sun4v_m) != 0;
|
||||
if (use_solaris_12_api && is_sun4v) {
|
||||
// If Solaris 12 API is supported and it's sun4v use sysconf() to get the cache line sizes
|
||||
Sysconf l1_dcache_line_size(_SC_DCACHE_LINESZ);
|
||||
if (l1_dcache_line_size.valid()) {
|
||||
_L1_data_cache_line_size = l1_dcache_line_size.value();
|
||||
// Niagara Core S3 supports fast RDPC and block zeroing.
|
||||
if (has_ima()) {
|
||||
synthetic |= (CPU_fast_rdpc_msk | CPU_blk_zeroing_msk);
|
||||
}
|
||||
|
||||
Sysconf l2_dcache_line_size(_SC_L2CACHE_LINESZ);
|
||||
if (l2_dcache_line_size.valid()) {
|
||||
_L2_data_cache_line_size = l2_dcache_line_size.value();
|
||||
// Niagara Core S3 and S4 have slow CMOVE.
|
||||
if (!has_ima()) {
|
||||
synthetic |= CPU_fast_cmove_msk;
|
||||
}
|
||||
} else if (do_sun4u) {
|
||||
// SPARC64 only have fast IDIV and RDPC.
|
||||
synthetic |= (CPU_fast_idiv_msk | CPU_fast_rdpc_msk);
|
||||
} else {
|
||||
// Otherwise figure out the cache line sizes using PICL
|
||||
bool is_fujitsu = (features & sparc64_family_m) != 0;
|
||||
PICL picl(is_fujitsu, is_sun4v);
|
||||
log_info(os, cpu)("Unable to derive CPU features: %s", machine.value());
|
||||
}
|
||||
|
||||
_features += synthetic; // Including CPU derived/synthetic features.
|
||||
|
||||
Sysconf l1_dcache_line_size(_SC_DCACHE_LINESZ);
|
||||
Sysconf l2_dcache_line_size(_SC_L2CACHE_LINESZ);
|
||||
|
||||
// Require both Sysconf requests to be valid or use fall-back.
|
||||
|
||||
if (l1_dcache_line_size.valid() &&
|
||||
l2_dcache_line_size.valid()) {
|
||||
_L1_data_cache_line_size = l1_dcache_line_size.value();
|
||||
_L2_data_cache_line_size = l2_dcache_line_size.value();
|
||||
} else {
|
||||
// Otherwise figure out the cache line sizes using PICL.
|
||||
PICL picl(is_sun4u, is_sun4v);
|
||||
_L1_data_cache_line_size = picl.L1_data_cache_line_size();
|
||||
_L2_data_cache_line_size = picl.L2_data_cache_line_size();
|
||||
}
|
||||
return features;
|
||||
}
|
||||
|
@ -731,29 +731,43 @@
|
||||
volatile_nonstatic_field(JavaFrameAnchor, _flags, int)
|
||||
|
||||
#define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) \
|
||||
declare_constant(VM_Version::vis1_instructions_m) \
|
||||
declare_constant(VM_Version::vis2_instructions_m) \
|
||||
declare_constant(VM_Version::vis3_instructions_m) \
|
||||
declare_constant(VM_Version::cbcond_instructions_m) \
|
||||
declare_constant(VM_Version::v8_instructions_m) \
|
||||
declare_constant(VM_Version::hardware_mul32_m) \
|
||||
declare_constant(VM_Version::hardware_div32_m) \
|
||||
declare_constant(VM_Version::hardware_fsmuld_m) \
|
||||
declare_constant(VM_Version::hardware_popc_m) \
|
||||
declare_constant(VM_Version::v9_instructions_m) \
|
||||
declare_constant(VM_Version::sun4v_m) \
|
||||
declare_constant(VM_Version::blk_init_instructions_m) \
|
||||
declare_constant(VM_Version::fmaf_instructions_m) \
|
||||
declare_constant(VM_Version::sparc64_family_m) \
|
||||
declare_constant(VM_Version::M_family_m) \
|
||||
declare_constant(VM_Version::T_family_m) \
|
||||
declare_constant(VM_Version::T1_model_m) \
|
||||
declare_constant(VM_Version::sparc5_instructions_m) \
|
||||
declare_constant(VM_Version::aes_instructions_m) \
|
||||
declare_constant(VM_Version::sha1_instruction_m) \
|
||||
declare_constant(VM_Version::sha256_instruction_m) \
|
||||
declare_constant(VM_Version::sha512_instruction_m)
|
||||
|
||||
declare_constant(VM_Version::ISA_V9) \
|
||||
declare_constant(VM_Version::ISA_POPC) \
|
||||
declare_constant(VM_Version::ISA_VIS1) \
|
||||
declare_constant(VM_Version::ISA_VIS2) \
|
||||
declare_constant(VM_Version::ISA_BLK_INIT) \
|
||||
declare_constant(VM_Version::ISA_FMAF) \
|
||||
declare_constant(VM_Version::ISA_VIS3) \
|
||||
declare_constant(VM_Version::ISA_HPC) \
|
||||
declare_constant(VM_Version::ISA_IMA) \
|
||||
declare_constant(VM_Version::ISA_AES) \
|
||||
declare_constant(VM_Version::ISA_DES) \
|
||||
declare_constant(VM_Version::ISA_KASUMI) \
|
||||
declare_constant(VM_Version::ISA_CAMELLIA) \
|
||||
declare_constant(VM_Version::ISA_MD5) \
|
||||
declare_constant(VM_Version::ISA_SHA1) \
|
||||
declare_constant(VM_Version::ISA_SHA256) \
|
||||
declare_constant(VM_Version::ISA_SHA512) \
|
||||
declare_constant(VM_Version::ISA_MPMUL) \
|
||||
declare_constant(VM_Version::ISA_MONT) \
|
||||
declare_constant(VM_Version::ISA_PAUSE) \
|
||||
declare_constant(VM_Version::ISA_CBCOND) \
|
||||
declare_constant(VM_Version::ISA_CRC32C) \
|
||||
declare_constant(VM_Version::ISA_VIS3B) \
|
||||
declare_constant(VM_Version::ISA_ADI) \
|
||||
declare_constant(VM_Version::ISA_SPARC5) \
|
||||
declare_constant(VM_Version::ISA_MWAIT) \
|
||||
declare_constant(VM_Version::ISA_XMPMUL) \
|
||||
declare_constant(VM_Version::ISA_XMONT) \
|
||||
declare_constant(VM_Version::ISA_PAUSE_NSEC) \
|
||||
declare_constant(VM_Version::ISA_VAMASK) \
|
||||
declare_constant(VM_Version::CPU_FAST_IDIV) \
|
||||
declare_constant(VM_Version::CPU_FAST_RDPC) \
|
||||
declare_constant(VM_Version::CPU_FAST_BIS) \
|
||||
declare_constant(VM_Version::CPU_FAST_LD) \
|
||||
declare_constant(VM_Version::CPU_FAST_CMOVE) \
|
||||
declare_constant(VM_Version::CPU_FAST_IND_BR) \
|
||||
declare_constant(VM_Version::CPU_BLK_ZEROING)
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -248,7 +248,7 @@ class StubRoutines: AllStatic {
|
||||
static jint verify_oop_count() { return _verify_oop_count; }
|
||||
static jint* verify_oop_count_addr() { return &_verify_oop_count; }
|
||||
// a subroutine for debugging the GC
|
||||
static address verify_oop_subroutine_entry_address() { return (address)&_verify_oop_subroutine_entry; }
|
||||
static address verify_oop_subroutine_entry_address() { return (address)&_verify_oop_subroutine_entry; }
|
||||
|
||||
static address catch_exception_entry() { return _catch_exception_entry; }
|
||||
|
||||
@ -335,8 +335,8 @@ class StubRoutines: AllStatic {
|
||||
static address checkcast_arraycopy(bool dest_uninitialized = false) {
|
||||
return dest_uninitialized ? _checkcast_arraycopy_uninit : _checkcast_arraycopy;
|
||||
}
|
||||
static address unsafe_arraycopy() { return _unsafe_arraycopy; }
|
||||
static address generic_arraycopy() { return _generic_arraycopy; }
|
||||
static address unsafe_arraycopy() { return _unsafe_arraycopy; }
|
||||
static address generic_arraycopy() { return _generic_arraycopy; }
|
||||
|
||||
static address jbyte_fill() { return _jbyte_fill; }
|
||||
static address jshort_fill() { return _jshort_fill; }
|
||||
@ -349,8 +349,8 @@ class StubRoutines: AllStatic {
|
||||
static address aescrypt_decryptBlock() { return _aescrypt_decryptBlock; }
|
||||
static address cipherBlockChaining_encryptAESCrypt() { return _cipherBlockChaining_encryptAESCrypt; }
|
||||
static address cipherBlockChaining_decryptAESCrypt() { return _cipherBlockChaining_decryptAESCrypt; }
|
||||
static address counterMode_AESCrypt() { return _counterMode_AESCrypt; }
|
||||
static address ghash_processBlocks() { return _ghash_processBlocks; }
|
||||
static address counterMode_AESCrypt() { return _counterMode_AESCrypt; }
|
||||
static address ghash_processBlocks() { return _ghash_processBlocks; }
|
||||
|
||||
static address sha1_implCompress() { return _sha1_implCompress; }
|
||||
static address sha1_implCompressMB() { return _sha1_implCompressMB; }
|
||||
@ -366,9 +366,9 @@ class StubRoutines: AllStatic {
|
||||
static address updateBytesCRC32C() { return _updateBytesCRC32C; }
|
||||
static address updateBytesAdler32() { return _updateBytesAdler32; }
|
||||
|
||||
static address multiplyToLen() {return _multiplyToLen; }
|
||||
static address squareToLen() {return _squareToLen; }
|
||||
static address mulAdd() {return _mulAdd; }
|
||||
static address multiplyToLen() { return _multiplyToLen; }
|
||||
static address squareToLen() { return _squareToLen; }
|
||||
static address mulAdd() { return _mulAdd; }
|
||||
static address montgomeryMultiply() { return _montgomeryMultiply; }
|
||||
static address montgomerySquare() { return _montgomerySquare; }
|
||||
|
||||
@ -376,7 +376,7 @@ class StubRoutines: AllStatic {
|
||||
|
||||
static address dexp() { return _dexp; }
|
||||
static address dlog() { return _dlog; }
|
||||
static address dlog10() { return _dlog10; }
|
||||
static address dlog10() { return _dlog10; }
|
||||
static address dpow() { return _dpow; }
|
||||
static address dsin() { return _dsin; }
|
||||
static address dcos() { return _dcos; }
|
||||
@ -387,7 +387,7 @@ class StubRoutines: AllStatic {
|
||||
|
||||
static address select_fill_function(BasicType t, bool aligned, const char* &name);
|
||||
|
||||
static address zero_aligned_words() { return _zero_aligned_words; }
|
||||
static address zero_aligned_words() { return _zero_aligned_words; }
|
||||
|
||||
static double intrinsic_log10(double d) {
|
||||
assert(_intrinsic_log10 != NULL, "must be defined");
|
||||
|
Loading…
x
Reference in New Issue
Block a user