mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-22 03:54:33 +02:00
Merge
This commit is contained in:
commit
fcc8abec1e
7 changed files with 479 additions and 233 deletions
|
@ -716,6 +716,8 @@ class Assembler : public AbstractAssembler {
|
|||
casa_op3 = 0x3c,
|
||||
casxa_op3 = 0x3e,
|
||||
|
||||
mftoi_op3 = 0x36,
|
||||
|
||||
alt_bit_op3 = 0x10,
|
||||
cc_bit_op3 = 0x10
|
||||
};
|
||||
|
@ -750,7 +752,13 @@ class Assembler : public AbstractAssembler {
|
|||
fitod_opf = 0xc8,
|
||||
fstod_opf = 0xc9,
|
||||
fstoi_opf = 0xd1,
|
||||
fdtoi_opf = 0xd2
|
||||
fdtoi_opf = 0xd2,
|
||||
|
||||
mdtox_opf = 0x110,
|
||||
mstouw_opf = 0x111,
|
||||
mstosw_opf = 0x113,
|
||||
mxtod_opf = 0x118,
|
||||
mwtos_opf = 0x119
|
||||
};
|
||||
|
||||
enum RCondition { rc_z = 1, rc_lez = 2, rc_lz = 3, rc_nz = 5, rc_gz = 6, rc_gez = 7 };
|
||||
|
@ -1061,6 +1069,9 @@ class Assembler : public AbstractAssembler {
|
|||
return x & ((1 << 10) - 1);
|
||||
}
|
||||
|
||||
// instruction only in VIS3
|
||||
static void vis3_only() { assert( VM_Version::has_vis3(), "This instruction only works on SPARC with VIS3"); }
|
||||
|
||||
// instruction only in v9
|
||||
static void v9_only() { assert( VM_Version::v9_instructions_work(), "This instruction only works on SPARC V9"); }
|
||||
|
||||
|
@ -1247,8 +1258,8 @@ public:
|
|||
|
||||
// pp 159
|
||||
|
||||
void ftox( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { v9_only(); emit_long( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0x80 + w) | fs2(s, w)); }
|
||||
void ftoi( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { emit_long( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0xd0 + w) | fs2(s, w)); }
|
||||
void ftox( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { v9_only(); emit_long( op(arith_op) | fd(d, FloatRegisterImpl::D) | op3(fpop1_op3) | opf(0x80 + w) | fs2(s, w)); }
|
||||
void ftoi( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { emit_long( op(arith_op) | fd(d, FloatRegisterImpl::S) | op3(fpop1_op3) | opf(0xd0 + w) | fs2(s, w)); }
|
||||
|
||||
// pp 160
|
||||
|
||||
|
@ -1256,8 +1267,8 @@ public:
|
|||
|
||||
// pp 161
|
||||
|
||||
void fxtof( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { v9_only(); emit_long( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0x80 + w*4) | fs2(s, w)); }
|
||||
void fitof( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { emit_long( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0xc0 + w*4) | fs2(s, w)); }
|
||||
void fxtof( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { v9_only(); emit_long( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0x80 + w*4) | fs2(s, FloatRegisterImpl::D)); }
|
||||
void fitof( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { emit_long( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0xc0 + w*4) | fs2(s, FloatRegisterImpl::S)); }
|
||||
|
||||
// pp 162
|
||||
|
||||
|
@ -1709,6 +1720,19 @@ public:
|
|||
inline void wrasi( Register d) { v9_only(); emit_long( op(arith_op) | rs1(d) | op3(wrreg_op3) | u_field(3, 29, 25)); }
|
||||
inline void wrfprs( Register d) { v9_only(); emit_long( op(arith_op) | rs1(d) | op3(wrreg_op3) | u_field(6, 29, 25)); }
|
||||
|
||||
|
||||
// VIS3 instructions
|
||||
|
||||
void movstosw( FloatRegister s, Register d ) { vis3_only(); emit_long( op(arith_op) | rd(d) | op3(mftoi_op3) | opf(mstosw_opf) | fs2(s, FloatRegisterImpl::S)); }
|
||||
void movstouw( FloatRegister s, Register d ) { vis3_only(); emit_long( op(arith_op) | rd(d) | op3(mftoi_op3) | opf(mstouw_opf) | fs2(s, FloatRegisterImpl::S)); }
|
||||
void movdtox( FloatRegister s, Register d ) { vis3_only(); emit_long( op(arith_op) | rd(d) | op3(mftoi_op3) | opf(mdtox_opf) | fs2(s, FloatRegisterImpl::D)); }
|
||||
|
||||
void movwtos( Register s, FloatRegister d ) { vis3_only(); emit_long( op(arith_op) | fd(d, FloatRegisterImpl::S) | op3(mftoi_op3) | opf(mwtos_opf) | rs2(s)); }
|
||||
void movxtod( Register s, FloatRegister d ) { vis3_only(); emit_long( op(arith_op) | fd(d, FloatRegisterImpl::D) | op3(mftoi_op3) | opf(mxtod_opf) | rs2(s)); }
|
||||
|
||||
|
||||
|
||||
|
||||
// For a given register condition, return the appropriate condition code
|
||||
// Condition (the one you would use to get the same effect after "tst" on
|
||||
// the target register.)
|
||||
|
|
|
@ -425,7 +425,7 @@ reg_class dflt_reg(R_F0, R_F1, R_F2, R_F3, R_F4, R_F5, R_F6, R_F7, R_F8, R_F9, R
|
|||
// but they are used with the "Op_RegD" type, and always occur in even/odd pairs.
|
||||
// This class is usable for mis-aligned loads as happen in I2C adapters.
|
||||
reg_class dflt_low_reg(R_F0, R_F1, R_F2, R_F3, R_F4, R_F5, R_F6, R_F7, R_F8, R_F9, R_F10,R_F11,R_F12,R_F13,R_F14,R_F15,
|
||||
R_F16,R_F17,R_F18,R_F19,R_F20,R_F21,R_F22,R_F23,R_F24,R_F25,R_F26,R_F27,R_F28,R_F29,R_F30,R_F31 );
|
||||
R_F16,R_F17,R_F18,R_F19,R_F20,R_F21,R_F22,R_F23,R_F24,R_F25,R_F26,R_F27,R_F28,R_F29);
|
||||
%}
|
||||
|
||||
//----------DEFINITION BLOCK---------------------------------------------------
|
||||
|
@ -1326,17 +1326,17 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf,
|
|||
|
||||
// --------------------------------------
|
||||
// Check for float->int copy; requires a trip through memory
|
||||
if( src_first_rc == rc_float && dst_first_rc == rc_int ) {
|
||||
if (src_first_rc == rc_float && dst_first_rc == rc_int && UseVIS < 3) {
|
||||
int offset = frame::register_save_words*wordSize;
|
||||
if( cbuf ) {
|
||||
if (cbuf) {
|
||||
emit3_simm13( *cbuf, Assembler::arith_op, R_SP_enc, Assembler::sub_op3, R_SP_enc, 16 );
|
||||
impl_helper(this,cbuf,ra_,do_size,false,offset,src_first,Assembler::stf_op3 ,"STF ",size, st);
|
||||
impl_helper(this,cbuf,ra_,do_size,true ,offset,dst_first,Assembler::lduw_op3,"LDUW",size, st);
|
||||
emit3_simm13( *cbuf, Assembler::arith_op, R_SP_enc, Assembler::add_op3, R_SP_enc, 16 );
|
||||
}
|
||||
#ifndef PRODUCT
|
||||
else if( !do_size ) {
|
||||
if( size != 0 ) st->print("\n\t");
|
||||
else if (!do_size) {
|
||||
if (size != 0) st->print("\n\t");
|
||||
st->print( "SUB R_SP,16,R_SP\n");
|
||||
impl_helper(this,cbuf,ra_,do_size,false,offset,src_first,Assembler::stf_op3 ,"STF ",size, st);
|
||||
impl_helper(this,cbuf,ra_,do_size,true ,offset,dst_first,Assembler::lduw_op3,"LDUW",size, st);
|
||||
|
@ -1346,6 +1346,21 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf,
|
|||
size += 16;
|
||||
}
|
||||
|
||||
// Check for float->int copy on T4
|
||||
if (src_first_rc == rc_float && dst_first_rc == rc_int && UseVIS >= 3) {
|
||||
// Further check for aligned-adjacent pair, so we can use a double move
|
||||
if ((src_first&1)==0 && src_first+1 == src_second && (dst_first&1)==0 && dst_first+1 == dst_second)
|
||||
return impl_mov_helper(cbuf,do_size,src_first,dst_first,Assembler::mftoi_op3,Assembler::mdtox_opf,"MOVDTOX",size, st);
|
||||
size = impl_mov_helper(cbuf,do_size,src_first,dst_first,Assembler::mftoi_op3,Assembler::mstouw_opf,"MOVSTOUW",size, st);
|
||||
}
|
||||
// Check for int->float copy on T4
|
||||
if (src_first_rc == rc_int && dst_first_rc == rc_float && UseVIS >= 3) {
|
||||
// Further check for aligned-adjacent pair, so we can use a double move
|
||||
if ((src_first&1)==0 && src_first+1 == src_second && (dst_first&1)==0 && dst_first+1 == dst_second)
|
||||
return impl_mov_helper(cbuf,do_size,src_first,dst_first,Assembler::mftoi_op3,Assembler::mxtod_opf,"MOVXTOD",size, st);
|
||||
size = impl_mov_helper(cbuf,do_size,src_first,dst_first,Assembler::mftoi_op3,Assembler::mwtos_opf,"MOVWTOS",size, st);
|
||||
}
|
||||
|
||||
// --------------------------------------
|
||||
// In the 32-bit 1-reg-longs build ONLY, I see mis-aligned long destinations.
|
||||
// In such cases, I have to do the big-endian swap. For aligned targets, the
|
||||
|
@ -8164,215 +8179,58 @@ instruct cadd_cmpLTMask( iRegI p, iRegI q, iRegI y, iRegI tmp, flagsReg ccr ) %{
|
|||
ins_pipe( cadd_cmpltmask );
|
||||
%}
|
||||
|
||||
//----------Arithmetic Conversion Instructions---------------------------------
|
||||
// The conversions operations are all Alpha sorted. Please keep it that way!
|
||||
|
||||
instruct convD2F_reg(regF dst, regD src) %{
|
||||
match(Set dst (ConvD2F src));
|
||||
size(4);
|
||||
format %{ "FDTOS $src,$dst" %}
|
||||
opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fdtos_opf);
|
||||
ins_encode(form3_opf_rs2D_rdF(src, dst));
|
||||
ins_pipe(fcvtD2F);
|
||||
%}
|
||||
//-----------------------------------------------------------------
|
||||
// Direct raw moves between float and general registers using VIS3.
|
||||
|
||||
// ins_pipe(faddF_reg);
|
||||
instruct MoveF2I_reg_reg(iRegI dst, regF src) %{
|
||||
predicate(UseVIS >= 3);
|
||||
match(Set dst (MoveF2I src));
|
||||
|
||||
// Convert a double to an int in a float register.
|
||||
// If the double is a NAN, stuff a zero in instead.
|
||||
instruct convD2I_helper(regF dst, regD src, flagsRegF0 fcc0) %{
|
||||
effect(DEF dst, USE src, KILL fcc0);
|
||||
format %{ "FCMPd fcc0,$src,$src\t! check for NAN\n\t"
|
||||
"FBO,pt fcc0,skip\t! branch on ordered, predict taken\n\t"
|
||||
"FDTOI $src,$dst\t! convert in delay slot\n\t"
|
||||
"FITOS $dst,$dst\t! change NaN/max-int to valid float\n\t"
|
||||
"FSUBs $dst,$dst,$dst\t! cleared only if nan\n"
|
||||
"skip:" %}
|
||||
ins_encode(form_d2i_helper(src,dst));
|
||||
ins_pipe(fcvtD2I);
|
||||
%}
|
||||
|
||||
instruct convD2I_reg(stackSlotI dst, regD src) %{
|
||||
match(Set dst (ConvD2I src));
|
||||
ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST);
|
||||
expand %{
|
||||
regF tmp;
|
||||
convD2I_helper(tmp, src);
|
||||
regF_to_stkI(dst, tmp);
|
||||
format %{ "MOVSTOUW $src,$dst\t! MoveF2I" %}
|
||||
ins_encode %{
|
||||
__ movstouw($src$$FloatRegister, $dst$$Register);
|
||||
%}
|
||||
%}
|
||||
|
||||
// Convert a double to a long in a double register.
|
||||
// If the double is a NAN, stuff a zero in instead.
|
||||
instruct convD2L_helper(regD dst, regD src, flagsRegF0 fcc0) %{
|
||||
effect(DEF dst, USE src, KILL fcc0);
|
||||
format %{ "FCMPd fcc0,$src,$src\t! check for NAN\n\t"
|
||||
"FBO,pt fcc0,skip\t! branch on ordered, predict taken\n\t"
|
||||
"FDTOX $src,$dst\t! convert in delay slot\n\t"
|
||||
"FXTOD $dst,$dst\t! change NaN/max-long to valid double\n\t"
|
||||
"FSUBd $dst,$dst,$dst\t! cleared only if nan\n"
|
||||
"skip:" %}
|
||||
ins_encode(form_d2l_helper(src,dst));
|
||||
ins_pipe(fcvtD2L);
|
||||
%}
|
||||
|
||||
|
||||
// Double to Long conversion
|
||||
instruct convD2L_reg(stackSlotL dst, regD src) %{
|
||||
match(Set dst (ConvD2L src));
|
||||
ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST);
|
||||
expand %{
|
||||
regD tmp;
|
||||
convD2L_helper(tmp, src);
|
||||
regD_to_stkL(dst, tmp);
|
||||
%}
|
||||
%}
|
||||
|
||||
|
||||
instruct convF2D_reg(regD dst, regF src) %{
|
||||
match(Set dst (ConvF2D src));
|
||||
format %{ "FSTOD $src,$dst" %}
|
||||
opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fstod_opf);
|
||||
ins_encode(form3_opf_rs2F_rdD(src, dst));
|
||||
ins_pipe(fcvtF2D);
|
||||
%}
|
||||
|
||||
|
||||
instruct convF2I_helper(regF dst, regF src, flagsRegF0 fcc0) %{
|
||||
effect(DEF dst, USE src, KILL fcc0);
|
||||
format %{ "FCMPs fcc0,$src,$src\t! check for NAN\n\t"
|
||||
"FBO,pt fcc0,skip\t! branch on ordered, predict taken\n\t"
|
||||
"FSTOI $src,$dst\t! convert in delay slot\n\t"
|
||||
"FITOS $dst,$dst\t! change NaN/max-int to valid float\n\t"
|
||||
"FSUBs $dst,$dst,$dst\t! cleared only if nan\n"
|
||||
"skip:" %}
|
||||
ins_encode(form_f2i_helper(src,dst));
|
||||
ins_pipe(fcvtF2I);
|
||||
%}
|
||||
|
||||
instruct convF2I_reg(stackSlotI dst, regF src) %{
|
||||
match(Set dst (ConvF2I src));
|
||||
ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST);
|
||||
expand %{
|
||||
regF tmp;
|
||||
convF2I_helper(tmp, src);
|
||||
regF_to_stkI(dst, tmp);
|
||||
%}
|
||||
%}
|
||||
|
||||
|
||||
instruct convF2L_helper(regD dst, regF src, flagsRegF0 fcc0) %{
|
||||
effect(DEF dst, USE src, KILL fcc0);
|
||||
format %{ "FCMPs fcc0,$src,$src\t! check for NAN\n\t"
|
||||
"FBO,pt fcc0,skip\t! branch on ordered, predict taken\n\t"
|
||||
"FSTOX $src,$dst\t! convert in delay slot\n\t"
|
||||
"FXTOD $dst,$dst\t! change NaN/max-long to valid double\n\t"
|
||||
"FSUBd $dst,$dst,$dst\t! cleared only if nan\n"
|
||||
"skip:" %}
|
||||
ins_encode(form_f2l_helper(src,dst));
|
||||
ins_pipe(fcvtF2L);
|
||||
%}
|
||||
|
||||
// Float to Long conversion
|
||||
instruct convF2L_reg(stackSlotL dst, regF src) %{
|
||||
match(Set dst (ConvF2L src));
|
||||
ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST);
|
||||
expand %{
|
||||
regD tmp;
|
||||
convF2L_helper(tmp, src);
|
||||
regD_to_stkL(dst, tmp);
|
||||
%}
|
||||
%}
|
||||
|
||||
|
||||
instruct convI2D_helper(regD dst, regF tmp) %{
|
||||
effect(USE tmp, DEF dst);
|
||||
format %{ "FITOD $tmp,$dst" %}
|
||||
opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fitod_opf);
|
||||
ins_encode(form3_opf_rs2F_rdD(tmp, dst));
|
||||
ins_pipe(fcvtI2D);
|
||||
%}
|
||||
|
||||
instruct convI2D_reg(stackSlotI src, regD dst) %{
|
||||
match(Set dst (ConvI2D src));
|
||||
ins_cost(DEFAULT_COST + MEMORY_REF_COST);
|
||||
expand %{
|
||||
regF tmp;
|
||||
stkI_to_regF( tmp, src);
|
||||
convI2D_helper( dst, tmp);
|
||||
%}
|
||||
%}
|
||||
|
||||
instruct convI2D_mem( regD_low dst, memory mem ) %{
|
||||
match(Set dst (ConvI2D (LoadI mem)));
|
||||
ins_cost(DEFAULT_COST + MEMORY_REF_COST);
|
||||
size(8);
|
||||
format %{ "LDF $mem,$dst\n\t"
|
||||
"FITOD $dst,$dst" %}
|
||||
opcode(Assembler::ldf_op3, Assembler::fitod_opf);
|
||||
ins_encode(simple_form3_mem_reg( mem, dst ), form3_convI2F(dst, dst));
|
||||
ins_pipe(floadF_mem);
|
||||
%}
|
||||
|
||||
|
||||
instruct convI2F_helper(regF dst, regF tmp) %{
|
||||
effect(DEF dst, USE tmp);
|
||||
format %{ "FITOS $tmp,$dst" %}
|
||||
opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fitos_opf);
|
||||
ins_encode(form3_opf_rs2F_rdF(tmp, dst));
|
||||
ins_pipe(fcvtI2F);
|
||||
%}
|
||||
|
||||
instruct convI2F_reg( regF dst, stackSlotI src ) %{
|
||||
match(Set dst (ConvI2F src));
|
||||
ins_cost(DEFAULT_COST + MEMORY_REF_COST);
|
||||
expand %{
|
||||
regF tmp;
|
||||
stkI_to_regF(tmp,src);
|
||||
convI2F_helper(dst, tmp);
|
||||
%}
|
||||
%}
|
||||
|
||||
instruct convI2F_mem( regF dst, memory mem ) %{
|
||||
match(Set dst (ConvI2F (LoadI mem)));
|
||||
ins_cost(DEFAULT_COST + MEMORY_REF_COST);
|
||||
size(8);
|
||||
format %{ "LDF $mem,$dst\n\t"
|
||||
"FITOS $dst,$dst" %}
|
||||
opcode(Assembler::ldf_op3, Assembler::fitos_opf);
|
||||
ins_encode(simple_form3_mem_reg( mem, dst ), form3_convI2F(dst, dst));
|
||||
ins_pipe(floadF_mem);
|
||||
%}
|
||||
|
||||
|
||||
instruct convI2L_reg(iRegL dst, iRegI src) %{
|
||||
match(Set dst (ConvI2L src));
|
||||
size(4);
|
||||
format %{ "SRA $src,0,$dst\t! int->long" %}
|
||||
opcode(Assembler::sra_op3, Assembler::arith_op);
|
||||
ins_encode( form3_rs1_rs2_rd( src, R_G0, dst ) );
|
||||
ins_pipe(ialu_reg_reg);
|
||||
%}
|
||||
|
||||
// Zero-extend convert int to long
|
||||
instruct convI2L_reg_zex(iRegL dst, iRegI src, immL_32bits mask ) %{
|
||||
match(Set dst (AndL (ConvI2L src) mask) );
|
||||
size(4);
|
||||
format %{ "SRL $src,0,$dst\t! zero-extend int to long" %}
|
||||
opcode(Assembler::srl_op3, Assembler::arith_op);
|
||||
ins_encode( form3_rs1_rs2_rd( src, R_G0, dst ) );
|
||||
instruct MoveI2F_reg_reg(regF dst, iRegI src) %{
|
||||
predicate(UseVIS >= 3);
|
||||
match(Set dst (MoveI2F src));
|
||||
|
||||
format %{ "MOVWTOS $src,$dst\t! MoveI2F" %}
|
||||
ins_encode %{
|
||||
__ movwtos($src$$Register, $dst$$FloatRegister);
|
||||
%}
|
||||
ins_pipe(ialu_reg_reg);
|
||||
%}
|
||||
|
||||
// Zero-extend long
|
||||
instruct zerox_long(iRegL dst, iRegL src, immL_32bits mask ) %{
|
||||
match(Set dst (AndL src mask) );
|
||||
size(4);
|
||||
format %{ "SRL $src,0,$dst\t! zero-extend long" %}
|
||||
opcode(Assembler::srl_op3, Assembler::arith_op);
|
||||
ins_encode( form3_rs1_rs2_rd( src, R_G0, dst ) );
|
||||
instruct MoveD2L_reg_reg(iRegL dst, regD src) %{
|
||||
predicate(UseVIS >= 3);
|
||||
match(Set dst (MoveD2L src));
|
||||
|
||||
format %{ "MOVDTOX $src,$dst\t! MoveD2L" %}
|
||||
ins_encode %{
|
||||
__ movdtox(as_DoubleFloatRegister($src$$reg), $dst$$Register);
|
||||
%}
|
||||
ins_pipe(ialu_reg_reg);
|
||||
%}
|
||||
|
||||
instruct MoveL2D_reg_reg(regD dst, iRegL src) %{
|
||||
predicate(UseVIS >= 3);
|
||||
match(Set dst (MoveL2D src));
|
||||
|
||||
format %{ "MOVXTOD $src,$dst\t! MoveL2D" %}
|
||||
ins_encode %{
|
||||
__ movxtod($src$$Register, as_DoubleFloatRegister($dst$$reg));
|
||||
%}
|
||||
ins_pipe(ialu_reg_reg);
|
||||
%}
|
||||
|
||||
|
||||
// Raw moves between float and general registers using stack.
|
||||
|
||||
instruct MoveF2I_stack_reg(iRegI dst, stackSlotF src) %{
|
||||
match(Set dst (MoveF2I src));
|
||||
effect(DEF dst, USE src);
|
||||
|
@ -8427,7 +8285,7 @@ instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{
|
|||
ins_cost(MEMORY_REF_COST);
|
||||
|
||||
size(4);
|
||||
format %{ "STF $src,$dst\t!MoveF2I" %}
|
||||
format %{ "STF $src,$dst\t! MoveF2I" %}
|
||||
opcode(Assembler::stf_op3);
|
||||
ins_encode(simple_form3_mem_reg(dst, src));
|
||||
ins_pipe(fstoreF_stk_reg);
|
||||
|
@ -8439,7 +8297,7 @@ instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{
|
|||
ins_cost(MEMORY_REF_COST);
|
||||
|
||||
size(4);
|
||||
format %{ "STW $src,$dst\t!MoveI2F" %}
|
||||
format %{ "STW $src,$dst\t! MoveI2F" %}
|
||||
opcode(Assembler::stw_op3);
|
||||
ins_encode(simple_form3_mem_reg( dst, src ) );
|
||||
ins_pipe(istore_mem_reg);
|
||||
|
@ -8451,7 +8309,7 @@ instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{
|
|||
ins_cost(MEMORY_REF_COST);
|
||||
|
||||
size(4);
|
||||
format %{ "STDF $src,$dst\t!MoveD2L" %}
|
||||
format %{ "STDF $src,$dst\t! MoveD2L" %}
|
||||
opcode(Assembler::stdf_op3);
|
||||
ins_encode(simple_form3_mem_reg(dst, src));
|
||||
ins_pipe(fstoreD_stk_reg);
|
||||
|
@ -8463,13 +8321,290 @@ instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{
|
|||
ins_cost(MEMORY_REF_COST);
|
||||
|
||||
size(4);
|
||||
format %{ "STX $src,$dst\t!MoveL2D" %}
|
||||
format %{ "STX $src,$dst\t! MoveL2D" %}
|
||||
opcode(Assembler::stx_op3);
|
||||
ins_encode(simple_form3_mem_reg( dst, src ) );
|
||||
ins_pipe(istore_mem_reg);
|
||||
%}
|
||||
|
||||
|
||||
//----------Arithmetic Conversion Instructions---------------------------------
|
||||
// The conversions operations are all Alpha sorted. Please keep it that way!
|
||||
|
||||
instruct convD2F_reg(regF dst, regD src) %{
|
||||
match(Set dst (ConvD2F src));
|
||||
size(4);
|
||||
format %{ "FDTOS $src,$dst" %}
|
||||
opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fdtos_opf);
|
||||
ins_encode(form3_opf_rs2D_rdF(src, dst));
|
||||
ins_pipe(fcvtD2F);
|
||||
%}
|
||||
|
||||
|
||||
// Convert a double to an int in a float register.
|
||||
// If the double is a NAN, stuff a zero in instead.
|
||||
instruct convD2I_helper(regF dst, regD src, flagsRegF0 fcc0) %{
|
||||
effect(DEF dst, USE src, KILL fcc0);
|
||||
format %{ "FCMPd fcc0,$src,$src\t! check for NAN\n\t"
|
||||
"FBO,pt fcc0,skip\t! branch on ordered, predict taken\n\t"
|
||||
"FDTOI $src,$dst\t! convert in delay slot\n\t"
|
||||
"FITOS $dst,$dst\t! change NaN/max-int to valid float\n\t"
|
||||
"FSUBs $dst,$dst,$dst\t! cleared only if nan\n"
|
||||
"skip:" %}
|
||||
ins_encode(form_d2i_helper(src,dst));
|
||||
ins_pipe(fcvtD2I);
|
||||
%}
|
||||
|
||||
instruct convD2I_stk(stackSlotI dst, regD src) %{
|
||||
match(Set dst (ConvD2I src));
|
||||
ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST);
|
||||
expand %{
|
||||
regF tmp;
|
||||
convD2I_helper(tmp, src);
|
||||
regF_to_stkI(dst, tmp);
|
||||
%}
|
||||
%}
|
||||
|
||||
instruct convD2I_reg(iRegI dst, regD src) %{
|
||||
predicate(UseVIS >= 3);
|
||||
match(Set dst (ConvD2I src));
|
||||
ins_cost(DEFAULT_COST*2 + BRANCH_COST);
|
||||
expand %{
|
||||
regF tmp;
|
||||
convD2I_helper(tmp, src);
|
||||
MoveF2I_reg_reg(dst, tmp);
|
||||
%}
|
||||
%}
|
||||
|
||||
|
||||
// Convert a double to a long in a double register.
|
||||
// If the double is a NAN, stuff a zero in instead.
|
||||
instruct convD2L_helper(regD dst, regD src, flagsRegF0 fcc0) %{
|
||||
effect(DEF dst, USE src, KILL fcc0);
|
||||
format %{ "FCMPd fcc0,$src,$src\t! check for NAN\n\t"
|
||||
"FBO,pt fcc0,skip\t! branch on ordered, predict taken\n\t"
|
||||
"FDTOX $src,$dst\t! convert in delay slot\n\t"
|
||||
"FXTOD $dst,$dst\t! change NaN/max-long to valid double\n\t"
|
||||
"FSUBd $dst,$dst,$dst\t! cleared only if nan\n"
|
||||
"skip:" %}
|
||||
ins_encode(form_d2l_helper(src,dst));
|
||||
ins_pipe(fcvtD2L);
|
||||
%}
|
||||
|
||||
instruct convD2L_stk(stackSlotL dst, regD src) %{
|
||||
match(Set dst (ConvD2L src));
|
||||
ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST);
|
||||
expand %{
|
||||
regD tmp;
|
||||
convD2L_helper(tmp, src);
|
||||
regD_to_stkL(dst, tmp);
|
||||
%}
|
||||
%}
|
||||
|
||||
instruct convD2L_reg(iRegL dst, regD src) %{
|
||||
predicate(UseVIS >= 3);
|
||||
match(Set dst (ConvD2L src));
|
||||
ins_cost(DEFAULT_COST*2 + BRANCH_COST);
|
||||
expand %{
|
||||
regD tmp;
|
||||
convD2L_helper(tmp, src);
|
||||
MoveD2L_reg_reg(dst, tmp);
|
||||
%}
|
||||
%}
|
||||
|
||||
|
||||
instruct convF2D_reg(regD dst, regF src) %{
|
||||
match(Set dst (ConvF2D src));
|
||||
format %{ "FSTOD $src,$dst" %}
|
||||
opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fstod_opf);
|
||||
ins_encode(form3_opf_rs2F_rdD(src, dst));
|
||||
ins_pipe(fcvtF2D);
|
||||
%}
|
||||
|
||||
|
||||
// Convert a float to an int in a float register.
|
||||
// If the float is a NAN, stuff a zero in instead.
|
||||
instruct convF2I_helper(regF dst, regF src, flagsRegF0 fcc0) %{
|
||||
effect(DEF dst, USE src, KILL fcc0);
|
||||
format %{ "FCMPs fcc0,$src,$src\t! check for NAN\n\t"
|
||||
"FBO,pt fcc0,skip\t! branch on ordered, predict taken\n\t"
|
||||
"FSTOI $src,$dst\t! convert in delay slot\n\t"
|
||||
"FITOS $dst,$dst\t! change NaN/max-int to valid float\n\t"
|
||||
"FSUBs $dst,$dst,$dst\t! cleared only if nan\n"
|
||||
"skip:" %}
|
||||
ins_encode(form_f2i_helper(src,dst));
|
||||
ins_pipe(fcvtF2I);
|
||||
%}
|
||||
|
||||
instruct convF2I_stk(stackSlotI dst, regF src) %{
|
||||
match(Set dst (ConvF2I src));
|
||||
ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST);
|
||||
expand %{
|
||||
regF tmp;
|
||||
convF2I_helper(tmp, src);
|
||||
regF_to_stkI(dst, tmp);
|
||||
%}
|
||||
%}
|
||||
|
||||
instruct convF2I_reg(iRegI dst, regF src) %{
|
||||
predicate(UseVIS >= 3);
|
||||
match(Set dst (ConvF2I src));
|
||||
ins_cost(DEFAULT_COST*2 + BRANCH_COST);
|
||||
expand %{
|
||||
regF tmp;
|
||||
convF2I_helper(tmp, src);
|
||||
MoveF2I_reg_reg(dst, tmp);
|
||||
%}
|
||||
%}
|
||||
|
||||
|
||||
// Convert a float to a long in a float register.
|
||||
// If the float is a NAN, stuff a zero in instead.
|
||||
instruct convF2L_helper(regD dst, regF src, flagsRegF0 fcc0) %{
|
||||
effect(DEF dst, USE src, KILL fcc0);
|
||||
format %{ "FCMPs fcc0,$src,$src\t! check for NAN\n\t"
|
||||
"FBO,pt fcc0,skip\t! branch on ordered, predict taken\n\t"
|
||||
"FSTOX $src,$dst\t! convert in delay slot\n\t"
|
||||
"FXTOD $dst,$dst\t! change NaN/max-long to valid double\n\t"
|
||||
"FSUBd $dst,$dst,$dst\t! cleared only if nan\n"
|
||||
"skip:" %}
|
||||
ins_encode(form_f2l_helper(src,dst));
|
||||
ins_pipe(fcvtF2L);
|
||||
%}
|
||||
|
||||
instruct convF2L_stk(stackSlotL dst, regF src) %{
|
||||
match(Set dst (ConvF2L src));
|
||||
ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST);
|
||||
expand %{
|
||||
regD tmp;
|
||||
convF2L_helper(tmp, src);
|
||||
regD_to_stkL(dst, tmp);
|
||||
%}
|
||||
%}
|
||||
|
||||
instruct convF2L_reg(iRegL dst, regF src) %{
|
||||
predicate(UseVIS >= 3);
|
||||
match(Set dst (ConvF2L src));
|
||||
ins_cost(DEFAULT_COST*2 + BRANCH_COST);
|
||||
expand %{
|
||||
regD tmp;
|
||||
convF2L_helper(tmp, src);
|
||||
MoveD2L_reg_reg(dst, tmp);
|
||||
%}
|
||||
%}
|
||||
|
||||
|
||||
instruct convI2D_helper(regD dst, regF tmp) %{
|
||||
effect(USE tmp, DEF dst);
|
||||
format %{ "FITOD $tmp,$dst" %}
|
||||
opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fitod_opf);
|
||||
ins_encode(form3_opf_rs2F_rdD(tmp, dst));
|
||||
ins_pipe(fcvtI2D);
|
||||
%}
|
||||
|
||||
instruct convI2D_stk(stackSlotI src, regD dst) %{
|
||||
match(Set dst (ConvI2D src));
|
||||
ins_cost(DEFAULT_COST + MEMORY_REF_COST);
|
||||
expand %{
|
||||
regF tmp;
|
||||
stkI_to_regF(tmp, src);
|
||||
convI2D_helper(dst, tmp);
|
||||
%}
|
||||
%}
|
||||
|
||||
instruct convI2D_reg(regD_low dst, iRegI src) %{
|
||||
predicate(UseVIS >= 3);
|
||||
match(Set dst (ConvI2D src));
|
||||
expand %{
|
||||
regF tmp;
|
||||
MoveI2F_reg_reg(tmp, src);
|
||||
convI2D_helper(dst, tmp);
|
||||
%}
|
||||
%}
|
||||
|
||||
instruct convI2D_mem(regD_low dst, memory mem) %{
|
||||
match(Set dst (ConvI2D (LoadI mem)));
|
||||
ins_cost(DEFAULT_COST + MEMORY_REF_COST);
|
||||
size(8);
|
||||
format %{ "LDF $mem,$dst\n\t"
|
||||
"FITOD $dst,$dst" %}
|
||||
opcode(Assembler::ldf_op3, Assembler::fitod_opf);
|
||||
ins_encode(simple_form3_mem_reg( mem, dst ), form3_convI2F(dst, dst));
|
||||
ins_pipe(floadF_mem);
|
||||
%}
|
||||
|
||||
|
||||
instruct convI2F_helper(regF dst, regF tmp) %{
|
||||
effect(DEF dst, USE tmp);
|
||||
format %{ "FITOS $tmp,$dst" %}
|
||||
opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fitos_opf);
|
||||
ins_encode(form3_opf_rs2F_rdF(tmp, dst));
|
||||
ins_pipe(fcvtI2F);
|
||||
%}
|
||||
|
||||
instruct convI2F_stk(regF dst, stackSlotI src) %{
|
||||
match(Set dst (ConvI2F src));
|
||||
ins_cost(DEFAULT_COST + MEMORY_REF_COST);
|
||||
expand %{
|
||||
regF tmp;
|
||||
stkI_to_regF(tmp,src);
|
||||
convI2F_helper(dst, tmp);
|
||||
%}
|
||||
%}
|
||||
|
||||
instruct convI2F_reg(regF dst, iRegI src) %{
|
||||
predicate(UseVIS >= 3);
|
||||
match(Set dst (ConvI2F src));
|
||||
ins_cost(DEFAULT_COST);
|
||||
expand %{
|
||||
regF tmp;
|
||||
MoveI2F_reg_reg(tmp, src);
|
||||
convI2F_helper(dst, tmp);
|
||||
%}
|
||||
%}
|
||||
|
||||
instruct convI2F_mem( regF dst, memory mem ) %{
|
||||
match(Set dst (ConvI2F (LoadI mem)));
|
||||
ins_cost(DEFAULT_COST + MEMORY_REF_COST);
|
||||
size(8);
|
||||
format %{ "LDF $mem,$dst\n\t"
|
||||
"FITOS $dst,$dst" %}
|
||||
opcode(Assembler::ldf_op3, Assembler::fitos_opf);
|
||||
ins_encode(simple_form3_mem_reg( mem, dst ), form3_convI2F(dst, dst));
|
||||
ins_pipe(floadF_mem);
|
||||
%}
|
||||
|
||||
|
||||
instruct convI2L_reg(iRegL dst, iRegI src) %{
|
||||
match(Set dst (ConvI2L src));
|
||||
size(4);
|
||||
format %{ "SRA $src,0,$dst\t! int->long" %}
|
||||
opcode(Assembler::sra_op3, Assembler::arith_op);
|
||||
ins_encode( form3_rs1_rs2_rd( src, R_G0, dst ) );
|
||||
ins_pipe(ialu_reg_reg);
|
||||
%}
|
||||
|
||||
// Zero-extend convert int to long
|
||||
instruct convI2L_reg_zex(iRegL dst, iRegI src, immL_32bits mask ) %{
|
||||
match(Set dst (AndL (ConvI2L src) mask) );
|
||||
size(4);
|
||||
format %{ "SRL $src,0,$dst\t! zero-extend int to long" %}
|
||||
opcode(Assembler::srl_op3, Assembler::arith_op);
|
||||
ins_encode( form3_rs1_rs2_rd( src, R_G0, dst ) );
|
||||
ins_pipe(ialu_reg_reg);
|
||||
%}
|
||||
|
||||
// Zero-extend long
|
||||
instruct zerox_long(iRegL dst, iRegL src, immL_32bits mask ) %{
|
||||
match(Set dst (AndL src mask) );
|
||||
size(4);
|
||||
format %{ "SRL $src,0,$dst\t! zero-extend long" %}
|
||||
opcode(Assembler::srl_op3, Assembler::arith_op);
|
||||
ins_encode( form3_rs1_rs2_rd( src, R_G0, dst ) );
|
||||
ins_pipe(ialu_reg_reg);
|
||||
%}
|
||||
|
||||
|
||||
//-----------
|
||||
// Long to Double conversion using V8 opcodes.
|
||||
// Still useful because cheetah traps and becomes
|
||||
|
@ -8589,7 +8724,7 @@ instruct convL2D_helper(regD dst, regD tmp) %{
|
|||
ins_pipe(fcvtL2D);
|
||||
%}
|
||||
|
||||
instruct convL2D_reg_fast_fxtof(regD dst, stackSlotL src) %{
|
||||
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);
|
||||
|
@ -8600,10 +8735,15 @@ instruct convL2D_reg_fast_fxtof(regD dst, stackSlotL src) %{
|
|||
%}
|
||||
%}
|
||||
|
||||
//-----------
|
||||
// Long to Float conversion using V8 opcodes.
|
||||
// Still useful because cheetah traps and becomes
|
||||
// amazingly slow for some common numbers.
|
||||
instruct convL2D_reg(regD dst, iRegL src) %{
|
||||
predicate(UseVIS >= 3);
|
||||
match(Set dst (ConvL2D src));
|
||||
expand %{
|
||||
regD tmp;
|
||||
MoveL2D_reg_reg(tmp, src);
|
||||
convL2D_helper(dst, tmp);
|
||||
%}
|
||||
%}
|
||||
|
||||
// Long to Float conversion using fast fxtof
|
||||
instruct convL2F_helper(regF dst, regD tmp) %{
|
||||
|
@ -8615,7 +8755,7 @@ instruct convL2F_helper(regF dst, regD tmp) %{
|
|||
ins_pipe(fcvtL2F);
|
||||
%}
|
||||
|
||||
instruct convL2F_reg_fast_fxtof(regF dst, stackSlotL src) %{
|
||||
instruct convL2F_stk_fast_fxtof(regF dst, stackSlotL src) %{
|
||||
match(Set dst (ConvL2F src));
|
||||
ins_cost(DEFAULT_COST + MEMORY_REF_COST);
|
||||
expand %{
|
||||
|
@ -8624,6 +8764,18 @@ instruct convL2F_reg_fast_fxtof(regF dst, stackSlotL src) %{
|
|||
convL2F_helper(dst, tmp);
|
||||
%}
|
||||
%}
|
||||
|
||||
instruct convL2F_reg(regF dst, iRegL src) %{
|
||||
predicate(UseVIS >= 3);
|
||||
match(Set dst (ConvL2F src));
|
||||
ins_cost(DEFAULT_COST);
|
||||
expand %{
|
||||
regD tmp;
|
||||
MoveL2D_reg_reg(tmp, src);
|
||||
convL2F_helper(dst, tmp);
|
||||
%}
|
||||
%}
|
||||
|
||||
//-----------
|
||||
|
||||
instruct convL2I_reg(iRegI dst, iRegL src) %{
|
||||
|
|
|
@ -144,6 +144,18 @@ void VM_Version::initialize() {
|
|||
// buf is started with ", " or is empty
|
||||
_features_str = strdup(strlen(buf) > 2 ? buf + 2 : buf);
|
||||
|
||||
// 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);
|
||||
if (!has_vis2()) // Drop to 1 if no VIS2 support
|
||||
UseVIS = MIN2((intx)1,UseVIS);
|
||||
if (!has_vis1()) // Drop to 0 if no VIS1 support
|
||||
UseVIS = 0;
|
||||
|
||||
#ifndef PRODUCT
|
||||
if (PrintMiscellaneous && Verbose) {
|
||||
tty->print("Allocation: ");
|
||||
|
|
|
@ -417,17 +417,10 @@ void Parse::do_multianewarray() {
|
|||
|
||||
// Note: Array classes are always initialized; no is_initialized check.
|
||||
|
||||
enum { MAX_DIMENSION = 5 };
|
||||
if (ndimensions > MAX_DIMENSION || ndimensions <= 0) {
|
||||
uncommon_trap(Deoptimization::Reason_unhandled,
|
||||
Deoptimization::Action_none);
|
||||
return;
|
||||
}
|
||||
|
||||
kill_dead_locals();
|
||||
|
||||
// get the lengths from the stack (first dimension is on top)
|
||||
Node* length[MAX_DIMENSION+1];
|
||||
Node** length = NEW_RESOURCE_ARRAY(Node*, ndimensions + 1);
|
||||
length[ndimensions] = NULL; // terminating null for make_runtime_call
|
||||
int j;
|
||||
for (j = ndimensions-1; j >= 0 ; j--) length[j] = pop();
|
||||
|
@ -470,20 +463,43 @@ void Parse::do_multianewarray() {
|
|||
|
||||
address fun = NULL;
|
||||
switch (ndimensions) {
|
||||
//case 1: Actually, there is no case 1. It's handled by new_array.
|
||||
case 1: ShouldNotReachHere(); break;
|
||||
case 2: fun = OptoRuntime::multianewarray2_Java(); break;
|
||||
case 3: fun = OptoRuntime::multianewarray3_Java(); break;
|
||||
case 4: fun = OptoRuntime::multianewarray4_Java(); break;
|
||||
case 5: fun = OptoRuntime::multianewarray5_Java(); break;
|
||||
default: ShouldNotReachHere();
|
||||
};
|
||||
Node* c = NULL;
|
||||
|
||||
if (fun != NULL) {
|
||||
c = make_runtime_call(RC_NO_LEAF | RC_NO_IO,
|
||||
OptoRuntime::multianewarray_Type(ndimensions),
|
||||
fun, NULL, TypeRawPtr::BOTTOM,
|
||||
makecon(TypeKlassPtr::make(array_klass)),
|
||||
length[0], length[1], length[2],
|
||||
length[3], length[4]);
|
||||
} else {
|
||||
// Create a java array for dimension sizes
|
||||
Node* dims = NULL;
|
||||
{ PreserveReexecuteState preexecs(this);
|
||||
_sp += ndimensions;
|
||||
Node* dims_array_klass = makecon(TypeKlassPtr::make(ciArrayKlass::make(ciType::make(T_INT))));
|
||||
dims = new_array(dims_array_klass, intcon(ndimensions), 0);
|
||||
|
||||
// Fill-in it with values
|
||||
for (j = 0; j < ndimensions; j++) {
|
||||
Node *dims_elem = array_element_address(dims, intcon(j), T_INT);
|
||||
store_to_memory(control(), dims_elem, length[j], T_INT, TypeAryPtr::INTS);
|
||||
}
|
||||
}
|
||||
|
||||
c = make_runtime_call(RC_NO_LEAF | RC_NO_IO,
|
||||
OptoRuntime::multianewarrayN_Type(),
|
||||
OptoRuntime::multianewarrayN_Java(), NULL, TypeRawPtr::BOTTOM,
|
||||
makecon(TypeKlassPtr::make(array_klass)),
|
||||
dims);
|
||||
}
|
||||
|
||||
Node* c = make_runtime_call(RC_NO_LEAF | RC_NO_IO,
|
||||
OptoRuntime::multianewarray_Type(ndimensions),
|
||||
fun, NULL, TypeRawPtr::BOTTOM,
|
||||
makecon(TypeKlassPtr::make(array_klass)),
|
||||
length[0], length[1], length[2],
|
||||
length[3], length[4]);
|
||||
Node* res = _gvn.transform(new (C, 1) ProjNode(c, TypeFunc::Parms));
|
||||
|
||||
const Type* type = TypeOopPtr::make_from_klass_raw(array_klass);
|
||||
|
@ -496,7 +512,7 @@ void Parse::do_multianewarray() {
|
|||
if (ltype != NULL)
|
||||
type = type->is_aryptr()->cast_to_size(ltype);
|
||||
|
||||
// We cannot sharpen the nested sub-arrays, since the top level is mutable.
|
||||
// We cannot sharpen the nested sub-arrays, since the top level is mutable.
|
||||
|
||||
Node* cast = _gvn.transform( new (C, 2) CheckCastPPNode(control(), res, type) );
|
||||
push(cast);
|
||||
|
|
|
@ -106,6 +106,7 @@ address OptoRuntime::_multianewarray2_Java = NULL;
|
|||
address OptoRuntime::_multianewarray3_Java = NULL;
|
||||
address OptoRuntime::_multianewarray4_Java = NULL;
|
||||
address OptoRuntime::_multianewarray5_Java = NULL;
|
||||
address OptoRuntime::_multianewarrayN_Java = NULL;
|
||||
address OptoRuntime::_g1_wb_pre_Java = NULL;
|
||||
address OptoRuntime::_g1_wb_post_Java = NULL;
|
||||
address OptoRuntime::_vtable_must_compile_Java = NULL;
|
||||
|
@ -154,6 +155,7 @@ void OptoRuntime::generate(ciEnv* env) {
|
|||
gen(env, _multianewarray3_Java , multianewarray3_Type , multianewarray3_C , 0 , true , false, false);
|
||||
gen(env, _multianewarray4_Java , multianewarray4_Type , multianewarray4_C , 0 , true , false, false);
|
||||
gen(env, _multianewarray5_Java , multianewarray5_Type , multianewarray5_C , 0 , true , false, false);
|
||||
gen(env, _multianewarrayN_Java , multianewarrayN_Type , multianewarrayN_C , 0 , true , false, false);
|
||||
gen(env, _g1_wb_pre_Java , g1_wb_pre_Type , SharedRuntime::g1_wb_pre , 0 , false, false, false);
|
||||
gen(env, _g1_wb_post_Java , g1_wb_post_Type , SharedRuntime::g1_wb_post , 0 , false, false, false);
|
||||
gen(env, _complete_monitor_locking_Java , complete_monitor_enter_Type , SharedRuntime::complete_monitor_locking_C , 0 , false, false, false);
|
||||
|
@ -374,6 +376,24 @@ JRT_ENTRY(void, OptoRuntime::multianewarray5_C(klassOopDesc* elem_type, int len1
|
|||
thread->set_vm_result(obj);
|
||||
JRT_END
|
||||
|
||||
JRT_ENTRY(void, OptoRuntime::multianewarrayN_C(klassOopDesc* elem_type, arrayOopDesc* dims, JavaThread *thread))
|
||||
assert(check_compiled_frame(thread), "incorrect caller");
|
||||
assert(oop(elem_type)->is_klass(), "not a class");
|
||||
assert(oop(dims)->is_typeArray(), "not an array");
|
||||
|
||||
ResourceMark rm;
|
||||
jint len = dims->length();
|
||||
assert(len > 0, "Dimensions array should contain data");
|
||||
jint *j_dims = typeArrayOop(dims)->int_at_addr(0);
|
||||
jint *c_dims = NEW_RESOURCE_ARRAY(jint, len);
|
||||
Copy::conjoint_jints_atomic(j_dims, c_dims, len);
|
||||
|
||||
oop obj = arrayKlass::cast(elem_type)->multi_allocate(len, c_dims, THREAD);
|
||||
deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION);
|
||||
thread->set_vm_result(obj);
|
||||
JRT_END
|
||||
|
||||
|
||||
const TypeFunc *OptoRuntime::new_instance_Type() {
|
||||
// create input type (domain)
|
||||
const Type **fields = TypeTuple::fields(1);
|
||||
|
@ -454,6 +474,21 @@ const TypeFunc *OptoRuntime::multianewarray5_Type() {
|
|||
return multianewarray_Type(5);
|
||||
}
|
||||
|
||||
const TypeFunc *OptoRuntime::multianewarrayN_Type() {
|
||||
// create input type (domain)
|
||||
const Type **fields = TypeTuple::fields(2);
|
||||
fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // element klass
|
||||
fields[TypeFunc::Parms+1] = TypeInstPtr::NOTNULL; // array of dim sizes
|
||||
const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields);
|
||||
|
||||
// create result type (range)
|
||||
fields = TypeTuple::fields(1);
|
||||
fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Returned oop
|
||||
const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
|
||||
|
||||
return TypeFunc::make(domain, range);
|
||||
}
|
||||
|
||||
const TypeFunc *OptoRuntime::g1_wb_pre_Type() {
|
||||
const Type **fields = TypeTuple::fields(2);
|
||||
fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // original field value
|
||||
|
|
|
@ -118,6 +118,7 @@ class OptoRuntime : public AllStatic {
|
|||
static address _multianewarray3_Java;
|
||||
static address _multianewarray4_Java;
|
||||
static address _multianewarray5_Java;
|
||||
static address _multianewarrayN_Java;
|
||||
static address _g1_wb_pre_Java;
|
||||
static address _g1_wb_post_Java;
|
||||
static address _vtable_must_compile_Java;
|
||||
|
@ -153,6 +154,7 @@ class OptoRuntime : public AllStatic {
|
|||
static void multianewarray3_C(klassOopDesc* klass, int len1, int len2, int len3, JavaThread *thread);
|
||||
static void multianewarray4_C(klassOopDesc* klass, int len1, int len2, int len3, int len4, JavaThread *thread);
|
||||
static void multianewarray5_C(klassOopDesc* klass, int len1, int len2, int len3, int len4, int len5, JavaThread *thread);
|
||||
static void multianewarrayN_C(klassOopDesc* klass, arrayOopDesc* dims, JavaThread *thread);
|
||||
static void g1_wb_pre_C(oopDesc* orig, JavaThread* thread);
|
||||
static void g1_wb_post_C(void* card_addr, JavaThread* thread);
|
||||
|
||||
|
@ -210,6 +212,7 @@ private:
|
|||
static address multianewarray3_Java() { return _multianewarray3_Java; }
|
||||
static address multianewarray4_Java() { return _multianewarray4_Java; }
|
||||
static address multianewarray5_Java() { return _multianewarray5_Java; }
|
||||
static address multianewarrayN_Java() { return _multianewarrayN_Java; }
|
||||
static address g1_wb_pre_Java() { return _g1_wb_pre_Java; }
|
||||
static address g1_wb_post_Java() { return _g1_wb_post_Java; }
|
||||
static address vtable_must_compile_stub() { return _vtable_must_compile_Java; }
|
||||
|
@ -249,6 +252,7 @@ private:
|
|||
static const TypeFunc* multianewarray3_Type(); // multianewarray
|
||||
static const TypeFunc* multianewarray4_Type(); // multianewarray
|
||||
static const TypeFunc* multianewarray5_Type(); // multianewarray
|
||||
static const TypeFunc* multianewarrayN_Type(); // multianewarray
|
||||
static const TypeFunc* g1_wb_pre_Type();
|
||||
static const TypeFunc* g1_wb_post_Type();
|
||||
static const TypeFunc* complete_monitor_enter_Type();
|
||||
|
|
|
@ -501,6 +501,9 @@ class CommandLineFlags {
|
|||
product(intx, UseSSE, 99, \
|
||||
"Highest supported SSE instructions set on x86/x64") \
|
||||
\
|
||||
product(intx, UseVIS, 99, \
|
||||
"Highest supported VIS instructions set on Sparc") \
|
||||
\
|
||||
product(uintx, LargePageSizeInBytes, 0, \
|
||||
"Large page size (0 to let VM choose the page size") \
|
||||
\
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue