src/cpu/x86/vm/x86_32.ad
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File
7116452 Cdiff src/cpu/x86/vm/x86_32.ad
src/cpu/x86/vm/x86_32.ad
Print this page
*** 279,289 ****
return 6; // fldcw
return 0;
}
static int preserve_SP_size() {
! return LP64_ONLY(1 +) 2; // [rex,] op, rm(reg/reg)
}
// !!!!! Special hack to get all type of calls to specify the byte offset
// from the start of the call to the point where the return address
// will point.
--- 279,289 ----
return 6; // fldcw
return 0;
}
static int preserve_SP_size() {
! return 2; // op, rm(reg/reg)
}
// !!!!! Special hack to get all type of calls to specify the byte offset
// from the start of the call to the point where the return address
// will point.
*** 493,510 ****
emit_opcode( cbuf, 0x8B );
emit_rm(cbuf, 0x3, dst_encoding, src_encoding );
}
}
! void encode_CopyXD( CodeBuffer &cbuf, int dst_encoding, int src_encoding ) {
! if( dst_encoding == src_encoding ) {
! // reg-reg copy, use an empty encoding
! } else {
! MacroAssembler _masm(&cbuf);
! __ movdqa(as_XMMRegister(dst_encoding), as_XMMRegister(src_encoding));
! }
}
//=============================================================================
const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty;
--- 493,530 ----
emit_opcode( cbuf, 0x8B );
emit_rm(cbuf, 0x3, dst_encoding, src_encoding );
}
}
! void emit_cmpfp_fixup(MacroAssembler& _masm) {
! Label exit;
! __ jccb(Assembler::noParity, exit);
! __ pushf();
! //
! // comiss/ucomiss instructions set ZF,PF,CF flags and
! // zero OF,AF,SF for NaN values.
! // Fixup flags by zeroing ZF,PF so that compare of NaN
! // values returns 'less than' result (CF is set).
! // Leave the rest of flags unchanged.
! //
! // 7 6 5 4 3 2 1 0
! // |S|Z|r|A|r|P|r|C| (r - reserved bit)
! // 0 0 1 0 1 0 1 1 (0x2B)
! //
! __ andl(Address(rsp, 0), 0xffffff2b);
! __ popf();
! __ bind(exit);
! }
! void emit_cmpfp3(MacroAssembler& _masm, Register dst) {
! Label done;
! __ movl(dst, -1);
! __ jcc(Assembler::parity, done);
! __ jcc(Assembler::below, done);
! __ setb(Assembler::notEqual, dst);
! __ movzbl(dst, dst);
! __ bind(done);
}
//=============================================================================
const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty;
*** 790,885 ****
}
// Helper for XMM registers. Extra opcode bits, limited syntax.
static int impl_x_helper( CodeBuffer *cbuf, bool do_size, bool is_load,
int offset, int reg_lo, int reg_hi, int size, outputStream* st ) {
! if( cbuf ) {
! if( reg_lo+1 == reg_hi ) { // double move?
! if( is_load && !UseXmmLoadAndClearUpper )
! emit_opcode(*cbuf, 0x66 ); // use 'movlpd' for load
! else
! emit_opcode(*cbuf, 0xF2 ); // use 'movsd' otherwise
} else {
! emit_opcode(*cbuf, 0xF3 );
}
! emit_opcode(*cbuf, 0x0F );
! if( reg_lo+1 == reg_hi && is_load && !UseXmmLoadAndClearUpper )
! emit_opcode(*cbuf, 0x12 ); // use 'movlpd' for load
! else
! emit_opcode(*cbuf, is_load ? 0x10 : 0x11 );
! encode_RegMem(*cbuf, Matcher::_regEncode[reg_lo], ESP_enc, 0x4, 0, offset, false);
#ifndef PRODUCT
! } else if( !do_size ) {
! if( size != 0 ) st->print("\n\t");
! if( reg_lo+1 == reg_hi ) { // double move?
! if( is_load ) st->print("%s %s,[ESP + #%d]",
UseXmmLoadAndClearUpper ? "MOVSD " : "MOVLPD",
Matcher::regName[reg_lo], offset);
else st->print("MOVSD [ESP + #%d],%s",
offset, Matcher::regName[reg_lo]);
} else {
! if( is_load ) st->print("MOVSS %s,[ESP + #%d]",
Matcher::regName[reg_lo], offset);
else st->print("MOVSS [ESP + #%d],%s",
offset, Matcher::regName[reg_lo]);
}
#endif
}
int offset_size = (offset == 0) ? 0 : ((offset <= 127) ? 1 : 4);
return size+5+offset_size;
}
static int impl_movx_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo,
int src_hi, int dst_hi, int size, outputStream* st ) {
! if( UseXmmRegToRegMoveAll ) {//Use movaps,movapd to move between xmm registers
! if( cbuf ) {
! if( (src_lo+1 == src_hi && dst_lo+1 == dst_hi) ) {
! emit_opcode(*cbuf, 0x66 );
}
- emit_opcode(*cbuf, 0x0F );
- emit_opcode(*cbuf, 0x28 );
- emit_rm (*cbuf, 0x3, Matcher::_regEncode[dst_lo], Matcher::_regEncode[src_lo] );
#ifndef PRODUCT
! } else if( !do_size ) {
! if( size != 0 ) st->print("\n\t");
! if( src_lo+1 == src_hi && dst_lo+1 == dst_hi ) { // double move?
st->print("MOVAPD %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
} else {
st->print("MOVAPS %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
}
- #endif
- }
- return size + ((src_lo+1 == src_hi && dst_lo+1 == dst_hi) ? 4 : 3);
} else {
- if( cbuf ) {
- emit_opcode(*cbuf, (src_lo+1 == src_hi && dst_lo+1 == dst_hi) ? 0xF2 : 0xF3 );
- emit_opcode(*cbuf, 0x0F );
- emit_opcode(*cbuf, 0x10 );
- emit_rm (*cbuf, 0x3, Matcher::_regEncode[dst_lo], Matcher::_regEncode[src_lo] );
- #ifndef PRODUCT
- } else if( !do_size ) {
- if( size != 0 ) st->print("\n\t");
if( src_lo+1 == src_hi && dst_lo+1 == dst_hi ) { // double move?
st->print("MOVSD %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
} else {
st->print("MOVSS %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
}
#endif
}
! return size+4;
! }
}
static int impl_movgpr2x_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo,
int src_hi, int dst_hi, int size, outputStream* st ) {
// 32-bit
if (cbuf) {
! emit_opcode(*cbuf, 0x66);
! emit_opcode(*cbuf, 0x0F);
! emit_opcode(*cbuf, 0x6E);
! emit_rm(*cbuf, 0x3, Matcher::_regEncode[dst_lo] & 7, Matcher::_regEncode[src_lo] & 7);
#ifndef PRODUCT
} else if (!do_size) {
st->print("movdl %s, %s\t# spill", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
#endif
}
--- 810,901 ----
}
// Helper for XMM registers. Extra opcode bits, limited syntax.
static int impl_x_helper( CodeBuffer *cbuf, bool do_size, bool is_load,
int offset, int reg_lo, int reg_hi, int size, outputStream* st ) {
! if (cbuf) {
! MacroAssembler _masm(cbuf);
! if (reg_lo+1 == reg_hi) { // double move?
! if (is_load) {
! __ movdbl(as_XMMRegister(Matcher::_regEncode[reg_lo]), Address(rsp, offset));
} else {
! __ movdbl(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[reg_lo]));
}
! } else {
! if (is_load) {
! __ movflt(as_XMMRegister(Matcher::_regEncode[reg_lo]), Address(rsp, offset));
! } else {
! __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[reg_lo]));
! }
! }
#ifndef PRODUCT
! } else if (!do_size) {
! if (size != 0) st->print("\n\t");
! if (reg_lo+1 == reg_hi) { // double move?
! if (is_load) st->print("%s %s,[ESP + #%d]",
UseXmmLoadAndClearUpper ? "MOVSD " : "MOVLPD",
Matcher::regName[reg_lo], offset);
else st->print("MOVSD [ESP + #%d],%s",
offset, Matcher::regName[reg_lo]);
} else {
! if (is_load) st->print("MOVSS %s,[ESP + #%d]",
Matcher::regName[reg_lo], offset);
else st->print("MOVSS [ESP + #%d],%s",
offset, Matcher::regName[reg_lo]);
}
#endif
}
int offset_size = (offset == 0) ? 0 : ((offset <= 127) ? 1 : 4);
+ // VEX_2bytes prefix is used if UseAVX > 0, so it takes the same 2 bytes.
return size+5+offset_size;
}
static int impl_movx_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo,
int src_hi, int dst_hi, int size, outputStream* st ) {
! if (cbuf) {
! MacroAssembler _masm(cbuf);
! if (src_lo+1 == src_hi && dst_lo+1 == dst_hi) { // double move?
! __ movdbl(as_XMMRegister(Matcher::_regEncode[dst_lo]),
! as_XMMRegister(Matcher::_regEncode[src_lo]));
! } else {
! __ movflt(as_XMMRegister(Matcher::_regEncode[dst_lo]),
! as_XMMRegister(Matcher::_regEncode[src_lo]));
}
#ifndef PRODUCT
! } else if (!do_size) {
! if (size != 0) st->print("\n\t");
! if (UseXmmRegToRegMoveAll) {//Use movaps,movapd to move between xmm registers
! if (src_lo+1 == src_hi && dst_lo+1 == dst_hi) { // double move?
st->print("MOVAPD %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
} else {
st->print("MOVAPS %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
}
} else {
if( src_lo+1 == src_hi && dst_lo+1 == dst_hi ) { // double move?
st->print("MOVSD %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
} else {
st->print("MOVSS %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
}
+ }
#endif
}
! // VEX_2bytes prefix is used if UseAVX > 0, and it takes the same 2 bytes.
! // Only MOVAPS SSE prefix uses 1 byte.
! int sz = 4;
! if (!(src_lo+1 == src_hi && dst_lo+1 == dst_hi) &&
! UseXmmRegToRegMoveAll && (UseAVX == 0)) sz = 3;
! return size + sz;
}
static int impl_movgpr2x_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo,
int src_hi, int dst_hi, int size, outputStream* st ) {
// 32-bit
if (cbuf) {
! MacroAssembler _masm(cbuf);
! __ movdl(as_XMMRegister(Matcher::_regEncode[dst_lo]),
! as_Register(Matcher::_regEncode[src_lo]));
#ifndef PRODUCT
} else if (!do_size) {
st->print("movdl %s, %s\t# spill", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
#endif
}
*** 889,902 ****
static int impl_movx2gpr_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo,
int src_hi, int dst_hi, int size, outputStream* st ) {
// 32-bit
if (cbuf) {
! emit_opcode(*cbuf, 0x66);
! emit_opcode(*cbuf, 0x0F);
! emit_opcode(*cbuf, 0x7E);
! emit_rm(*cbuf, 0x3, Matcher::_regEncode[src_lo] & 7, Matcher::_regEncode[dst_lo] & 7);
#ifndef PRODUCT
} else if (!do_size) {
st->print("movdl %s, %s\t# spill", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
#endif
}
--- 905,917 ----
static int impl_movx2gpr_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo,
int src_hi, int dst_hi, int size, outputStream* st ) {
// 32-bit
if (cbuf) {
! MacroAssembler _masm(cbuf);
! __ movdl(as_Register(Matcher::_regEncode[dst_lo]),
! as_XMMRegister(Matcher::_regEncode[src_lo]));
#ifndef PRODUCT
} else if (!do_size) {
st->print("movdl %s, %s\t# spill", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
#endif
}
*** 1929,1943 ****
emit_rm(cbuf, 0x01, $secondary, EAX_enc ); // R/M byte
emit_d8(cbuf, disp); // Displacement
%}
- enc_class Xor_Reg (eRegI dst) %{
- emit_opcode(cbuf, 0x33);
- emit_rm(cbuf, 0x3, $dst$$reg, $dst$$reg);
- %}
-
// Following encoding is no longer used, but may be restored if calling
// convention changes significantly.
// Became: Xor_Reg(EBP), Java_To_Runtime( labl )
//
// enc_class Java_Interpreter_Call (label labl) %{ // JAVA INTERPRETER CALL
--- 1944,1953 ----
*** 2011,2092 ****
emit_d32(cbuf, src_con);
}
%}
- enc_class MovI2X_reg(regX dst, eRegI src) %{
- emit_opcode(cbuf, 0x66 ); // MOVD dst,src
- emit_opcode(cbuf, 0x0F );
- emit_opcode(cbuf, 0x6E );
- emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
- %}
-
- enc_class MovX2I_reg(eRegI dst, regX src) %{
- emit_opcode(cbuf, 0x66 ); // MOVD dst,src
- emit_opcode(cbuf, 0x0F );
- emit_opcode(cbuf, 0x7E );
- emit_rm(cbuf, 0x3, $src$$reg, $dst$$reg);
- %}
-
- enc_class MovL2XD_reg(regXD dst, eRegL src, regXD tmp) %{
- { // MOVD $dst,$src.lo
- emit_opcode(cbuf,0x66);
- emit_opcode(cbuf,0x0F);
- emit_opcode(cbuf,0x6E);
- emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
- }
- { // MOVD $tmp,$src.hi
- emit_opcode(cbuf,0x66);
- emit_opcode(cbuf,0x0F);
- emit_opcode(cbuf,0x6E);
- emit_rm(cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($src$$reg));
- }
- { // PUNPCKLDQ $dst,$tmp
- emit_opcode(cbuf,0x66);
- emit_opcode(cbuf,0x0F);
- emit_opcode(cbuf,0x62);
- emit_rm(cbuf, 0x3, $dst$$reg, $tmp$$reg);
- }
- %}
-
- enc_class MovXD2L_reg(eRegL dst, regXD src, regXD tmp) %{
- { // MOVD $dst.lo,$src
- emit_opcode(cbuf,0x66);
- emit_opcode(cbuf,0x0F);
- emit_opcode(cbuf,0x7E);
- emit_rm(cbuf, 0x3, $src$$reg, $dst$$reg);
- }
- { // PSHUFLW $tmp,$src,0x4E (01001110b)
- emit_opcode(cbuf,0xF2);
- emit_opcode(cbuf,0x0F);
- emit_opcode(cbuf,0x70);
- emit_rm(cbuf, 0x3, $tmp$$reg, $src$$reg);
- emit_d8(cbuf, 0x4E);
- }
- { // MOVD $dst.hi,$tmp
- emit_opcode(cbuf,0x66);
- emit_opcode(cbuf,0x0F);
- emit_opcode(cbuf,0x7E);
- emit_rm(cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($dst$$reg));
- }
- %}
-
-
// Encode a reg-reg copy. If it is useless, then empty encoding.
enc_class enc_Copy( eRegI dst, eRegI src ) %{
encode_Copy( cbuf, $dst$$reg, $src$$reg );
%}
enc_class enc_CopyL_Lo( eRegI dst, eRegL src ) %{
encode_Copy( cbuf, $dst$$reg, $src$$reg );
%}
- // Encode xmm reg-reg copy. If it is useless, then empty encoding.
- enc_class enc_CopyXD( RegXD dst, RegXD src ) %{
- encode_CopyXD( cbuf, $dst$$reg, $src$$reg );
- %}
-
enc_class RegReg (eRegI dst, eRegI src) %{ // RegReg(Many)
emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
%}
enc_class RegReg_Lo(eRegL dst, eRegL src) %{ // RegReg(Many)
--- 2021,2039 ----
*** 2632,2751 ****
emit_opcode (cbuf, 0xD9);
emit_opcode (cbuf, 0xF6);
}
%}
! enc_class Push_ModD_encoding( regXD src0, regXD src1) %{
! // Allocate a word
! emit_opcode(cbuf,0x83); // SUB ESP,8
! emit_opcode(cbuf,0xEC);
! emit_d8(cbuf,0x08);
!
! emit_opcode (cbuf, 0xF2 ); // MOVSD [ESP], src1
! emit_opcode (cbuf, 0x0F );
! emit_opcode (cbuf, 0x11 );
! encode_RegMem(cbuf, $src1$$reg, ESP_enc, 0x4, 0, 0, false);
!
! emit_opcode(cbuf,0xDD ); // FLD_D [ESP]
! encode_RegMem(cbuf, 0x0, ESP_enc, 0x4, 0, 0, false);
!
! emit_opcode (cbuf, 0xF2 ); // MOVSD [ESP], src0
! emit_opcode (cbuf, 0x0F );
! emit_opcode (cbuf, 0x11 );
! encode_RegMem(cbuf, $src0$$reg, ESP_enc, 0x4, 0, 0, false);
!
! emit_opcode(cbuf,0xDD ); // FLD_D [ESP]
! encode_RegMem(cbuf, 0x0, ESP_enc, 0x4, 0, 0, false);
!
%}
! enc_class Push_ModX_encoding( regX src0, regX src1) %{
! // Allocate a word
! emit_opcode(cbuf,0x83); // SUB ESP,4
! emit_opcode(cbuf,0xEC);
! emit_d8(cbuf,0x04);
!
! emit_opcode (cbuf, 0xF3 ); // MOVSS [ESP], src1
! emit_opcode (cbuf, 0x0F );
! emit_opcode (cbuf, 0x11 );
! encode_RegMem(cbuf, $src1$$reg, ESP_enc, 0x4, 0, 0, false);
!
! emit_opcode(cbuf,0xD9 ); // FLD [ESP]
! encode_RegMem(cbuf, 0x0, ESP_enc, 0x4, 0, 0, false);
!
! emit_opcode (cbuf, 0xF3 ); // MOVSS [ESP], src0
! emit_opcode (cbuf, 0x0F );
! emit_opcode (cbuf, 0x11 );
! encode_RegMem(cbuf, $src0$$reg, ESP_enc, 0x4, 0, 0, false);
!
! emit_opcode(cbuf,0xD9 ); // FLD [ESP]
! encode_RegMem(cbuf, 0x0, ESP_enc, 0x4, 0, 0, false);
!
%}
enc_class Push_ResultXD(regXD dst) %{
! store_to_stackslot( cbuf, 0xDD, 0x03, 0 ); //FSTP [ESP]
!
! // UseXmmLoadAndClearUpper ? movsd dst,[esp] : movlpd dst,[esp]
! emit_opcode (cbuf, UseXmmLoadAndClearUpper ? 0xF2 : 0x66);
! emit_opcode (cbuf, 0x0F );
! emit_opcode (cbuf, UseXmmLoadAndClearUpper ? 0x10 : 0x12);
! encode_RegMem(cbuf, $dst$$reg, ESP_enc, 0x4, 0, 0, false);
!
! emit_opcode(cbuf,0x83); // ADD ESP,8
! emit_opcode(cbuf,0xC4);
! emit_d8(cbuf,0x08);
%}
enc_class Push_ResultX(regX dst, immI d8) %{
! store_to_stackslot( cbuf, 0xD9, 0x03, 0 ); //FSTP_S [ESP]
!
! emit_opcode (cbuf, 0xF3 ); // MOVSS dst(xmm), [ESP]
! emit_opcode (cbuf, 0x0F );
! emit_opcode (cbuf, 0x10 );
! encode_RegMem(cbuf, $dst$$reg, ESP_enc, 0x4, 0, 0, false);
!
! emit_opcode(cbuf,0x83); // ADD ESP,d8 (4 or 8)
! emit_opcode(cbuf,0xC4);
! emit_d8(cbuf,$d8$$constant);
%}
enc_class Push_SrcXD(regXD src) %{
! // Allocate a word
! emit_opcode(cbuf,0x83); // SUB ESP,8
! emit_opcode(cbuf,0xEC);
! emit_d8(cbuf,0x08);
!
! emit_opcode (cbuf, 0xF2 ); // MOVSD [ESP], src
! emit_opcode (cbuf, 0x0F );
! emit_opcode (cbuf, 0x11 );
! encode_RegMem(cbuf, $src$$reg, ESP_enc, 0x4, 0, 0, false);
!
! emit_opcode(cbuf,0xDD ); // FLD_D [ESP]
! encode_RegMem(cbuf, 0x0, ESP_enc, 0x4, 0, 0, false);
%}
enc_class push_stack_temp_qword() %{
! emit_opcode(cbuf,0x83); // SUB ESP,8
! emit_opcode(cbuf,0xEC);
! emit_d8 (cbuf,0x08);
%}
enc_class pop_stack_temp_qword() %{
! emit_opcode(cbuf,0x83); // ADD ESP,8
! emit_opcode(cbuf,0xC4);
! emit_d8 (cbuf,0x08);
%}
! enc_class push_xmm_to_fpr1( regXD xmm_src ) %{
! emit_opcode (cbuf, 0xF2 ); // MOVSD [ESP], xmm_src
! emit_opcode (cbuf, 0x0F );
! emit_opcode (cbuf, 0x11 );
! encode_RegMem(cbuf, $xmm_src$$reg, ESP_enc, 0x4, 0, 0, false);
!
! emit_opcode(cbuf,0xDD ); // FLD_D [ESP]
! encode_RegMem(cbuf, 0x0, ESP_enc, 0x4, 0, 0, false);
%}
// Compute X^Y using Intel's fast hardware instructions, if possible.
// Otherwise return a NaN.
enc_class pow_exp_core_encoding %{
--- 2579,2641 ----
emit_opcode (cbuf, 0xD9);
emit_opcode (cbuf, 0xF6);
}
%}
! enc_class Push_ModD_encoding(regXD src0, regXD src1) %{
! MacroAssembler _masm(&cbuf);
! __ subptr(rsp, 8);
! __ movdbl(Address(rsp, 0), $src1$$XMMRegister);
! __ fld_d(Address(rsp, 0));
! __ movdbl(Address(rsp, 0), $src0$$XMMRegister);
! __ fld_d(Address(rsp, 0));
%}
! enc_class Push_ModX_encoding(regX src0, regX src1) %{
! MacroAssembler _masm(&cbuf);
! __ subptr(rsp, 4);
! __ movflt(Address(rsp, 0), $src1$$XMMRegister);
! __ fld_s(Address(rsp, 0));
! __ movflt(Address(rsp, 0), $src0$$XMMRegister);
! __ fld_s(Address(rsp, 0));
%}
enc_class Push_ResultXD(regXD dst) %{
! MacroAssembler _masm(&cbuf);
! __ fstp_d(Address(rsp, 0));
! __ movdbl($dst$$XMMRegister, Address(rsp, 0));
! __ addptr(rsp, 8);
%}
enc_class Push_ResultX(regX dst, immI d8) %{
! MacroAssembler _masm(&cbuf);
! __ fstp_s(Address(rsp, 0));
! __ movflt($dst$$XMMRegister, Address(rsp, 0));
! __ addptr(rsp, $d8$$constant);
%}
enc_class Push_SrcXD(regXD src) %{
! MacroAssembler _masm(&cbuf);
! __ subptr(rsp, 8);
! __ movdbl(Address(rsp, 0), $src$$XMMRegister);
! __ fld_d(Address(rsp, 0));
%}
enc_class push_stack_temp_qword() %{
! MacroAssembler _masm(&cbuf);
! __ subptr(rsp, 8);
%}
enc_class pop_stack_temp_qword() %{
! MacroAssembler _masm(&cbuf);
! __ addptr(rsp, 8);
%}
! enc_class push_xmm_to_fpr1(regXD src) %{
! MacroAssembler _masm(&cbuf);
! __ movdbl(Address(rsp, 0), $src$$XMMRegister);
! __ fld_d(Address(rsp, 0));
%}
// Compute X^Y using Intel's fast hardware instructions, if possible.
// Otherwise return a NaN.
enc_class pow_exp_core_encoding %{
*** 2920,2947 ****
emit_opcode( cbuf, 0xB8 + $dst$$reg);
emit_d32( cbuf, 1 );
%}
- // XMM version of CmpF_Result. Because the XMM compare
- // instructions set the EFLAGS directly. It becomes simpler than
- // the float version above.
- enc_class CmpX_Result(eRegI dst) %{
- MacroAssembler _masm(&cbuf);
- Label nan, inc, done;
-
- __ jccb(Assembler::parity, nan);
- __ jccb(Assembler::equal, done);
- __ jccb(Assembler::above, inc);
- __ bind(nan);
- __ decrement(as_Register($dst$$reg)); // NO L qqq
- __ jmpb(done);
- __ bind(inc);
- __ increment(as_Register($dst$$reg)); // NO L qqq
- __ bind(done);
- %}
-
// Compare the longs and set flags
// BROKEN! Do Not use as-is
enc_class cmpl_test( eRegL src1, eRegL src2 ) %{
// CMP $src1.hi,$src2.hi
emit_opcode( cbuf, 0x3B );
--- 2810,2819 ----
*** 3160,3212 ****
emit_opcode(cbuf,0x83); // SBB hi,0
emit_rm (cbuf,0x3, 0x3, HIGH_FROM_LOW($dst$$reg));
emit_d8 (cbuf,0 );
%}
- enc_class movq_ld(regXD dst, memory mem) %{
- MacroAssembler _masm(&cbuf);
- __ movq($dst$$XMMRegister, $mem$$Address);
- %}
- enc_class movq_st(memory mem, regXD src) %{
- MacroAssembler _masm(&cbuf);
- __ movq($mem$$Address, $src$$XMMRegister);
- %}
-
- enc_class pshufd_8x8(regX dst, regX src) %{
- MacroAssembler _masm(&cbuf);
-
- encode_CopyXD(cbuf, $dst$$reg, $src$$reg);
- __ punpcklbw(as_XMMRegister($dst$$reg), as_XMMRegister($dst$$reg));
- __ pshuflw(as_XMMRegister($dst$$reg), as_XMMRegister($dst$$reg), 0x00);
- %}
-
- enc_class pshufd_4x16(regX dst, regX src) %{
- MacroAssembler _masm(&cbuf);
-
- __ pshuflw(as_XMMRegister($dst$$reg), as_XMMRegister($src$$reg), 0x00);
- %}
-
- enc_class pshufd(regXD dst, regXD src, int mode) %{
- MacroAssembler _masm(&cbuf);
-
- __ pshufd(as_XMMRegister($dst$$reg), as_XMMRegister($src$$reg), $mode);
- %}
-
- enc_class pxor(regXD dst, regXD src) %{
- MacroAssembler _masm(&cbuf);
-
- __ pxor(as_XMMRegister($dst$$reg), as_XMMRegister($src$$reg));
- %}
-
- enc_class mov_i2x(regXD dst, eRegI src) %{
- MacroAssembler _masm(&cbuf);
-
- __ movdl(as_XMMRegister($dst$$reg), as_Register($src$$reg));
- %}
-
-
// Because the transitions from emitted code to the runtime
// monitorenter/exit helper stubs are so slow it's critical that
// we inline both the stack-locking fast-path and the inflated fast path.
//
// See also: cmpFastLock and cmpFastUnlock.
--- 3032,3042 ----
*** 3840,4116 ****
emit_opcode(cbuf,0xE8); // Call into runtime
emit_d32_reloc(cbuf, (StubRoutines::d2l_wrapper() - cbuf.insts_end()) - 4, runtime_call_Relocation::spec(), RELOC_IMM32 );
// Carry on here...
%}
- enc_class X2L_encoding( regX src ) %{
- // Allocate a word
- emit_opcode(cbuf,0x83); // SUB ESP,8
- emit_opcode(cbuf,0xEC);
- emit_d8(cbuf,0x08);
-
- emit_opcode (cbuf, 0xF3 ); // MOVSS [ESP], src
- emit_opcode (cbuf, 0x0F );
- emit_opcode (cbuf, 0x11 );
- encode_RegMem(cbuf, $src$$reg, ESP_enc, 0x4, 0, 0, false);
-
- emit_opcode(cbuf,0xD9 ); // FLD_S [ESP]
- encode_RegMem(cbuf, 0x0, ESP_enc, 0x4, 0, 0, false);
-
- emit_opcode(cbuf,0xD9); // FLDCW trunc
- emit_opcode(cbuf,0x2D);
- emit_d32(cbuf,(int)StubRoutines::addr_fpu_cntrl_wrd_trunc());
-
- // Encoding assumes a double has been pushed into FPR0.
- // Store down the double as a long, popping the FPU stack
- emit_opcode(cbuf,0xDF); // FISTP [ESP]
- emit_opcode(cbuf,0x3C);
- emit_d8(cbuf,0x24);
-
- // Restore the rounding mode; mask the exception
- emit_opcode(cbuf,0xD9); // FLDCW std/24-bit mode
- emit_opcode(cbuf,0x2D);
- emit_d32( cbuf, Compile::current()->in_24_bit_fp_mode()
- ? (int)StubRoutines::addr_fpu_cntrl_wrd_24()
- : (int)StubRoutines::addr_fpu_cntrl_wrd_std());
-
- // Load the converted int; adjust CPU stack
- emit_opcode(cbuf,0x58); // POP EAX
-
- emit_opcode(cbuf,0x5A); // POP EDX
-
- emit_opcode(cbuf,0x81); // CMP EDX,imm
- emit_d8 (cbuf,0xFA); // rdx
- emit_d32 (cbuf,0x80000000);// 0x80000000
-
- emit_opcode(cbuf,0x75); // JNE around_slow_call
- emit_d8 (cbuf,0x13+4); // Size of slow_call
-
- emit_opcode(cbuf,0x85); // TEST EAX,EAX
- emit_opcode(cbuf,0xC0); // 2/rax,/rax,
-
- emit_opcode(cbuf,0x75); // JNE around_slow_call
- emit_d8 (cbuf,0x13); // Size of slow_call
-
- // Allocate a word
- emit_opcode(cbuf,0x83); // SUB ESP,4
- emit_opcode(cbuf,0xEC);
- emit_d8(cbuf,0x04);
-
- emit_opcode (cbuf, 0xF3 ); // MOVSS [ESP], src
- emit_opcode (cbuf, 0x0F );
- emit_opcode (cbuf, 0x11 );
- encode_RegMem(cbuf, $src$$reg, ESP_enc, 0x4, 0, 0, false);
-
- emit_opcode(cbuf,0xD9 ); // FLD_S [ESP]
- encode_RegMem(cbuf, 0x0, ESP_enc, 0x4, 0, 0, false);
-
- emit_opcode(cbuf,0x83); // ADD ESP,4
- emit_opcode(cbuf,0xC4);
- emit_d8(cbuf,0x04);
-
- // CALL directly to the runtime
- cbuf.set_insts_mark();
- emit_opcode(cbuf,0xE8); // Call into runtime
- emit_d32_reloc(cbuf, (StubRoutines::d2l_wrapper() - cbuf.insts_end()) - 4, runtime_call_Relocation::spec(), RELOC_IMM32 );
- // Carry on here...
- %}
-
- enc_class XD2L_encoding( regXD src ) %{
- // Allocate a word
- emit_opcode(cbuf,0x83); // SUB ESP,8
- emit_opcode(cbuf,0xEC);
- emit_d8(cbuf,0x08);
-
- emit_opcode (cbuf, 0xF2 ); // MOVSD [ESP], src
- emit_opcode (cbuf, 0x0F );
- emit_opcode (cbuf, 0x11 );
- encode_RegMem(cbuf, $src$$reg, ESP_enc, 0x4, 0, 0, false);
-
- emit_opcode(cbuf,0xDD ); // FLD_D [ESP]
- encode_RegMem(cbuf, 0x0, ESP_enc, 0x4, 0, 0, false);
-
- emit_opcode(cbuf,0xD9); // FLDCW trunc
- emit_opcode(cbuf,0x2D);
- emit_d32(cbuf,(int)StubRoutines::addr_fpu_cntrl_wrd_trunc());
-
- // Encoding assumes a double has been pushed into FPR0.
- // Store down the double as a long, popping the FPU stack
- emit_opcode(cbuf,0xDF); // FISTP [ESP]
- emit_opcode(cbuf,0x3C);
- emit_d8(cbuf,0x24);
-
- // Restore the rounding mode; mask the exception
- emit_opcode(cbuf,0xD9); // FLDCW std/24-bit mode
- emit_opcode(cbuf,0x2D);
- emit_d32( cbuf, Compile::current()->in_24_bit_fp_mode()
- ? (int)StubRoutines::addr_fpu_cntrl_wrd_24()
- : (int)StubRoutines::addr_fpu_cntrl_wrd_std());
-
- // Load the converted int; adjust CPU stack
- emit_opcode(cbuf,0x58); // POP EAX
-
- emit_opcode(cbuf,0x5A); // POP EDX
-
- emit_opcode(cbuf,0x81); // CMP EDX,imm
- emit_d8 (cbuf,0xFA); // rdx
- emit_d32 (cbuf,0x80000000); // 0x80000000
-
- emit_opcode(cbuf,0x75); // JNE around_slow_call
- emit_d8 (cbuf,0x13+4); // Size of slow_call
-
- emit_opcode(cbuf,0x85); // TEST EAX,EAX
- emit_opcode(cbuf,0xC0); // 2/rax,/rax,
-
- emit_opcode(cbuf,0x75); // JNE around_slow_call
- emit_d8 (cbuf,0x13); // Size of slow_call
-
- // Push src onto stack slow-path
- // Allocate a word
- emit_opcode(cbuf,0x83); // SUB ESP,8
- emit_opcode(cbuf,0xEC);
- emit_d8(cbuf,0x08);
-
- emit_opcode (cbuf, 0xF2 ); // MOVSD [ESP], src
- emit_opcode (cbuf, 0x0F );
- emit_opcode (cbuf, 0x11 );
- encode_RegMem(cbuf, $src$$reg, ESP_enc, 0x4, 0, 0, false);
-
- emit_opcode(cbuf,0xDD ); // FLD_D [ESP]
- encode_RegMem(cbuf, 0x0, ESP_enc, 0x4, 0, 0, false);
-
- emit_opcode(cbuf,0x83); // ADD ESP,8
- emit_opcode(cbuf,0xC4);
- emit_d8(cbuf,0x08);
-
- // CALL directly to the runtime
- cbuf.set_insts_mark();
- emit_opcode(cbuf,0xE8); // Call into runtime
- emit_d32_reloc(cbuf, (StubRoutines::d2l_wrapper() - cbuf.insts_end()) - 4, runtime_call_Relocation::spec(), RELOC_IMM32 );
- // Carry on here...
- %}
-
- enc_class D2X_encoding( regX dst, regD src ) %{
- // Allocate a word
- emit_opcode(cbuf,0x83); // SUB ESP,4
- emit_opcode(cbuf,0xEC);
- emit_d8(cbuf,0x04);
- int pop = 0x02;
- if ($src$$reg != FPR1L_enc) {
- emit_opcode( cbuf, 0xD9 ); // FLD ST(i-1)
- emit_d8( cbuf, 0xC0-1+$src$$reg );
- pop = 0x03;
- }
- store_to_stackslot( cbuf, 0xD9, pop, 0 ); // FST<P>_S [ESP]
-
- emit_opcode (cbuf, 0xF3 ); // MOVSS dst(xmm), [ESP]
- emit_opcode (cbuf, 0x0F );
- emit_opcode (cbuf, 0x10 );
- encode_RegMem(cbuf, $dst$$reg, ESP_enc, 0x4, 0, 0, false);
-
- emit_opcode(cbuf,0x83); // ADD ESP,4
- emit_opcode(cbuf,0xC4);
- emit_d8(cbuf,0x04);
- // Carry on here...
- %}
-
- enc_class FX2I_encoding( regX src, eRegI dst ) %{
- emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
-
- // Compare the result to see if we need to go to the slow path
- emit_opcode(cbuf,0x81); // CMP dst,imm
- emit_rm (cbuf,0x3,0x7,$dst$$reg);
- emit_d32 (cbuf,0x80000000); // 0x80000000
-
- emit_opcode(cbuf,0x75); // JNE around_slow_call
- emit_d8 (cbuf,0x13); // Size of slow_call
- // Store xmm to a temp memory
- // location and push it onto stack.
-
- emit_opcode(cbuf,0x83); // SUB ESP,4
- emit_opcode(cbuf,0xEC);
- emit_d8(cbuf, $primary ? 0x8 : 0x4);
-
- emit_opcode (cbuf, $primary ? 0xF2 : 0xF3 ); // MOVSS [ESP], xmm
- emit_opcode (cbuf, 0x0F );
- emit_opcode (cbuf, 0x11 );
- encode_RegMem(cbuf, $src$$reg, ESP_enc, 0x4, 0, 0, false);
-
- emit_opcode(cbuf, $primary ? 0xDD : 0xD9 ); // FLD [ESP]
- encode_RegMem(cbuf, 0x0, ESP_enc, 0x4, 0, 0, false);
-
- emit_opcode(cbuf,0x83); // ADD ESP,4
- emit_opcode(cbuf,0xC4);
- emit_d8(cbuf, $primary ? 0x8 : 0x4);
-
- // CALL directly to the runtime
- cbuf.set_insts_mark();
- emit_opcode(cbuf,0xE8); // Call into runtime
- emit_d32_reloc(cbuf, (StubRoutines::d2i_wrapper() - cbuf.insts_end()) - 4, runtime_call_Relocation::spec(), RELOC_IMM32 );
-
- // Carry on here...
- %}
-
- enc_class X2D_encoding( regD dst, regX src ) %{
- // Allocate a word
- emit_opcode(cbuf,0x83); // SUB ESP,4
- emit_opcode(cbuf,0xEC);
- emit_d8(cbuf,0x04);
-
- emit_opcode (cbuf, 0xF3 ); // MOVSS [ESP], xmm
- emit_opcode (cbuf, 0x0F );
- emit_opcode (cbuf, 0x11 );
- encode_RegMem(cbuf, $src$$reg, ESP_enc, 0x4, 0, 0, false);
-
- emit_opcode(cbuf,0xD9 ); // FLD_S [ESP]
- encode_RegMem(cbuf, 0x0, ESP_enc, 0x4, 0, 0, false);
-
- emit_opcode(cbuf,0x83); // ADD ESP,4
- emit_opcode(cbuf,0xC4);
- emit_d8(cbuf,0x04);
-
- // Carry on here...
- %}
-
- enc_class AbsXF_encoding(regX dst) %{
- address signmask_address=(address)float_signmask_pool;
- // andpd:\tANDPS $dst,[signconst]
- emit_opcode(cbuf, 0x0F);
- emit_opcode(cbuf, 0x54);
- emit_rm(cbuf, 0x0, $dst$$reg, 0x5);
- emit_d32(cbuf, (int)signmask_address);
- %}
-
- enc_class AbsXD_encoding(regXD dst) %{
- address signmask_address=(address)double_signmask_pool;
- // andpd:\tANDPD $dst,[signconst]
- emit_opcode(cbuf, 0x66);
- emit_opcode(cbuf, 0x0F);
- emit_opcode(cbuf, 0x54);
- emit_rm(cbuf, 0x0, $dst$$reg, 0x5);
- emit_d32(cbuf, (int)signmask_address);
- %}
-
- enc_class NegXF_encoding(regX dst) %{
- address signmask_address=(address)float_signflip_pool;
- // andpd:\tXORPS $dst,[signconst]
- emit_opcode(cbuf, 0x0F);
- emit_opcode(cbuf, 0x57);
- emit_rm(cbuf, 0x0, $dst$$reg, 0x5);
- emit_d32(cbuf, (int)signmask_address);
- %}
-
- enc_class NegXD_encoding(regXD dst) %{
- address signmask_address=(address)double_signflip_pool;
- // andpd:\tXORPD $dst,[signconst]
- emit_opcode(cbuf, 0x66);
- emit_opcode(cbuf, 0x0F);
- emit_opcode(cbuf, 0x57);
- emit_rm(cbuf, 0x0, $dst$$reg, 0x5);
- emit_d32(cbuf, (int)signmask_address);
- %}
-
enc_class FMul_ST_reg( eRegF src1 ) %{
// Operand was loaded from memory into fp ST (stack top)
// FMUL ST,$src /* D8 C8+i */
emit_opcode(cbuf, 0xD8);
emit_opcode(cbuf, 0xC8 + $src1$$reg);
--- 3670,3679 ----
*** 4174,4243 ****
bool disp_is_oop = $mem->disp_is_oop(); // disp-as-oop when working with static globals
encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, disp_is_oop);
store_to_stackslot( cbuf, 0x0DF, 0x07, $dst$$disp );
%}
- enc_class enc_loadLX_volatile( memory mem, stackSlotL dst, regXD tmp ) %{
- { // Atomic long load
- // UseXmmLoadAndClearUpper ? movsd $tmp,$mem : movlpd $tmp,$mem
- emit_opcode(cbuf,UseXmmLoadAndClearUpper ? 0xF2 : 0x66);
- emit_opcode(cbuf,0x0F);
- emit_opcode(cbuf,UseXmmLoadAndClearUpper ? 0x10 : 0x12);
- int base = $mem$$base;
- int index = $mem$$index;
- int scale = $mem$$scale;
- int displace = $mem$$disp;
- bool disp_is_oop = $mem->disp_is_oop(); // disp-as-oop when working with static globals
- encode_RegMem(cbuf, $tmp$$reg, base, index, scale, displace, disp_is_oop);
- }
- { // MOVSD $dst,$tmp ! atomic long store
- emit_opcode(cbuf,0xF2);
- emit_opcode(cbuf,0x0F);
- emit_opcode(cbuf,0x11);
- int base = $dst$$base;
- int index = $dst$$index;
- int scale = $dst$$scale;
- int displace = $dst$$disp;
- bool disp_is_oop = $dst->disp_is_oop(); // disp-as-oop when working with static globals
- encode_RegMem(cbuf, $tmp$$reg, base, index, scale, displace, disp_is_oop);
- }
- %}
-
- enc_class enc_loadLX_reg_volatile( memory mem, eRegL dst, regXD tmp ) %{
- { // Atomic long load
- // UseXmmLoadAndClearUpper ? movsd $tmp,$mem : movlpd $tmp,$mem
- emit_opcode(cbuf,UseXmmLoadAndClearUpper ? 0xF2 : 0x66);
- emit_opcode(cbuf,0x0F);
- emit_opcode(cbuf,UseXmmLoadAndClearUpper ? 0x10 : 0x12);
- int base = $mem$$base;
- int index = $mem$$index;
- int scale = $mem$$scale;
- int displace = $mem$$disp;
- bool disp_is_oop = $mem->disp_is_oop(); // disp-as-oop when working with static globals
- encode_RegMem(cbuf, $tmp$$reg, base, index, scale, displace, disp_is_oop);
- }
- { // MOVD $dst.lo,$tmp
- emit_opcode(cbuf,0x66);
- emit_opcode(cbuf,0x0F);
- emit_opcode(cbuf,0x7E);
- emit_rm(cbuf, 0x3, $tmp$$reg, $dst$$reg);
- }
- { // PSRLQ $tmp,32
- emit_opcode(cbuf,0x66);
- emit_opcode(cbuf,0x0F);
- emit_opcode(cbuf,0x73);
- emit_rm(cbuf, 0x3, 0x02, $tmp$$reg);
- emit_d8(cbuf, 0x20);
- }
- { // MOVD $dst.hi,$tmp
- emit_opcode(cbuf,0x66);
- emit_opcode(cbuf,0x0F);
- emit_opcode(cbuf,0x7E);
- emit_rm(cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($dst$$reg));
- }
- %}
-
// Volatile Store Long. Must be atomic, so move it into
// the FP TOS and then do a 64-bit FIST. Has to probe the
// target address before the store (for null-ptr checks)
// so the memory operand is used twice in the encoding.
enc_class enc_storeL_volatile( memory mem, stackSlotL src ) %{
--- 3737,3746 ----
*** 4251,4320 ****
int displace = $mem$$disp;
bool disp_is_oop = $mem->disp_is_oop(); // disp-as-oop when working with static globals
encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, disp_is_oop);
%}
- enc_class enc_storeLX_volatile( memory mem, stackSlotL src, regXD tmp) %{
- { // Atomic long load
- // UseXmmLoadAndClearUpper ? movsd $tmp,[$src] : movlpd $tmp,[$src]
- emit_opcode(cbuf,UseXmmLoadAndClearUpper ? 0xF2 : 0x66);
- emit_opcode(cbuf,0x0F);
- emit_opcode(cbuf,UseXmmLoadAndClearUpper ? 0x10 : 0x12);
- int base = $src$$base;
- int index = $src$$index;
- int scale = $src$$scale;
- int displace = $src$$disp;
- bool disp_is_oop = $src->disp_is_oop(); // disp-as-oop when working with static globals
- encode_RegMem(cbuf, $tmp$$reg, base, index, scale, displace, disp_is_oop);
- }
- cbuf.set_insts_mark(); // Mark start of MOVSD in case $mem has an oop
- { // MOVSD $mem,$tmp ! atomic long store
- emit_opcode(cbuf,0xF2);
- emit_opcode(cbuf,0x0F);
- emit_opcode(cbuf,0x11);
- int base = $mem$$base;
- int index = $mem$$index;
- int scale = $mem$$scale;
- int displace = $mem$$disp;
- bool disp_is_oop = $mem->disp_is_oop(); // disp-as-oop when working with static globals
- encode_RegMem(cbuf, $tmp$$reg, base, index, scale, displace, disp_is_oop);
- }
- %}
-
- enc_class enc_storeLX_reg_volatile( memory mem, eRegL src, regXD tmp, regXD tmp2) %{
- { // MOVD $tmp,$src.lo
- emit_opcode(cbuf,0x66);
- emit_opcode(cbuf,0x0F);
- emit_opcode(cbuf,0x6E);
- emit_rm(cbuf, 0x3, $tmp$$reg, $src$$reg);
- }
- { // MOVD $tmp2,$src.hi
- emit_opcode(cbuf,0x66);
- emit_opcode(cbuf,0x0F);
- emit_opcode(cbuf,0x6E);
- emit_rm(cbuf, 0x3, $tmp2$$reg, HIGH_FROM_LOW($src$$reg));
- }
- { // PUNPCKLDQ $tmp,$tmp2
- emit_opcode(cbuf,0x66);
- emit_opcode(cbuf,0x0F);
- emit_opcode(cbuf,0x62);
- emit_rm(cbuf, 0x3, $tmp$$reg, $tmp2$$reg);
- }
- cbuf.set_insts_mark(); // Mark start of MOVSD in case $mem has an oop
- { // MOVSD $mem,$tmp ! atomic long store
- emit_opcode(cbuf,0xF2);
- emit_opcode(cbuf,0x0F);
- emit_opcode(cbuf,0x11);
- int base = $mem$$base;
- int index = $mem$$index;
- int scale = $mem$$scale;
- int displace = $mem$$disp;
- bool disp_is_oop = $mem->disp_is_oop(); // disp-as-oop when working with static globals
- encode_RegMem(cbuf, $tmp$$reg, base, index, scale, displace, disp_is_oop);
- }
- %}
-
// Safepoint Poll. This polls the safepoint page, and causes an
// exception if it is not readable. Unfortunately, it kills the condition code
// in the process
// We current use TESTL [spp],EDI
// A better choice might be TESTB [spp + pagesize() - CacheLineSize()],0
--- 3754,3763 ----
*** 6875,6885 ****
match(Set dst (LoadL mem));
effect(TEMP tmp);
ins_cost(180);
format %{ "MOVSD $tmp,$mem\t# Atomic volatile long load\n\t"
"MOVSD $dst,$tmp" %}
! ins_encode(enc_loadLX_volatile(mem, dst, tmp));
ins_pipe( pipe_slow );
%}
instruct loadLX_reg_volatile(eRegL dst, memory mem, regXD tmp) %{
predicate(UseSSE>=2 && ((LoadLNode*)n)->require_atomic_access());
--- 6318,6331 ----
match(Set dst (LoadL mem));
effect(TEMP tmp);
ins_cost(180);
format %{ "MOVSD $tmp,$mem\t# Atomic volatile long load\n\t"
"MOVSD $dst,$tmp" %}
! ins_encode %{
! __ movdbl($tmp$$XMMRegister, $mem$$Address);
! __ movdbl(Address(rsp, $dst$$disp), $tmp$$XMMRegister);
! %}
ins_pipe( pipe_slow );
%}
instruct loadLX_reg_volatile(eRegL dst, memory mem, regXD tmp) %{
predicate(UseSSE>=2 && ((LoadLNode*)n)->require_atomic_access());
*** 6888,6898 ****
ins_cost(160);
format %{ "MOVSD $tmp,$mem\t# Atomic volatile long load\n\t"
"MOVD $dst.lo,$tmp\n\t"
"PSRLQ $tmp,32\n\t"
"MOVD $dst.hi,$tmp" %}
! ins_encode(enc_loadLX_reg_volatile(mem, dst, tmp));
ins_pipe( pipe_slow );
%}
// Load Range
instruct loadRange(eRegI dst, memory mem) %{
--- 6334,6349 ----
ins_cost(160);
format %{ "MOVSD $tmp,$mem\t# Atomic volatile long load\n\t"
"MOVD $dst.lo,$tmp\n\t"
"PSRLQ $tmp,32\n\t"
"MOVD $dst.hi,$tmp" %}
! ins_encode %{
! __ movdbl($tmp$$XMMRegister, $mem$$Address);
! __ movdl($dst$$Register, $tmp$$XMMRegister);
! __ psrlq($tmp$$XMMRegister, 32);
! __ movdl(HIGH_FROM_LOW($dst$$Register), $tmp$$XMMRegister);
! %}
ins_pipe( pipe_slow );
%}
// Load Range
instruct loadRange(eRegI dst, memory mem) %{
*** 6946,6965 ****
instruct loadXD(regXD dst, memory mem) %{
predicate(UseSSE>=2 && UseXmmLoadAndClearUpper);
match(Set dst (LoadD mem));
ins_cost(145);
format %{ "MOVSD $dst,$mem" %}
! ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x10), RegMem(dst,mem));
ins_pipe( pipe_slow );
%}
instruct loadXD_partial(regXD dst, memory mem) %{
predicate(UseSSE>=2 && !UseXmmLoadAndClearUpper);
match(Set dst (LoadD mem));
ins_cost(145);
format %{ "MOVLPD $dst,$mem" %}
! ins_encode( Opcode(0x66), Opcode(0x0F), Opcode(0x12), RegMem(dst,mem));
ins_pipe( pipe_slow );
%}
// Load to XMM register (single-precision floating point)
// MOVSS instruction
--- 6397,6420 ----
instruct loadXD(regXD dst, memory mem) %{
predicate(UseSSE>=2 && UseXmmLoadAndClearUpper);
match(Set dst (LoadD mem));
ins_cost(145);
format %{ "MOVSD $dst,$mem" %}
! ins_encode %{
! __ movdbl ($dst$$XMMRegister, $mem$$Address);
! %}
ins_pipe( pipe_slow );
%}
instruct loadXD_partial(regXD dst, memory mem) %{
predicate(UseSSE>=2 && !UseXmmLoadAndClearUpper);
match(Set dst (LoadD mem));
ins_cost(145);
format %{ "MOVLPD $dst,$mem" %}
! ins_encode %{
! __ movdbl ($dst$$XMMRegister, $mem$$Address);
! %}
ins_pipe( pipe_slow );
%}
// Load to XMM register (single-precision floating point)
// MOVSS instruction
*** 6966,6976 ****
instruct loadX(regX dst, memory mem) %{
predicate(UseSSE>=1);
match(Set dst (LoadF mem));
ins_cost(145);
format %{ "MOVSS $dst,$mem" %}
! ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x10), RegMem(dst,mem));
ins_pipe( pipe_slow );
%}
// Load Float
instruct loadF(regF dst, memory mem) %{
--- 6421,6433 ----
instruct loadX(regX dst, memory mem) %{
predicate(UseSSE>=1);
match(Set dst (LoadF mem));
ins_cost(145);
format %{ "MOVSS $dst,$mem" %}
! ins_encode %{
! __ movflt ($dst$$XMMRegister, $mem$$Address);
! %}
ins_pipe( pipe_slow );
%}
// Load Float
instruct loadF(regF dst, memory mem) %{
*** 6990,7040 ****
instruct loadA8B(regXD dst, memory mem) %{
predicate(UseSSE>=1);
match(Set dst (Load8B mem));
ins_cost(125);
format %{ "MOVQ $dst,$mem\t! packed8B" %}
! ins_encode( movq_ld(dst, mem));
ins_pipe( pipe_slow );
%}
// Load Aligned Packed Short to XMM register
instruct loadA4S(regXD dst, memory mem) %{
predicate(UseSSE>=1);
match(Set dst (Load4S mem));
ins_cost(125);
format %{ "MOVQ $dst,$mem\t! packed4S" %}
! ins_encode( movq_ld(dst, mem));
ins_pipe( pipe_slow );
%}
// Load Aligned Packed Char to XMM register
instruct loadA4C(regXD dst, memory mem) %{
predicate(UseSSE>=1);
match(Set dst (Load4C mem));
ins_cost(125);
format %{ "MOVQ $dst,$mem\t! packed4C" %}
! ins_encode( movq_ld(dst, mem));
ins_pipe( pipe_slow );
%}
// Load Aligned Packed Integer to XMM register
instruct load2IU(regXD dst, memory mem) %{
predicate(UseSSE>=1);
match(Set dst (Load2I mem));
ins_cost(125);
format %{ "MOVQ $dst,$mem\t! packed2I" %}
! ins_encode( movq_ld(dst, mem));
ins_pipe( pipe_slow );
%}
// Load Aligned Packed Single to XMM
instruct loadA2F(regXD dst, memory mem) %{
predicate(UseSSE>=1);
match(Set dst (Load2F mem));
ins_cost(145);
format %{ "MOVQ $dst,$mem\t! packed2F" %}
! ins_encode( movq_ld(dst, mem));
ins_pipe( pipe_slow );
%}
// Load Effective Address
instruct leaP8(eRegP dst, indOffset8 mem) %{
--- 6447,6507 ----
instruct loadA8B(regXD dst, memory mem) %{
predicate(UseSSE>=1);
match(Set dst (Load8B mem));
ins_cost(125);
format %{ "MOVQ $dst,$mem\t! packed8B" %}
! ins_encode %{
! __ movq($dst$$XMMRegister, $mem$$Address);
! %}
ins_pipe( pipe_slow );
%}
// Load Aligned Packed Short to XMM register
instruct loadA4S(regXD dst, memory mem) %{
predicate(UseSSE>=1);
match(Set dst (Load4S mem));
ins_cost(125);
format %{ "MOVQ $dst,$mem\t! packed4S" %}
! ins_encode %{
! __ movq($dst$$XMMRegister, $mem$$Address);
! %}
ins_pipe( pipe_slow );
%}
// Load Aligned Packed Char to XMM register
instruct loadA4C(regXD dst, memory mem) %{
predicate(UseSSE>=1);
match(Set dst (Load4C mem));
ins_cost(125);
format %{ "MOVQ $dst,$mem\t! packed4C" %}
! ins_encode %{
! __ movq($dst$$XMMRegister, $mem$$Address);
! %}
ins_pipe( pipe_slow );
%}
// Load Aligned Packed Integer to XMM register
instruct load2IU(regXD dst, memory mem) %{
predicate(UseSSE>=1);
match(Set dst (Load2I mem));
ins_cost(125);
format %{ "MOVQ $dst,$mem\t! packed2I" %}
! ins_encode %{
! __ movq($dst$$XMMRegister, $mem$$Address);
! %}
ins_pipe( pipe_slow );
%}
// Load Aligned Packed Single to XMM
instruct loadA2F(regXD dst, memory mem) %{
predicate(UseSSE>=1);
match(Set dst (Load2F mem));
ins_cost(145);
format %{ "MOVQ $dst,$mem\t! packed2F" %}
! ins_encode %{
! __ movq($dst$$XMMRegister, $mem$$Address);
! %}
ins_pipe( pipe_slow );
%}
// Load Effective Address
instruct leaP8(eRegP dst, indOffset8 mem) %{
*** 7256,7266 ****
// The instruction usage is guarded by predicate in operand immXD0().
instruct loadConXD0(regXD dst, immXD0 src) %{
match(Set dst src);
ins_cost(100);
format %{ "XORPD $dst,$dst\t# double 0.0" %}
! ins_encode( Opcode(0x66), Opcode(0x0F), Opcode(0x57), RegReg(dst,dst));
ins_pipe( pipe_slow );
%}
// Load Stack Slot
instruct loadSSI(eRegI dst, stackSlotI src) %{
--- 6723,6735 ----
// The instruction usage is guarded by predicate in operand immXD0().
instruct loadConXD0(regXD dst, immXD0 src) %{
match(Set dst src);
ins_cost(100);
format %{ "XORPD $dst,$dst\t# double 0.0" %}
! ins_encode %{
! __ xorpd ($dst$$XMMRegister, $dst$$XMMRegister);
! %}
ins_pipe( pipe_slow );
%}
// Load Stack Slot
instruct loadSSI(eRegI dst, stackSlotI src) %{
*** 7558,7569 ****
effect( TEMP tmp, KILL cr );
ins_cost(380);
format %{ "CMP $mem,EAX\t# Probe address for implicit null check\n\t"
"MOVSD $tmp,$src\n\t"
"MOVSD $mem,$tmp\t # 64-bit atomic volatile long store" %}
! opcode(0x3B);
! ins_encode( OpcP, RegMem( EAX, mem ), enc_storeLX_volatile(mem, src, tmp));
ins_pipe( pipe_slow );
%}
instruct storeLX_reg_volatile(memory mem, eRegL src, regXD tmp2, regXD tmp, eFlagsReg cr) %{
predicate(UseSSE>=2 && ((StoreLNode*)n)->require_atomic_access());
--- 7027,7041 ----
effect( TEMP tmp, KILL cr );
ins_cost(380);
format %{ "CMP $mem,EAX\t# Probe address for implicit null check\n\t"
"MOVSD $tmp,$src\n\t"
"MOVSD $mem,$tmp\t # 64-bit atomic volatile long store" %}
! ins_encode %{
! __ cmpl(rax, $mem$$Address);
! __ movdbl($tmp$$XMMRegister, Address(rsp, $src$$disp));
! __ movdbl($mem$$Address, $tmp$$XMMRegister);
! %}
ins_pipe( pipe_slow );
%}
instruct storeLX_reg_volatile(memory mem, eRegL src, regXD tmp2, regXD tmp, eFlagsReg cr) %{
predicate(UseSSE>=2 && ((StoreLNode*)n)->require_atomic_access());
*** 7573,7584 ****
format %{ "CMP $mem,EAX\t# Probe address for implicit null check\n\t"
"MOVD $tmp,$src.lo\n\t"
"MOVD $tmp2,$src.hi\n\t"
"PUNPCKLDQ $tmp,$tmp2\n\t"
"MOVSD $mem,$tmp\t # 64-bit atomic volatile long store" %}
! opcode(0x3B);
! ins_encode( OpcP, RegMem( EAX, mem ), enc_storeLX_reg_volatile(mem, src, tmp, tmp2));
ins_pipe( pipe_slow );
%}
// Store Pointer; for storing unknown oops and raw pointers
instruct storeP(memory mem, anyRegP src) %{
--- 7045,7061 ----
format %{ "CMP $mem,EAX\t# Probe address for implicit null check\n\t"
"MOVD $tmp,$src.lo\n\t"
"MOVD $tmp2,$src.hi\n\t"
"PUNPCKLDQ $tmp,$tmp2\n\t"
"MOVSD $mem,$tmp\t # 64-bit atomic volatile long store" %}
! ins_encode %{
! __ cmpl(rax, $mem$$Address);
! __ movdl($tmp$$XMMRegister, $src$$Register);
! __ movdl($tmp2$$XMMRegister, HIGH_FROM_LOW($src$$Register));
! __ punpckldq($tmp$$XMMRegister, $tmp2$$XMMRegister);
! __ movdbl($mem$$Address, $tmp$$XMMRegister);
! %}
ins_pipe( pipe_slow );
%}
// Store Pointer; for storing unknown oops and raw pointers
instruct storeP(memory mem, anyRegP src) %{
*** 7641,7671 ****
instruct storeA8B(memory mem, regXD src) %{
predicate(UseSSE>=1);
match(Set mem (Store8B mem src));
ins_cost(145);
format %{ "MOVQ $mem,$src\t! packed8B" %}
! ins_encode( movq_st(mem, src));
ins_pipe( pipe_slow );
%}
// Store Aligned Packed Char/Short XMM register to memory
instruct storeA4C(memory mem, regXD src) %{
predicate(UseSSE>=1);
match(Set mem (Store4C mem src));
ins_cost(145);
format %{ "MOVQ $mem,$src\t! packed4C" %}
! ins_encode( movq_st(mem, src));
ins_pipe( pipe_slow );
%}
// Store Aligned Packed Integer XMM register to memory
instruct storeA2I(memory mem, regXD src) %{
predicate(UseSSE>=1);
match(Set mem (Store2I mem src));
ins_cost(145);
format %{ "MOVQ $mem,$src\t! packed2I" %}
! ins_encode( movq_st(mem, src));
ins_pipe( pipe_slow );
%}
// Store CMS card-mark Immediate
instruct storeImmCM(memory mem, immI8 src) %{
--- 7118,7154 ----
instruct storeA8B(memory mem, regXD src) %{
predicate(UseSSE>=1);
match(Set mem (Store8B mem src));
ins_cost(145);
format %{ "MOVQ $mem,$src\t! packed8B" %}
! ins_encode %{
! __ movq($mem$$Address, $src$$XMMRegister);
! %}
ins_pipe( pipe_slow );
%}
// Store Aligned Packed Char/Short XMM register to memory
instruct storeA4C(memory mem, regXD src) %{
predicate(UseSSE>=1);
match(Set mem (Store4C mem src));
ins_cost(145);
format %{ "MOVQ $mem,$src\t! packed4C" %}
! ins_encode %{
! __ movq($mem$$Address, $src$$XMMRegister);
! %}
ins_pipe( pipe_slow );
%}
// Store Aligned Packed Integer XMM register to memory
instruct storeA2I(memory mem, regXD src) %{
predicate(UseSSE>=1);
match(Set mem (Store2I mem src));
ins_cost(145);
format %{ "MOVQ $mem,$src\t! packed2I" %}
! ins_encode %{
! __ movq($mem$$Address, $src$$XMMRegister);
! %}
ins_pipe( pipe_slow );
%}
// Store CMS card-mark Immediate
instruct storeImmCM(memory mem, immI8 src) %{
*** 7707,7717 ****
instruct storeXD(memory mem, regXD src) %{
predicate(UseSSE>=2);
match(Set mem (StoreD mem src));
ins_cost(95);
format %{ "MOVSD $mem,$src" %}
! ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x11), RegMem(src, mem));
ins_pipe( pipe_slow );
%}
// Store XMM register to memory (single-precision floating point)
// MOVSS instruction
--- 7190,7202 ----
instruct storeXD(memory mem, regXD src) %{
predicate(UseSSE>=2);
match(Set mem (StoreD mem src));
ins_cost(95);
format %{ "MOVSD $mem,$src" %}
! ins_encode %{
! __ movdbl($mem$$Address, $src$$XMMRegister);
! %}
ins_pipe( pipe_slow );
%}
// Store XMM register to memory (single-precision floating point)
// MOVSS instruction
*** 7718,7738 ****
instruct storeX(memory mem, regX src) %{
predicate(UseSSE>=1);
match(Set mem (StoreF mem src));
ins_cost(95);
format %{ "MOVSS $mem,$src" %}
! ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x11), RegMem(src, mem));
ins_pipe( pipe_slow );
%}
// Store Aligned Packed Single Float XMM register to memory
instruct storeA2F(memory mem, regXD src) %{
predicate(UseSSE>=1);
match(Set mem (Store2F mem src));
ins_cost(145);
format %{ "MOVQ $mem,$src\t! packed2F" %}
! ins_encode( movq_st(mem, src));
ins_pipe( pipe_slow );
%}
// Store Float
instruct storeF( memory mem, regFPR1 src) %{
--- 7203,7227 ----
instruct storeX(memory mem, regX src) %{
predicate(UseSSE>=1);
match(Set mem (StoreF mem src));
ins_cost(95);
format %{ "MOVSS $mem,$src" %}
! ins_encode %{
! __ movflt($mem$$Address, $src$$XMMRegister);
! %}
ins_pipe( pipe_slow );
%}
// Store Aligned Packed Single Float XMM register to memory
instruct storeA2F(memory mem, regXD src) %{
predicate(UseSSE>=1);
match(Set mem (Store2F mem src));
ins_cost(145);
format %{ "MOVQ $mem,$src\t! packed2F" %}
! ins_encode %{
! __ movq($mem$$Address, $src$$XMMRegister);
! %}
ins_pipe( pipe_slow );
%}
// Store Float
instruct storeF( memory mem, regFPR1 src) %{
*** 8438,8448 ****
ins_encode( OpcP, RegMem(dst,mem));
ins_pipe( ialu_reg_mem );
%}
// LoadLong-locked - same as a volatile long load when used with compare-swap
! instruct loadLLocked(stackSlotL dst, load_long_memory mem) %{
predicate(UseSSE<=1);
match(Set dst (LoadLLocked mem));
ins_cost(200);
format %{ "FILD $mem\t# Atomic volatile long load\n\t"
--- 7927,7937 ----
ins_encode( OpcP, RegMem(dst,mem));
ins_pipe( ialu_reg_mem );
%}
// LoadLong-locked - same as a volatile long load when used with compare-swap
! instruct loadLLocked(stackSlotL dst, memory mem) %{
predicate(UseSSE<=1);
match(Set dst (LoadLLocked mem));
ins_cost(200);
format %{ "FILD $mem\t# Atomic volatile long load\n\t"
*** 8449,8479 ****
"FISTp $dst" %}
ins_encode(enc_loadL_volatile(mem,dst));
ins_pipe( fpu_reg_mem );
%}
! instruct loadLX_Locked(stackSlotL dst, load_long_memory mem, regXD tmp) %{
predicate(UseSSE>=2);
match(Set dst (LoadLLocked mem));
effect(TEMP tmp);
ins_cost(180);
format %{ "MOVSD $tmp,$mem\t# Atomic volatile long load\n\t"
"MOVSD $dst,$tmp" %}
! ins_encode(enc_loadLX_volatile(mem, dst, tmp));
ins_pipe( pipe_slow );
%}
! instruct loadLX_reg_Locked(eRegL dst, load_long_memory mem, regXD tmp) %{
predicate(UseSSE>=2);
match(Set dst (LoadLLocked mem));
effect(TEMP tmp);
ins_cost(160);
format %{ "MOVSD $tmp,$mem\t# Atomic volatile long load\n\t"
"MOVD $dst.lo,$tmp\n\t"
"PSRLQ $tmp,32\n\t"
"MOVD $dst.hi,$tmp" %}
! ins_encode(enc_loadLX_reg_volatile(mem, dst, tmp));
ins_pipe( pipe_slow );
%}
// Conditional-store of the updated heap-top.
// Used during allocation of the shared heap.
--- 7938,7976 ----
"FISTp $dst" %}
ins_encode(enc_loadL_volatile(mem,dst));
ins_pipe( fpu_reg_mem );
%}
! instruct loadLX_Locked(stackSlotL dst, memory mem, regXD tmp) %{
predicate(UseSSE>=2);
match(Set dst (LoadLLocked mem));
effect(TEMP tmp);
ins_cost(180);
format %{ "MOVSD $tmp,$mem\t# Atomic volatile long load\n\t"
"MOVSD $dst,$tmp" %}
! ins_encode %{
! __ movdbl($tmp$$XMMRegister, $mem$$Address);
! __ movdbl(Address(rsp, $dst$$disp), $tmp$$XMMRegister);
! %}
ins_pipe( pipe_slow );
%}
! instruct loadLX_reg_Locked(eRegL dst, memory mem, regXD tmp) %{
predicate(UseSSE>=2);
match(Set dst (LoadLLocked mem));
effect(TEMP tmp);
ins_cost(160);
format %{ "MOVSD $tmp,$mem\t# Atomic volatile long load\n\t"
"MOVD $dst.lo,$tmp\n\t"
"PSRLQ $tmp,32\n\t"
"MOVD $dst.hi,$tmp" %}
! ins_encode %{
! __ movdbl($tmp$$XMMRegister, $mem$$Address);
! __ movdl($dst$$Register, $tmp$$XMMRegister);
! __ psrlq($tmp$$XMMRegister, 32);
! __ movdl(HIGH_FROM_LOW($dst$$Register), $tmp$$XMMRegister);
! %}
ins_pipe( pipe_slow );
%}
// Conditional-store of the updated heap-top.
// Used during allocation of the shared heap.
*** 10131,10232 ****
CmpF_Result(dst));
ins_pipe( pipe_slow );
%}
// float compare and set condition codes in EFLAGS by XMM regs
! instruct cmpXD_cc(eFlagsRegU cr, regXD dst, regXD src, eAXRegI rax) %{
predicate(UseSSE>=2);
! match(Set cr (CmpD dst src));
! effect(KILL rax);
! ins_cost(125);
! format %{ "COMISD $dst,$src\n"
! "\tJNP exit\n"
! "\tMOV ah,1 // saw a NaN, set CF\n"
! "\tSAHF\n"
! "exit:\tNOP // avoid branch to branch" %}
! opcode(0x66, 0x0F, 0x2F);
! ins_encode(OpcP, OpcS, Opcode(tertiary), RegReg(dst, src), cmpF_P6_fixup);
ins_pipe( pipe_slow );
%}
! instruct cmpXD_ccCF(eFlagsRegUCF cr, regXD dst, regXD src) %{
predicate(UseSSE>=2);
! match(Set cr (CmpD dst src));
ins_cost(100);
! format %{ "COMISD $dst,$src" %}
! opcode(0x66, 0x0F, 0x2F);
! ins_encode(OpcP, OpcS, Opcode(tertiary), RegReg(dst, src));
ins_pipe( pipe_slow );
%}
// float compare and set condition codes in EFLAGS by XMM regs
! instruct cmpXD_ccmem(eFlagsRegU cr, regXD dst, memory src, eAXRegI rax) %{
predicate(UseSSE>=2);
! match(Set cr (CmpD dst (LoadD src)));
! effect(KILL rax);
ins_cost(145);
! format %{ "COMISD $dst,$src\n"
! "\tJNP exit\n"
! "\tMOV ah,1 // saw a NaN, set CF\n"
! "\tSAHF\n"
! "exit:\tNOP // avoid branch to branch" %}
! opcode(0x66, 0x0F, 0x2F);
! ins_encode(OpcP, OpcS, Opcode(tertiary), RegMem(dst, src), cmpF_P6_fixup);
ins_pipe( pipe_slow );
%}
! instruct cmpXD_ccmemCF(eFlagsRegUCF cr, regXD dst, memory src) %{
predicate(UseSSE>=2);
! match(Set cr (CmpD dst (LoadD src)));
ins_cost(100);
! format %{ "COMISD $dst,$src" %}
! opcode(0x66, 0x0F, 0x2F);
! ins_encode(OpcP, OpcS, Opcode(tertiary), RegMem(dst, src));
ins_pipe( pipe_slow );
%}
// Compare into -1,0,1 in XMM
! instruct cmpXD_reg(eRegI dst, regXD src1, regXD src2, eFlagsReg cr) %{
predicate(UseSSE>=2);
match(Set dst (CmpD3 src1 src2));
effect(KILL cr);
ins_cost(255);
! format %{ "XOR $dst,$dst\n"
! "\tCOMISD $src1,$src2\n"
! "\tJP,s nan\n"
! "\tJEQ,s exit\n"
! "\tJA,s inc\n"
! "nan:\tDEC $dst\n"
! "\tJMP,s exit\n"
! "inc:\tINC $dst\n"
! "exit:"
%}
- opcode(0x66, 0x0F, 0x2F);
- ins_encode(Xor_Reg(dst), OpcP, OpcS, Opcode(tertiary), RegReg(src1, src2),
- CmpX_Result(dst));
ins_pipe( pipe_slow );
%}
// Compare into -1,0,1 in XMM and memory
! instruct cmpXD_regmem(eRegI dst, regXD src1, memory mem, eFlagsReg cr) %{
predicate(UseSSE>=2);
! match(Set dst (CmpD3 src1 (LoadD mem)));
effect(KILL cr);
ins_cost(275);
! format %{ "COMISD $src1,$mem\n"
! "\tMOV $dst,0\t\t# do not blow flags\n"
! "\tJP,s nan\n"
! "\tJEQ,s exit\n"
! "\tJA,s inc\n"
! "nan:\tDEC $dst\n"
! "\tJMP,s exit\n"
! "inc:\tINC $dst\n"
! "exit:"
%}
- opcode(0x66, 0x0F, 0x2F);
- ins_encode(OpcP, OpcS, Opcode(tertiary), RegMem(src1, mem),
- LdImmI(dst,0x0), CmpX_Result(dst));
ins_pipe( pipe_slow );
%}
instruct subD_reg(regD dst, regD src) %{
--- 9628,9731 ----
CmpF_Result(dst));
ins_pipe( pipe_slow );
%}
// float compare and set condition codes in EFLAGS by XMM regs
! instruct cmpXD_cc(eFlagsRegU cr, regXD src1, regXD src2) %{
predicate(UseSSE>=2);
! match(Set cr (CmpD src1 src2));
! ins_cost(145);
! format %{ "UCOMISD $src1,$src2\n\t"
! "JNP,s exit\n\t"
! "PUSHF\t# saw NaN, set CF\n\t"
! "AND [rsp], #0xffffff2b\n\t"
! "POPF\n"
! "exit:" %}
! ins_encode %{
! __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister);
! emit_cmpfp_fixup(_masm);
! %}
ins_pipe( pipe_slow );
%}
! instruct cmpXD_ccCF(eFlagsRegUCF cr, regXD src1, regXD src2) %{
predicate(UseSSE>=2);
! match(Set cr (CmpD src1 src2));
ins_cost(100);
! format %{ "UCOMISD $src1,$src2" %}
! ins_encode %{
! __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister);
! %}
ins_pipe( pipe_slow );
%}
// float compare and set condition codes in EFLAGS by XMM regs
! instruct cmpXD_ccmem(eFlagsRegU cr, regXD src1, memory src2) %{
predicate(UseSSE>=2);
! match(Set cr (CmpD src1 (LoadD src2)));
ins_cost(145);
! format %{ "UCOMISD $src1,$src2\n\t"
! "JNP,s exit\n\t"
! "PUSHF\t# saw NaN, set CF\n\t"
! "AND [rsp], #0xffffff2b\n\t"
! "POPF\n"
! "exit:" %}
! ins_encode %{
! __ ucomisd($src1$$XMMRegister, $src2$$Address);
! emit_cmpfp_fixup(_masm);
! %}
ins_pipe( pipe_slow );
%}
! instruct cmpXD_ccmemCF(eFlagsRegUCF cr, regXD src1, memory src2) %{
predicate(UseSSE>=2);
! match(Set cr (CmpD src1 (LoadD src2)));
ins_cost(100);
! format %{ "UCOMISD $src1,$src2" %}
! ins_encode %{
! __ ucomisd($src1$$XMMRegister, $src2$$Address);
! %}
ins_pipe( pipe_slow );
%}
// Compare into -1,0,1 in XMM
! instruct cmpXD_reg(xRegI dst, regXD src1, regXD src2, eFlagsReg cr) %{
predicate(UseSSE>=2);
match(Set dst (CmpD3 src1 src2));
effect(KILL cr);
ins_cost(255);
! format %{ "UCOMISD $src1, $src2\n\t"
! "MOV $dst, #-1\n\t"
! "JP,s done\n\t"
! "JB,s done\n\t"
! "SETNE $dst\n\t"
! "MOVZB $dst, $dst\n"
! "done:" %}
! ins_encode %{
! __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister);
! emit_cmpfp3(_masm, $dst$$Register);
%}
ins_pipe( pipe_slow );
%}
// Compare into -1,0,1 in XMM and memory
! instruct cmpXD_regmem(xRegI dst, regXD src1, memory src2, eFlagsReg cr) %{
predicate(UseSSE>=2);
! match(Set dst (CmpD3 src1 (LoadD src2)));
effect(KILL cr);
ins_cost(275);
! format %{ "UCOMISD $src1, $src2\n\t"
! "MOV $dst, #-1\n\t"
! "JP,s done\n\t"
! "JB,s done\n\t"
! "SETNE $dst\n\t"
! "MOVZB $dst, $dst\n"
! "done:" %}
! ins_encode %{
! __ ucomisd($src1$$XMMRegister, $src2$$Address);
! emit_cmpfp3(_masm, $dst$$Register);
%}
ins_pipe( pipe_slow );
%}
instruct subD_reg(regD dst, regD src) %{
*** 10281,10292 ****
%}
instruct absXD_reg( regXD dst ) %{
predicate(UseSSE>=2);
match(Set dst (AbsD dst));
format %{ "ANDPD $dst,[0x7FFFFFFFFFFFFFFF]\t# ABS D by sign masking" %}
! ins_encode( AbsXD_encoding(dst));
ins_pipe( pipe_slow );
%}
instruct negD_reg(regDPR1 dst, regDPR1 src) %{
predicate(UseSSE<=1);
--- 9780,9795 ----
%}
instruct absXD_reg( regXD dst ) %{
predicate(UseSSE>=2);
match(Set dst (AbsD dst));
+ ins_cost(150);
format %{ "ANDPD $dst,[0x7FFFFFFFFFFFFFFF]\t# ABS D by sign masking" %}
! ins_encode %{
! __ andpd($dst$$XMMRegister,
! ExternalAddress((address)double_signmask_pool));
! %}
ins_pipe( pipe_slow );
%}
instruct negD_reg(regDPR1 dst, regDPR1 src) %{
predicate(UseSSE<=1);
*** 10299,10308 ****
--- 9802,9812 ----
%}
instruct negXD_reg( regXD dst ) %{
predicate(UseSSE>=2);
match(Set dst (NegD dst));
+ ins_cost(150);
format %{ "XORPD $dst,[0x8000000000000000]\t# CHS D by sign flipping" %}
ins_encode %{
__ xorpd($dst$$XMMRegister,
ExternalAddress((address)double_signflip_pool));
%}
*** 10412,10422 ****
// Add two double precision floating point values in xmm
instruct addXD_reg(regXD dst, regXD src) %{
predicate(UseSSE>=2);
match(Set dst (AddD dst src));
format %{ "ADDSD $dst,$src" %}
! ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x58), RegReg(dst, src));
ins_pipe( pipe_slow );
%}
instruct addXD_imm(regXD dst, immXD con) %{
predicate(UseSSE>=2);
--- 9916,9928 ----
// Add two double precision floating point values in xmm
instruct addXD_reg(regXD dst, regXD src) %{
predicate(UseSSE>=2);
match(Set dst (AddD dst src));
format %{ "ADDSD $dst,$src" %}
! ins_encode %{
! __ addsd($dst$$XMMRegister, $src$$XMMRegister);
! %}
ins_pipe( pipe_slow );
%}
instruct addXD_imm(regXD dst, immXD con) %{
predicate(UseSSE>=2);
*** 10430,10455 ****
instruct addXD_mem(regXD dst, memory mem) %{
predicate(UseSSE>=2);
match(Set dst (AddD dst (LoadD mem)));
format %{ "ADDSD $dst,$mem" %}
! ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x58), RegMem(dst,mem));
ins_pipe( pipe_slow );
%}
// Sub two double precision floating point values in xmm
instruct subXD_reg(regXD dst, regXD src) %{
predicate(UseSSE>=2);
match(Set dst (SubD dst src));
format %{ "SUBSD $dst,$src" %}
! ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x5C), RegReg(dst, src));
ins_pipe( pipe_slow );
%}
instruct subXD_imm(regXD dst, immXD con) %{
predicate(UseSSE>=2);
match(Set dst (SubD dst con));
format %{ "SUBSD $dst,[$constantaddress]\t# load from constant table: double=$con" %}
ins_encode %{
__ subsd($dst$$XMMRegister, $constantaddress($con));
%}
ins_pipe(pipe_slow);
--- 9936,9967 ----
instruct addXD_mem(regXD dst, memory mem) %{
predicate(UseSSE>=2);
match(Set dst (AddD dst (LoadD mem)));
format %{ "ADDSD $dst,$mem" %}
! ins_encode %{
! __ addsd($dst$$XMMRegister, $mem$$Address);
! %}
ins_pipe( pipe_slow );
%}
// Sub two double precision floating point values in xmm
instruct subXD_reg(regXD dst, regXD src) %{
predicate(UseSSE>=2);
match(Set dst (SubD dst src));
+ ins_cost(150);
format %{ "SUBSD $dst,$src" %}
! ins_encode %{
! __ subsd($dst$$XMMRegister, $src$$XMMRegister);
! %}
ins_pipe( pipe_slow );
%}
instruct subXD_imm(regXD dst, immXD con) %{
predicate(UseSSE>=2);
match(Set dst (SubD dst con));
+ ins_cost(150);
format %{ "SUBSD $dst,[$constantaddress]\t# load from constant table: double=$con" %}
ins_encode %{
__ subsd($dst$$XMMRegister, $constantaddress($con));
%}
ins_pipe(pipe_slow);
*** 10456,10476 ****
%}
instruct subXD_mem(regXD dst, memory mem) %{
predicate(UseSSE>=2);
match(Set dst (SubD dst (LoadD mem)));
format %{ "SUBSD $dst,$mem" %}
! ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x5C), RegMem(dst,mem));
ins_pipe( pipe_slow );
%}
// Mul two double precision floating point values in xmm
instruct mulXD_reg(regXD dst, regXD src) %{
predicate(UseSSE>=2);
match(Set dst (MulD dst src));
format %{ "MULSD $dst,$src" %}
! ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x59), RegReg(dst, src));
ins_pipe( pipe_slow );
%}
instruct mulXD_imm(regXD dst, immXD con) %{
predicate(UseSSE>=2);
--- 9968,9993 ----
%}
instruct subXD_mem(regXD dst, memory mem) %{
predicate(UseSSE>=2);
match(Set dst (SubD dst (LoadD mem)));
+ ins_cost(150);
format %{ "SUBSD $dst,$mem" %}
! ins_encode %{
! __ subsd($dst$$XMMRegister, $mem$$Address);
! %}
ins_pipe( pipe_slow );
%}
// Mul two double precision floating point values in xmm
instruct mulXD_reg(regXD dst, regXD src) %{
predicate(UseSSE>=2);
match(Set dst (MulD dst src));
format %{ "MULSD $dst,$src" %}
! ins_encode %{
! __ mulsd($dst$$XMMRegister, $src$$XMMRegister);
! %}
ins_pipe( pipe_slow );
%}
instruct mulXD_imm(regXD dst, immXD con) %{
predicate(UseSSE>=2);
*** 10484,10504 ****
instruct mulXD_mem(regXD dst, memory mem) %{
predicate(UseSSE>=2);
match(Set dst (MulD dst (LoadD mem)));
format %{ "MULSD $dst,$mem" %}
! ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x59), RegMem(dst,mem));
ins_pipe( pipe_slow );
%}
// Div two double precision floating point values in xmm
instruct divXD_reg(regXD dst, regXD src) %{
predicate(UseSSE>=2);
match(Set dst (DivD dst src));
format %{ "DIVSD $dst,$src" %}
opcode(0xF2, 0x0F, 0x5E);
! ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x5E), RegReg(dst, src));
ins_pipe( pipe_slow );
%}
instruct divXD_imm(regXD dst, immXD con) %{
predicate(UseSSE>=2);
--- 10001,10025 ----
instruct mulXD_mem(regXD dst, memory mem) %{
predicate(UseSSE>=2);
match(Set dst (MulD dst (LoadD mem)));
format %{ "MULSD $dst,$mem" %}
! ins_encode %{
! __ mulsd($dst$$XMMRegister, $mem$$Address);
! %}
ins_pipe( pipe_slow );
%}
// Div two double precision floating point values in xmm
instruct divXD_reg(regXD dst, regXD src) %{
predicate(UseSSE>=2);
match(Set dst (DivD dst src));
format %{ "DIVSD $dst,$src" %}
opcode(0xF2, 0x0F, 0x5E);
! ins_encode %{
! __ divsd($dst$$XMMRegister, $src$$XMMRegister);
! %}
ins_pipe( pipe_slow );
%}
instruct divXD_imm(regXD dst, immXD con) %{
predicate(UseSSE>=2);
*** 10512,10522 ****
instruct divXD_mem(regXD dst, memory mem) %{
predicate(UseSSE>=2);
match(Set dst (DivD dst (LoadD mem)));
format %{ "DIVSD $dst,$mem" %}
! ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x5E), RegMem(dst,mem));
ins_pipe( pipe_slow );
%}
instruct mulD_reg(regD dst, regD src) %{
--- 10033,10045 ----
instruct divXD_mem(regXD dst, memory mem) %{
predicate(UseSSE>=2);
match(Set dst (DivD dst (LoadD mem)));
format %{ "DIVSD $dst,$mem" %}
! ins_encode %{
! __ divsd($dst$$XMMRegister, $mem$$Address);
! %}
ins_pipe( pipe_slow );
%}
instruct mulD_reg(regD dst, regD src) %{
*** 11144,11243 ****
CmpF_Result(dst));
ins_pipe( pipe_slow );
%}
// float compare and set condition codes in EFLAGS by XMM regs
! instruct cmpX_cc(eFlagsRegU cr, regX dst, regX src, eAXRegI rax) %{
predicate(UseSSE>=1);
! match(Set cr (CmpF dst src));
! effect(KILL rax);
ins_cost(145);
! format %{ "COMISS $dst,$src\n"
! "\tJNP exit\n"
! "\tMOV ah,1 // saw a NaN, set CF\n"
! "\tSAHF\n"
! "exit:\tNOP // avoid branch to branch" %}
! opcode(0x0F, 0x2F);
! ins_encode(OpcP, OpcS, RegReg(dst, src), cmpF_P6_fixup);
ins_pipe( pipe_slow );
%}
! instruct cmpX_ccCF(eFlagsRegUCF cr, regX dst, regX src) %{
predicate(UseSSE>=1);
! match(Set cr (CmpF dst src));
ins_cost(100);
! format %{ "COMISS $dst,$src" %}
! opcode(0x0F, 0x2F);
! ins_encode(OpcP, OpcS, RegReg(dst, src));
ins_pipe( pipe_slow );
%}
// float compare and set condition codes in EFLAGS by XMM regs
! instruct cmpX_ccmem(eFlagsRegU cr, regX dst, memory src, eAXRegI rax) %{
predicate(UseSSE>=1);
! match(Set cr (CmpF dst (LoadF src)));
! effect(KILL rax);
ins_cost(165);
! format %{ "COMISS $dst,$src\n"
! "\tJNP exit\n"
! "\tMOV ah,1 // saw a NaN, set CF\n"
! "\tSAHF\n"
! "exit:\tNOP // avoid branch to branch" %}
! opcode(0x0F, 0x2F);
! ins_encode(OpcP, OpcS, RegMem(dst, src), cmpF_P6_fixup);
ins_pipe( pipe_slow );
%}
! instruct cmpX_ccmemCF(eFlagsRegUCF cr, regX dst, memory src) %{
predicate(UseSSE>=1);
! match(Set cr (CmpF dst (LoadF src)));
ins_cost(100);
! format %{ "COMISS $dst,$src" %}
! opcode(0x0F, 0x2F);
! ins_encode(OpcP, OpcS, RegMem(dst, src));
ins_pipe( pipe_slow );
%}
// Compare into -1,0,1 in XMM
! instruct cmpX_reg(eRegI dst, regX src1, regX src2, eFlagsReg cr) %{
predicate(UseSSE>=1);
match(Set dst (CmpF3 src1 src2));
effect(KILL cr);
ins_cost(255);
! format %{ "XOR $dst,$dst\n"
! "\tCOMISS $src1,$src2\n"
! "\tJP,s nan\n"
! "\tJEQ,s exit\n"
! "\tJA,s inc\n"
! "nan:\tDEC $dst\n"
! "\tJMP,s exit\n"
! "inc:\tINC $dst\n"
! "exit:"
%}
- opcode(0x0F, 0x2F);
- ins_encode(Xor_Reg(dst), OpcP, OpcS, RegReg(src1, src2), CmpX_Result(dst));
ins_pipe( pipe_slow );
%}
// Compare into -1,0,1 in XMM and memory
! instruct cmpX_regmem(eRegI dst, regX src1, memory mem, eFlagsReg cr) %{
predicate(UseSSE>=1);
! match(Set dst (CmpF3 src1 (LoadF mem)));
effect(KILL cr);
ins_cost(275);
! format %{ "COMISS $src1,$mem\n"
! "\tMOV $dst,0\t\t# do not blow flags\n"
! "\tJP,s nan\n"
! "\tJEQ,s exit\n"
! "\tJA,s inc\n"
! "nan:\tDEC $dst\n"
! "\tJMP,s exit\n"
! "inc:\tINC $dst\n"
! "exit:"
%}
- opcode(0x0F, 0x2F);
- ins_encode(OpcP, OpcS, RegMem(src1, mem), LdImmI(dst,0x0), CmpX_Result(dst));
ins_pipe( pipe_slow );
%}
// Spill to obtain 24-bit precision
instruct subF24_reg(stackSlotF dst, regF src1, regF src2) %{
--- 10667,10770 ----
CmpF_Result(dst));
ins_pipe( pipe_slow );
%}
// float compare and set condition codes in EFLAGS by XMM regs
! instruct cmpX_cc(eFlagsRegU cr, regX src1, regX src2) %{
predicate(UseSSE>=1);
! match(Set cr (CmpF src1 src2));
ins_cost(145);
! format %{ "UCOMISS $src1,$src2\n\t"
! "JNP,s exit\n\t"
! "PUSHF\t# saw NaN, set CF\n\t"
! "AND [rsp], #0xffffff2b\n\t"
! "POPF\n"
! "exit:" %}
! ins_encode %{
! __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister);
! emit_cmpfp_fixup(_masm);
! %}
ins_pipe( pipe_slow );
%}
! instruct cmpX_ccCF(eFlagsRegUCF cr, regX src1, regX src2) %{
predicate(UseSSE>=1);
! match(Set cr (CmpF src1 src2));
ins_cost(100);
! format %{ "UCOMISS $src1,$src2" %}
! ins_encode %{
! __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister);
! %}
ins_pipe( pipe_slow );
%}
// float compare and set condition codes in EFLAGS by XMM regs
! instruct cmpX_ccmem(eFlagsRegU cr, regX src1, memory src2) %{
predicate(UseSSE>=1);
! match(Set cr (CmpF src1 (LoadF src2)));
ins_cost(165);
! format %{ "UCOMISS $src1,$src2\n\t"
! "JNP,s exit\n\t"
! "PUSHF\t# saw NaN, set CF\n\t"
! "AND [rsp], #0xffffff2b\n\t"
! "POPF\n"
! "exit:" %}
! ins_encode %{
! __ ucomiss($src1$$XMMRegister, $src2$$Address);
! emit_cmpfp_fixup(_masm);
! %}
ins_pipe( pipe_slow );
%}
! instruct cmpX_ccmemCF(eFlagsRegUCF cr, regX src1, memory src2) %{
predicate(UseSSE>=1);
! match(Set cr (CmpF src1 (LoadF src2)));
ins_cost(100);
! format %{ "UCOMISS $src1,$src2" %}
! ins_encode %{
! __ ucomiss($src1$$XMMRegister, $src2$$Address);
! %}
ins_pipe( pipe_slow );
%}
// Compare into -1,0,1 in XMM
! instruct cmpX_reg(xRegI dst, regX src1, regX src2, eFlagsReg cr) %{
predicate(UseSSE>=1);
match(Set dst (CmpF3 src1 src2));
effect(KILL cr);
ins_cost(255);
! format %{ "UCOMISS $src1, $src2\n\t"
! "MOV $dst, #-1\n\t"
! "JP,s done\n\t"
! "JB,s done\n\t"
! "SETNE $dst\n\t"
! "MOVZB $dst, $dst\n"
! "done:" %}
! ins_encode %{
! __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister);
! emit_cmpfp3(_masm, $dst$$Register);
%}
ins_pipe( pipe_slow );
%}
// Compare into -1,0,1 in XMM and memory
! instruct cmpX_regmem(xRegI dst, regX src1, memory src2, eFlagsReg cr) %{
predicate(UseSSE>=1);
! match(Set dst (CmpF3 src1 (LoadF src2)));
effect(KILL cr);
ins_cost(275);
! format %{ "UCOMISS $src1, $src2\n\t"
! "MOV $dst, #-1\n\t"
! "JP,s done\n\t"
! "JB,s done\n\t"
! "SETNE $dst\n\t"
! "MOVZB $dst, $dst\n"
! "done:" %}
! ins_encode %{
! __ ucomiss($src1$$XMMRegister, $src2$$Address);
! emit_cmpfp3(_masm, $dst$$Register);
%}
ins_pipe( pipe_slow );
%}
// Spill to obtain 24-bit precision
instruct subF24_reg(stackSlotF dst, regF src1, regF src2) %{
*** 11293,11303 ****
// Add two single precision floating point values in xmm
instruct addX_reg(regX dst, regX src) %{
predicate(UseSSE>=1);
match(Set dst (AddF dst src));
format %{ "ADDSS $dst,$src" %}
! ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x58), RegReg(dst, src));
ins_pipe( pipe_slow );
%}
instruct addX_imm(regX dst, immXF con) %{
predicate(UseSSE>=1);
--- 10820,10832 ----
// Add two single precision floating point values in xmm
instruct addX_reg(regX dst, regX src) %{
predicate(UseSSE>=1);
match(Set dst (AddF dst src));
format %{ "ADDSS $dst,$src" %}
! ins_encode %{
! __ addss($dst$$XMMRegister, $src$$XMMRegister);
! %}
ins_pipe( pipe_slow );
%}
instruct addX_imm(regX dst, immXF con) %{
predicate(UseSSE>=1);
*** 11311,11336 ****
instruct addX_mem(regX dst, memory mem) %{
predicate(UseSSE>=1);
match(Set dst (AddF dst (LoadF mem)));
format %{ "ADDSS $dst,$mem" %}
! ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x58), RegMem(dst, mem));
ins_pipe( pipe_slow );
%}
// Subtract two single precision floating point values in xmm
instruct subX_reg(regX dst, regX src) %{
predicate(UseSSE>=1);
match(Set dst (SubF dst src));
format %{ "SUBSS $dst,$src" %}
! ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x5C), RegReg(dst, src));
ins_pipe( pipe_slow );
%}
instruct subX_imm(regX dst, immXF con) %{
predicate(UseSSE>=1);
match(Set dst (SubF dst con));
format %{ "SUBSS $dst,[$constantaddress]\t# load from constant table: float=$con" %}
ins_encode %{
__ subss($dst$$XMMRegister, $constantaddress($con));
%}
ins_pipe(pipe_slow);
--- 10840,10871 ----
instruct addX_mem(regX dst, memory mem) %{
predicate(UseSSE>=1);
match(Set dst (AddF dst (LoadF mem)));
format %{ "ADDSS $dst,$mem" %}
! ins_encode %{
! __ addss($dst$$XMMRegister, $mem$$Address);
! %}
ins_pipe( pipe_slow );
%}
// Subtract two single precision floating point values in xmm
instruct subX_reg(regX dst, regX src) %{
predicate(UseSSE>=1);
match(Set dst (SubF dst src));
+ ins_cost(150);
format %{ "SUBSS $dst,$src" %}
! ins_encode %{
! __ subss($dst$$XMMRegister, $src$$XMMRegister);
! %}
ins_pipe( pipe_slow );
%}
instruct subX_imm(regX dst, immXF con) %{
predicate(UseSSE>=1);
match(Set dst (SubF dst con));
+ ins_cost(150);
format %{ "SUBSS $dst,[$constantaddress]\t# load from constant table: float=$con" %}
ins_encode %{
__ subss($dst$$XMMRegister, $constantaddress($con));
%}
ins_pipe(pipe_slow);
*** 11337,11357 ****
%}
instruct subX_mem(regX dst, memory mem) %{
predicate(UseSSE>=1);
match(Set dst (SubF dst (LoadF mem)));
format %{ "SUBSS $dst,$mem" %}
! ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x5C), RegMem(dst,mem));
ins_pipe( pipe_slow );
%}
// Multiply two single precision floating point values in xmm
instruct mulX_reg(regX dst, regX src) %{
predicate(UseSSE>=1);
match(Set dst (MulF dst src));
format %{ "MULSS $dst,$src" %}
! ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x59), RegReg(dst, src));
ins_pipe( pipe_slow );
%}
instruct mulX_imm(regX dst, immXF con) %{
predicate(UseSSE>=1);
--- 10872,10897 ----
%}
instruct subX_mem(regX dst, memory mem) %{
predicate(UseSSE>=1);
match(Set dst (SubF dst (LoadF mem)));
+ ins_cost(150);
format %{ "SUBSS $dst,$mem" %}
! ins_encode %{
! __ subss($dst$$XMMRegister, $mem$$Address);
! %}
ins_pipe( pipe_slow );
%}
// Multiply two single precision floating point values in xmm
instruct mulX_reg(regX dst, regX src) %{
predicate(UseSSE>=1);
match(Set dst (MulF dst src));
format %{ "MULSS $dst,$src" %}
! ins_encode %{
! __ mulss($dst$$XMMRegister, $src$$XMMRegister);
! %}
ins_pipe( pipe_slow );
%}
instruct mulX_imm(regX dst, immXF con) %{
predicate(UseSSE>=1);
*** 11365,11384 ****
instruct mulX_mem(regX dst, memory mem) %{
predicate(UseSSE>=1);
match(Set dst (MulF dst (LoadF mem)));
format %{ "MULSS $dst,$mem" %}
! ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x59), RegMem(dst,mem));
ins_pipe( pipe_slow );
%}
// Divide two single precision floating point values in xmm
instruct divX_reg(regX dst, regX src) %{
predicate(UseSSE>=1);
match(Set dst (DivF dst src));
format %{ "DIVSS $dst,$src" %}
! ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x5E), RegReg(dst, src));
ins_pipe( pipe_slow );
%}
instruct divX_imm(regX dst, immXF con) %{
predicate(UseSSE>=1);
--- 10905,10928 ----
instruct mulX_mem(regX dst, memory mem) %{
predicate(UseSSE>=1);
match(Set dst (MulF dst (LoadF mem)));
format %{ "MULSS $dst,$mem" %}
! ins_encode %{
! __ mulss($dst$$XMMRegister, $mem$$Address);
! %}
ins_pipe( pipe_slow );
%}
// Divide two single precision floating point values in xmm
instruct divX_reg(regX dst, regX src) %{
predicate(UseSSE>=1);
match(Set dst (DivF dst src));
format %{ "DIVSS $dst,$src" %}
! ins_encode %{
! __ divss($dst$$XMMRegister, $src$$XMMRegister);
! %}
ins_pipe( pipe_slow );
%}
instruct divX_imm(regX dst, immXF con) %{
predicate(UseSSE>=1);
*** 11392,11436 ****
instruct divX_mem(regX dst, memory mem) %{
predicate(UseSSE>=1);
match(Set dst (DivF dst (LoadF mem)));
format %{ "DIVSS $dst,$mem" %}
! ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x5E), RegMem(dst,mem));
ins_pipe( pipe_slow );
%}
// Get the square root of a single precision floating point values in xmm
instruct sqrtX_reg(regX dst, regX src) %{
predicate(UseSSE>=1);
match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
format %{ "SQRTSS $dst,$src" %}
! ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x51), RegReg(dst, src));
ins_pipe( pipe_slow );
%}
instruct sqrtX_mem(regX dst, memory mem) %{
predicate(UseSSE>=1);
match(Set dst (ConvD2F (SqrtD (ConvF2D (LoadF mem)))));
format %{ "SQRTSS $dst,$mem" %}
! ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x51), RegMem(dst, mem));
ins_pipe( pipe_slow );
%}
// Get the square root of a double precision floating point values in xmm
instruct sqrtXD_reg(regXD dst, regXD src) %{
predicate(UseSSE>=2);
match(Set dst (SqrtD src));
format %{ "SQRTSD $dst,$src" %}
! ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x51), RegReg(dst, src));
ins_pipe( pipe_slow );
%}
instruct sqrtXD_mem(regXD dst, memory mem) %{
predicate(UseSSE>=2);
match(Set dst (SqrtD (LoadD mem)));
format %{ "SQRTSD $dst,$mem" %}
! ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x51), RegMem(dst, mem));
ins_pipe( pipe_slow );
%}
instruct absF_reg(regFPR1 dst, regFPR1 src) %{
predicate(UseSSE==0);
--- 10936,10994 ----
instruct divX_mem(regX dst, memory mem) %{
predicate(UseSSE>=1);
match(Set dst (DivF dst (LoadF mem)));
format %{ "DIVSS $dst,$mem" %}
! ins_encode %{
! __ divss($dst$$XMMRegister, $mem$$Address);
! %}
ins_pipe( pipe_slow );
%}
// Get the square root of a single precision floating point values in xmm
instruct sqrtX_reg(regX dst, regX src) %{
predicate(UseSSE>=1);
match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
+ ins_cost(150);
format %{ "SQRTSS $dst,$src" %}
! ins_encode %{
! __ sqrtss($dst$$XMMRegister, $src$$XMMRegister);
! %}
ins_pipe( pipe_slow );
%}
instruct sqrtX_mem(regX dst, memory mem) %{
predicate(UseSSE>=1);
match(Set dst (ConvD2F (SqrtD (ConvF2D (LoadF mem)))));
+ ins_cost(150);
format %{ "SQRTSS $dst,$mem" %}
! ins_encode %{
! __ sqrtss($dst$$XMMRegister, $mem$$Address);
! %}
ins_pipe( pipe_slow );
%}
// Get the square root of a double precision floating point values in xmm
instruct sqrtXD_reg(regXD dst, regXD src) %{
predicate(UseSSE>=2);
match(Set dst (SqrtD src));
+ ins_cost(150);
format %{ "SQRTSD $dst,$src" %}
! ins_encode %{
! __ sqrtsd($dst$$XMMRegister, $src$$XMMRegister);
! %}
ins_pipe( pipe_slow );
%}
instruct sqrtXD_mem(regXD dst, memory mem) %{
predicate(UseSSE>=2);
match(Set dst (SqrtD (LoadD mem)));
+ ins_cost(150);
format %{ "SQRTSD $dst,$mem" %}
! ins_encode %{
! __ sqrtsd($dst$$XMMRegister, $mem$$Address);
! %}
ins_pipe( pipe_slow );
%}
instruct absF_reg(regFPR1 dst, regFPR1 src) %{
predicate(UseSSE==0);
*** 11443,11454 ****
%}
instruct absX_reg(regX dst ) %{
predicate(UseSSE>=1);
match(Set dst (AbsF dst));
format %{ "ANDPS $dst,[0x7FFFFFFF]\t# ABS F by sign masking" %}
! ins_encode( AbsXF_encoding(dst));
ins_pipe( pipe_slow );
%}
instruct negF_reg(regFPR1 dst, regFPR1 src) %{
predicate(UseSSE==0);
--- 11001,11016 ----
%}
instruct absX_reg(regX dst ) %{
predicate(UseSSE>=1);
match(Set dst (AbsF dst));
+ ins_cost(150);
format %{ "ANDPS $dst,[0x7FFFFFFF]\t# ABS F by sign masking" %}
! ins_encode %{
! __ andps($dst$$XMMRegister,
! ExternalAddress((address)float_signmask_pool));
! %}
ins_pipe( pipe_slow );
%}
instruct negF_reg(regFPR1 dst, regFPR1 src) %{
predicate(UseSSE==0);
*** 11461,11472 ****
%}
instruct negX_reg( regX dst ) %{
predicate(UseSSE>=1);
match(Set dst (NegF dst));
format %{ "XORPS $dst,[0x80000000]\t# CHS F by sign flipping" %}
! ins_encode( NegXF_encoding(dst));
ins_pipe( pipe_slow );
%}
// Cisc-alternate to addF_reg
// Spill to obtain 24-bit precision
--- 11023,11038 ----
%}
instruct negX_reg( regX dst ) %{
predicate(UseSSE>=1);
match(Set dst (NegF dst));
+ ins_cost(150);
format %{ "XORPS $dst,[0x80000000]\t# CHS F by sign flipping" %}
! ins_encode %{
! __ xorps($dst$$XMMRegister,
! ExternalAddress((address)float_signflip_pool));
! %}
ins_pipe( pipe_slow );
%}
// Cisc-alternate to addF_reg
// Spill to obtain 24-bit precision
*** 11868,11888 ****
effect( KILL cr );
format %{ "SUB ESP,4\n\t"
"FST_S [ESP],$src\t# F-round\n\t"
"MOVSS $dst,[ESP]\n\t"
"ADD ESP,4" %}
! ins_encode( D2X_encoding(dst, src) );
ins_pipe( pipe_slow );
%}
// Force rounding double precision to single precision
instruct convXD2X_reg(regX dst, regXD src) %{
predicate(UseSSE>=2);
match(Set dst (ConvD2F src));
format %{ "CVTSD2SS $dst,$src\t# F-round" %}
! opcode(0xF2, 0x0F, 0x5A);
! ins_encode( OpcP, OpcS, Opcode(tertiary), RegReg(dst, src));
ins_pipe( pipe_slow );
%}
instruct convF2D_reg_reg(regD dst, regF src) %{
predicate(UseSSE==0);
--- 11434,11465 ----
effect( KILL cr );
format %{ "SUB ESP,4\n\t"
"FST_S [ESP],$src\t# F-round\n\t"
"MOVSS $dst,[ESP]\n\t"
"ADD ESP,4" %}
! ins_encode %{
! __ subptr(rsp, 4);
! if ($src$$reg != FPR1L_enc) {
! __ fld_s($src$$reg-1);
! __ fstp_s(Address(rsp, 0));
! } else {
! __ fst_s(Address(rsp, 0));
! }
! __ movflt($dst$$XMMRegister, Address(rsp, 0));
! __ addptr(rsp, 4);
! %}
ins_pipe( pipe_slow );
%}
// Force rounding double precision to single precision
instruct convXD2X_reg(regX dst, regXD src) %{
predicate(UseSSE>=2);
match(Set dst (ConvD2F src));
format %{ "CVTSD2SS $dst,$src\t# F-round" %}
! ins_encode %{
! __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister);
! %}
ins_pipe( pipe_slow );
%}
instruct convF2D_reg_reg(regD dst, regF src) %{
predicate(UseSSE==0);
*** 11908,11927 ****
format %{ "SUB ESP,4\n\t"
"MOVSS [ESP] $src\n\t"
"FLD_S [ESP]\n\t"
"ADD ESP,4\n\t"
"FSTP $dst\t# D-round" %}
! ins_encode( X2D_encoding(dst, src), Pop_Reg_D(dst));
ins_pipe( pipe_slow );
%}
instruct convX2XD_reg(regXD dst, regX src) %{
predicate(UseSSE>=2);
match(Set dst (ConvF2D src));
format %{ "CVTSS2SD $dst,$src\t# D-round" %}
! opcode(0xF3, 0x0F, 0x5A);
! ins_encode( OpcP, OpcS, Opcode(tertiary), RegReg(dst, src));
ins_pipe( pipe_slow );
%}
// Convert a double to an int. If the double is a NAN, stuff a zero in instead.
instruct convD2I_reg_reg( eAXRegI dst, eDXRegI tmp, regD src, eFlagsReg cr ) %{
--- 11485,11511 ----
format %{ "SUB ESP,4\n\t"
"MOVSS [ESP] $src\n\t"
"FLD_S [ESP]\n\t"
"ADD ESP,4\n\t"
"FSTP $dst\t# D-round" %}
! ins_encode %{
! __ subptr(rsp, 4);
! __ movflt(Address(rsp, 0), $src$$XMMRegister);
! __ fld_s(Address(rsp, 0));
! __ addptr(rsp, 4);
! __ fstp_d($dst$$reg);
! %}
ins_pipe( pipe_slow );
%}
instruct convX2XD_reg(regXD dst, regX src) %{
predicate(UseSSE>=2);
match(Set dst (ConvF2D src));
format %{ "CVTSS2SD $dst,$src\t# D-round" %}
! ins_encode %{
! __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister);
! %}
ins_pipe( pipe_slow );
%}
// Convert a double to an int. If the double is a NAN, stuff a zero in instead.
instruct convD2I_reg_reg( eAXRegI dst, eDXRegI tmp, regD src, eFlagsReg cr ) %{
*** 11955,11966 ****
"MOVSD [ESP], $src\n\t"
"FLD_D [ESP]\n\t"
"ADD ESP, 8\n\t"
"CALL d2i_wrapper\n"
"fast:" %}
! opcode(0x1); // double-precision conversion
! ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x2C), FX2I_encoding(src,dst));
ins_pipe( pipe_slow );
%}
instruct convD2L_reg_reg( eADXRegL dst, regD src, eFlagsReg cr ) %{
predicate(UseSSE<=1);
--- 11539,11560 ----
"MOVSD [ESP], $src\n\t"
"FLD_D [ESP]\n\t"
"ADD ESP, 8\n\t"
"CALL d2i_wrapper\n"
"fast:" %}
! ins_encode %{
! Label fast;
! __ cvttsd2sil($dst$$Register, $src$$XMMRegister);
! __ cmpl($dst$$Register, 0x80000000);
! __ jccb(Assembler::notEqual, fast);
! __ subptr(rsp, 8);
! __ movdbl(Address(rsp, 0), $src$$XMMRegister);
! __ fld_d(Address(rsp, 0));
! __ addptr(rsp, 8);
! __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::d2i_wrapper())));
! __ bind(fast);
! %}
ins_pipe( pipe_slow );
%}
instruct convD2L_reg_reg( eADXRegL dst, regD src, eFlagsReg cr ) %{
predicate(UseSSE<=1);
*** 12002,12014 ****
"TEST EAX,EAX\n\t"
"JNE,s fast\n\t"
"SUB ESP,8\n\t"
"MOVSD [ESP],$src\n\t"
"FLD_D [ESP]\n\t"
"CALL d2l_wrapper\n"
"fast:" %}
! ins_encode( XD2L_encoding(src) );
ins_pipe( pipe_slow );
%}
// Convert a double to an int. Java semantics require we do complex
// manglations in the corner cases. So we set the rounding mode to
--- 11596,11635 ----
"TEST EAX,EAX\n\t"
"JNE,s fast\n\t"
"SUB ESP,8\n\t"
"MOVSD [ESP],$src\n\t"
"FLD_D [ESP]\n\t"
+ "ADD ESP,8\n\t"
"CALL d2l_wrapper\n"
"fast:" %}
! ins_encode %{
! Label fast;
! __ subptr(rsp, 8);
! __ movdbl(Address(rsp, 0), $src$$XMMRegister);
! __ fld_d(Address(rsp, 0));
! __ fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_trunc()));
! __ fistp_d(Address(rsp, 0));
! // Restore the rounding mode, mask the exception
! if (Compile::current()->in_24_bit_fp_mode()) {
! __ fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_24()));
! } else {
! __ fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std()));
! }
! // Load the converted long, adjust CPU stack
! __ pop(rax);
! __ pop(rdx);
! __ cmpl(rdx, 0x80000000);
! __ jccb(Assembler::notEqual, fast);
! __ testl(rax, rax);
! __ jccb(Assembler::notEqual, fast);
! __ subptr(rsp, 8);
! __ movdbl(Address(rsp, 0), $src$$XMMRegister);
! __ fld_d(Address(rsp, 0));
! __ addptr(rsp, 8);
! __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::d2l_wrapper())));
! __ bind(fast);
! %}
ins_pipe( pipe_slow );
%}
// Convert a double to an int. Java semantics require we do complex
// manglations in the corner cases. So we set the rounding mode to
*** 12048,12059 ****
"MOVSS [ESP], $src\n\t"
"FLD [ESP]\n\t"
"ADD ESP, 4\n\t"
"CALL d2i_wrapper\n"
"fast:" %}
! opcode(0x0); // single-precision conversion
! ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x2C), FX2I_encoding(src,dst));
ins_pipe( pipe_slow );
%}
instruct convF2L_reg_reg( eADXRegL dst, regF src, eFlagsReg cr ) %{
predicate(UseSSE==0);
--- 11669,11690 ----
"MOVSS [ESP], $src\n\t"
"FLD [ESP]\n\t"
"ADD ESP, 4\n\t"
"CALL d2i_wrapper\n"
"fast:" %}
! ins_encode %{
! Label fast;
! __ cvttss2sil($dst$$Register, $src$$XMMRegister);
! __ cmpl($dst$$Register, 0x80000000);
! __ jccb(Assembler::notEqual, fast);
! __ subptr(rsp, 4);
! __ movflt(Address(rsp, 0), $src$$XMMRegister);
! __ fld_s(Address(rsp, 0));
! __ addptr(rsp, 4);
! __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::d2i_wrapper())));
! __ bind(fast);
! %}
ins_pipe( pipe_slow );
%}
instruct convF2L_reg_reg( eADXRegL dst, regF src, eFlagsReg cr ) %{
predicate(UseSSE==0);
*** 12099,12109 ****
"MOVSS [ESP],$src\n\t"
"FLD_S [ESP]\n\t"
"ADD ESP,4\n\t"
"CALL d2l_wrapper\n"
"fast:" %}
! ins_encode( X2L_encoding(src) );
ins_pipe( pipe_slow );
%}
instruct convI2D_reg(regD dst, stackSlotI src) %{
predicate( UseSSE<=1 );
--- 11730,11766 ----
"MOVSS [ESP],$src\n\t"
"FLD_S [ESP]\n\t"
"ADD ESP,4\n\t"
"CALL d2l_wrapper\n"
"fast:" %}
! ins_encode %{
! Label fast;
! __ subptr(rsp, 8);
! __ movflt(Address(rsp, 0), $src$$XMMRegister);
! __ fld_s(Address(rsp, 0));
! __ fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_trunc()));
! __ fistp_d(Address(rsp, 0));
! // Restore the rounding mode, mask the exception
! if (Compile::current()->in_24_bit_fp_mode()) {
! __ fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_24()));
! } else {
! __ fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std()));
! }
! // Load the converted long, adjust CPU stack
! __ pop(rax);
! __ pop(rdx);
! __ cmpl(rdx, 0x80000000);
! __ jccb(Assembler::notEqual, fast);
! __ testl(rax, rax);
! __ jccb(Assembler::notEqual, fast);
! __ subptr(rsp, 4);
! __ movflt(Address(rsp, 0), $src$$XMMRegister);
! __ fld_s(Address(rsp, 0));
! __ addptr(rsp, 4);
! __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::d2l_wrapper())));
! __ bind(fast);
! %}
ins_pipe( pipe_slow );
%}
instruct convI2D_reg(regD dst, stackSlotI src) %{
predicate( UseSSE<=1 );
*** 12117,12137 ****
instruct convI2XD_reg(regXD dst, eRegI src) %{
predicate( UseSSE>=2 && !UseXmmI2D );
match(Set dst (ConvI2D src));
format %{ "CVTSI2SD $dst,$src" %}
! opcode(0xF2, 0x0F, 0x2A);
! ins_encode( OpcP, OpcS, Opcode(tertiary), RegReg(dst, src));
ins_pipe( pipe_slow );
%}
instruct convI2XD_mem(regXD dst, memory mem) %{
predicate( UseSSE>=2 );
match(Set dst (ConvI2D (LoadI mem)));
format %{ "CVTSI2SD $dst,$mem" %}
! opcode(0xF2, 0x0F, 0x2A);
! ins_encode( OpcP, OpcS, Opcode(tertiary), RegMem(dst, mem));
ins_pipe( pipe_slow );
%}
instruct convXI2XD_reg(regXD dst, eRegI src)
%{
--- 11774,11796 ----
instruct convI2XD_reg(regXD dst, eRegI src) %{
predicate( UseSSE>=2 && !UseXmmI2D );
match(Set dst (ConvI2D src));
format %{ "CVTSI2SD $dst,$src" %}
! ins_encode %{
! __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register);
! %}
ins_pipe( pipe_slow );
%}
instruct convI2XD_mem(regXD dst, memory mem) %{
predicate( UseSSE>=2 );
match(Set dst (ConvI2D (LoadI mem)));
format %{ "CVTSI2SD $dst,$mem" %}
! ins_encode %{
! __ cvtsi2sdl ($dst$$XMMRegister, $mem$$Address);
! %}
ins_pipe( pipe_slow );
%}
instruct convXI2XD_reg(regXD dst, eRegI src)
%{
*** 12223,12235 ****
// Convert an int to a float in xmm; no rounding step needed.
instruct convI2X_reg(regX dst, eRegI src) %{
predicate( UseSSE==1 || UseSSE>=2 && !UseXmmI2F );
match(Set dst (ConvI2F src));
format %{ "CVTSI2SS $dst, $src" %}
!
! opcode(0xF3, 0x0F, 0x2A); /* F3 0F 2A /r */
! ins_encode( OpcP, OpcS, Opcode(tertiary), RegReg(dst, src));
ins_pipe( pipe_slow );
%}
instruct convXI2X_reg(regX dst, eRegI src)
%{
--- 11882,11894 ----
// Convert an int to a float in xmm; no rounding step needed.
instruct convI2X_reg(regX dst, eRegI src) %{
predicate( UseSSE==1 || UseSSE>=2 && !UseXmmI2F );
match(Set dst (ConvI2F src));
format %{ "CVTSI2SS $dst, $src" %}
! ins_encode %{
! __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register);
! %}
ins_pipe( pipe_slow );
%}
instruct convXI2X_reg(regX dst, eRegI src)
%{
*** 12349,12360 ****
instruct MoveF2I_stack_reg(eRegI dst, stackSlotF src) %{
match(Set dst (MoveF2I src));
effect( DEF dst, USE src );
ins_cost(100);
format %{ "MOV $dst,$src\t# MoveF2I_stack_reg" %}
! opcode(0x8B);
! ins_encode( OpcP, RegMem(dst,src));
ins_pipe( ialu_reg_mem );
%}
instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{
predicate(UseSSE==0);
--- 12008,12020 ----
instruct MoveF2I_stack_reg(eRegI dst, stackSlotF src) %{
match(Set dst (MoveF2I src));
effect( DEF dst, USE src );
ins_cost(100);
format %{ "MOV $dst,$src\t# MoveF2I_stack_reg" %}
! ins_encode %{
! __ movl($dst$$Register, Address(rsp, $src$$disp));
! %}
ins_pipe( ialu_reg_mem );
%}
instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{
predicate(UseSSE==0);
*** 12372,12403 ****
match(Set dst (MoveF2I src));
effect( DEF dst, USE src );
ins_cost(95);
format %{ "MOVSS $dst,$src\t# MoveF2I_reg_stack_sse" %}
! ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x11), RegMem(src, dst));
ins_pipe( pipe_slow );
%}
instruct MoveF2I_reg_reg_sse(eRegI dst, regX src) %{
predicate(UseSSE>=2);
match(Set dst (MoveF2I src));
effect( DEF dst, USE src );
ins_cost(85);
format %{ "MOVD $dst,$src\t# MoveF2I_reg_reg_sse" %}
! ins_encode( MovX2I_reg(dst, src));
ins_pipe( pipe_slow );
%}
instruct MoveI2F_reg_stack(stackSlotF dst, eRegI src) %{
match(Set dst (MoveI2F src));
effect( DEF dst, USE src );
ins_cost(100);
format %{ "MOV $dst,$src\t# MoveI2F_reg_stack" %}
! opcode(0x89);
! ins_encode( OpcPRegSS( dst, src ) );
ins_pipe( ialu_mem_reg );
%}
instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{
--- 12032,12068 ----
match(Set dst (MoveF2I src));
effect( DEF dst, USE src );
ins_cost(95);
format %{ "MOVSS $dst,$src\t# MoveF2I_reg_stack_sse" %}
! ins_encode %{
! __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister);
! %}
ins_pipe( pipe_slow );
%}
instruct MoveF2I_reg_reg_sse(eRegI dst, regX src) %{
predicate(UseSSE>=2);
match(Set dst (MoveF2I src));
effect( DEF dst, USE src );
ins_cost(85);
format %{ "MOVD $dst,$src\t# MoveF2I_reg_reg_sse" %}
! ins_encode %{
! __ movdl($dst$$Register, $src$$XMMRegister);
! %}
ins_pipe( pipe_slow );
%}
instruct MoveI2F_reg_stack(stackSlotF dst, eRegI src) %{
match(Set dst (MoveI2F src));
effect( DEF dst, USE src );
ins_cost(100);
format %{ "MOV $dst,$src\t# MoveI2F_reg_stack" %}
! ins_encode %{
! __ movl(Address(rsp, $dst$$disp), $src$$Register);
! %}
ins_pipe( ialu_mem_reg );
%}
instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{
*** 12419,12429 ****
match(Set dst (MoveI2F src));
effect( DEF dst, USE src );
ins_cost(95);
format %{ "MOVSS $dst,$src\t# MoveI2F_stack_reg_sse" %}
! ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x10), RegMem(dst,src));
ins_pipe( pipe_slow );
%}
instruct MoveI2F_reg_reg_sse(regX dst, eRegI src) %{
predicate(UseSSE>=2);
--- 12084,12096 ----
match(Set dst (MoveI2F src));
effect( DEF dst, USE src );
ins_cost(95);
format %{ "MOVSS $dst,$src\t# MoveI2F_stack_reg_sse" %}
! ins_encode %{
! __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp));
! %}
ins_pipe( pipe_slow );
%}
instruct MoveI2F_reg_reg_sse(regX dst, eRegI src) %{
predicate(UseSSE>=2);
*** 12430,12440 ****
match(Set dst (MoveI2F src));
effect( DEF dst, USE src );
ins_cost(85);
format %{ "MOVD $dst,$src\t# MoveI2F_reg_reg_sse" %}
! ins_encode( MovI2X_reg(dst, src) );
ins_pipe( pipe_slow );
%}
instruct MoveD2L_stack_reg(eRegL dst, stackSlotD src) %{
match(Set dst (MoveD2L src));
--- 12097,12109 ----
match(Set dst (MoveI2F src));
effect( DEF dst, USE src );
ins_cost(85);
format %{ "MOVD $dst,$src\t# MoveI2F_reg_reg_sse" %}
! ins_encode %{
! __ movdl($dst$$XMMRegister, $src$$Register);
! %}
ins_pipe( pipe_slow );
%}
instruct MoveD2L_stack_reg(eRegL dst, stackSlotD src) %{
match(Set dst (MoveD2L src));
*** 12462,12474 ****
instruct MoveD2L_reg_stack_sse(stackSlotL dst, regXD src) %{
predicate(UseSSE>=2);
match(Set dst (MoveD2L src));
effect(DEF dst, USE src);
ins_cost(95);
-
format %{ "MOVSD $dst,$src\t# MoveD2L_reg_stack_sse" %}
! ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x11), RegMem(src,dst));
ins_pipe( pipe_slow );
%}
instruct MoveD2L_reg_reg_sse(eRegL dst, regXD src, regXD tmp) %{
predicate(UseSSE>=2);
--- 12131,12144 ----
instruct MoveD2L_reg_stack_sse(stackSlotL dst, regXD src) %{
predicate(UseSSE>=2);
match(Set dst (MoveD2L src));
effect(DEF dst, USE src);
ins_cost(95);
format %{ "MOVSD $dst,$src\t# MoveD2L_reg_stack_sse" %}
! ins_encode %{
! __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister);
! %}
ins_pipe( pipe_slow );
%}
instruct MoveD2L_reg_reg_sse(eRegL dst, regXD src, regXD tmp) %{
predicate(UseSSE>=2);
*** 12476,12486 ****
effect(DEF dst, USE src, TEMP tmp);
ins_cost(85);
format %{ "MOVD $dst.lo,$src\n\t"
"PSHUFLW $tmp,$src,0x4E\n\t"
"MOVD $dst.hi,$tmp\t# MoveD2L_reg_reg_sse" %}
! ins_encode( MovXD2L_reg(dst, src, tmp) );
ins_pipe( pipe_slow );
%}
instruct MoveL2D_reg_stack(stackSlotD dst, eRegL src) %{
match(Set dst (MoveL2D src));
--- 12146,12160 ----
effect(DEF dst, USE src, TEMP tmp);
ins_cost(85);
format %{ "MOVD $dst.lo,$src\n\t"
"PSHUFLW $tmp,$src,0x4E\n\t"
"MOVD $dst.hi,$tmp\t# MoveD2L_reg_reg_sse" %}
! ins_encode %{
! __ movdl($dst$$Register, $src$$XMMRegister);
! __ pshuflw($tmp$$XMMRegister, $src$$XMMRegister, 0x4e);
! __ movdl(HIGH_FROM_LOW($dst$$Register), $tmp$$XMMRegister);
! %}
ins_pipe( pipe_slow );
%}
instruct MoveL2D_reg_stack(stackSlotD dst, eRegL src) %{
match(Set dst (MoveL2D src));
*** 12515,12525 ****
match(Set dst (MoveL2D src));
effect(DEF dst, USE src);
ins_cost(95);
format %{ "MOVSD $dst,$src\t# MoveL2D_stack_reg_sse" %}
! ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x10), RegMem(dst,src));
ins_pipe( pipe_slow );
%}
instruct MoveL2D_stack_reg_sse_partial(regXD dst, stackSlotL src) %{
predicate(UseSSE>=2 && !UseXmmLoadAndClearUpper);
--- 12189,12201 ----
match(Set dst (MoveL2D src));
effect(DEF dst, USE src);
ins_cost(95);
format %{ "MOVSD $dst,$src\t# MoveL2D_stack_reg_sse" %}
! ins_encode %{
! __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp));
! %}
ins_pipe( pipe_slow );
%}
instruct MoveL2D_stack_reg_sse_partial(regXD dst, stackSlotL src) %{
predicate(UseSSE>=2 && !UseXmmLoadAndClearUpper);
*** 12526,12536 ****
match(Set dst (MoveL2D src));
effect(DEF dst, USE src);
ins_cost(95);
format %{ "MOVLPD $dst,$src\t# MoveL2D_stack_reg_sse" %}
! ins_encode( Opcode(0x66), Opcode(0x0F), Opcode(0x12), RegMem(dst,src));
ins_pipe( pipe_slow );
%}
instruct MoveL2D_reg_reg_sse(regXD dst, eRegL src, regXD tmp) %{
predicate(UseSSE>=2);
--- 12202,12214 ----
match(Set dst (MoveL2D src));
effect(DEF dst, USE src);
ins_cost(95);
format %{ "MOVLPD $dst,$src\t# MoveL2D_stack_reg_sse" %}
! ins_encode %{
! __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp));
! %}
ins_pipe( pipe_slow );
%}
instruct MoveL2D_reg_reg_sse(regXD dst, eRegL src, regXD tmp) %{
predicate(UseSSE>=2);
*** 12538,12548 ****
effect(TEMP dst, USE src, TEMP tmp);
ins_cost(85);
format %{ "MOVD $dst,$src.lo\n\t"
"MOVD $tmp,$src.hi\n\t"
"PUNPCKLDQ $dst,$tmp\t# MoveL2D_reg_reg_sse" %}
! ins_encode( MovL2XD_reg(dst, src, tmp) );
ins_pipe( pipe_slow );
%}
// Replicate scalar to packed byte (1 byte) values in xmm
instruct Repl8B_reg(regXD dst, regXD src) %{
--- 12216,12230 ----
effect(TEMP dst, USE src, TEMP tmp);
ins_cost(85);
format %{ "MOVD $dst,$src.lo\n\t"
"MOVD $tmp,$src.hi\n\t"
"PUNPCKLDQ $dst,$tmp\t# MoveL2D_reg_reg_sse" %}
! ins_encode %{
! __ movdl($dst$$XMMRegister, $src$$Register);
! __ movdl($tmp$$XMMRegister, HIGH_FROM_LOW($src$$Register));
! __ punpckldq($dst$$XMMRegister, $tmp$$XMMRegister);
! %}
ins_pipe( pipe_slow );
%}
// Replicate scalar to packed byte (1 byte) values in xmm
instruct Repl8B_reg(regXD dst, regXD src) %{
*** 12549,12559 ****
predicate(UseSSE>=2);
match(Set dst (Replicate8B src));
format %{ "MOVDQA $dst,$src\n\t"
"PUNPCKLBW $dst,$dst\n\t"
"PSHUFLW $dst,$dst,0x00\t! replicate8B" %}
! ins_encode( pshufd_8x8(dst, src));
ins_pipe( pipe_slow );
%}
// Replicate scalar to packed byte (1 byte) values in xmm
instruct Repl8B_eRegI(regXD dst, eRegI src) %{
--- 12231,12247 ----
predicate(UseSSE>=2);
match(Set dst (Replicate8B src));
format %{ "MOVDQA $dst,$src\n\t"
"PUNPCKLBW $dst,$dst\n\t"
"PSHUFLW $dst,$dst,0x00\t! replicate8B" %}
! ins_encode %{
! if ($dst$$reg != $src$$reg) {
! __ movdqa($dst$$XMMRegister, $src$$XMMRegister);
! }
! __ punpcklbw($dst$$XMMRegister, $dst$$XMMRegister);
! __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
! %}
ins_pipe( pipe_slow );
%}
// Replicate scalar to packed byte (1 byte) values in xmm
instruct Repl8B_eRegI(regXD dst, eRegI src) %{
*** 12560,12690 ****
predicate(UseSSE>=2);
match(Set dst (Replicate8B src));
format %{ "MOVD $dst,$src\n\t"
"PUNPCKLBW $dst,$dst\n\t"
"PSHUFLW $dst,$dst,0x00\t! replicate8B" %}
! ins_encode( mov_i2x(dst, src), pshufd_8x8(dst, dst));
ins_pipe( pipe_slow );
%}
// Replicate scalar zero to packed byte (1 byte) values in xmm
instruct Repl8B_immI0(regXD dst, immI0 zero) %{
predicate(UseSSE>=2);
match(Set dst (Replicate8B zero));
format %{ "PXOR $dst,$dst\t! replicate8B" %}
! ins_encode( pxor(dst, dst));
ins_pipe( fpu_reg_reg );
%}
// Replicate scalar to packed shore (2 byte) values in xmm
instruct Repl4S_reg(regXD dst, regXD src) %{
predicate(UseSSE>=2);
match(Set dst (Replicate4S src));
format %{ "PSHUFLW $dst,$src,0x00\t! replicate4S" %}
! ins_encode( pshufd_4x16(dst, src));
ins_pipe( fpu_reg_reg );
%}
// Replicate scalar to packed shore (2 byte) values in xmm
instruct Repl4S_eRegI(regXD dst, eRegI src) %{
predicate(UseSSE>=2);
match(Set dst (Replicate4S src));
format %{ "MOVD $dst,$src\n\t"
"PSHUFLW $dst,$dst,0x00\t! replicate4S" %}
! ins_encode( mov_i2x(dst, src), pshufd_4x16(dst, dst));
ins_pipe( fpu_reg_reg );
%}
// Replicate scalar zero to packed short (2 byte) values in xmm
instruct Repl4S_immI0(regXD dst, immI0 zero) %{
predicate(UseSSE>=2);
match(Set dst (Replicate4S zero));
format %{ "PXOR $dst,$dst\t! replicate4S" %}
! ins_encode( pxor(dst, dst));
ins_pipe( fpu_reg_reg );
%}
// Replicate scalar to packed char (2 byte) values in xmm
instruct Repl4C_reg(regXD dst, regXD src) %{
predicate(UseSSE>=2);
match(Set dst (Replicate4C src));
format %{ "PSHUFLW $dst,$src,0x00\t! replicate4C" %}
! ins_encode( pshufd_4x16(dst, src));
ins_pipe( fpu_reg_reg );
%}
// Replicate scalar to packed char (2 byte) values in xmm
instruct Repl4C_eRegI(regXD dst, eRegI src) %{
predicate(UseSSE>=2);
match(Set dst (Replicate4C src));
format %{ "MOVD $dst,$src\n\t"
"PSHUFLW $dst,$dst,0x00\t! replicate4C" %}
! ins_encode( mov_i2x(dst, src), pshufd_4x16(dst, dst));
ins_pipe( fpu_reg_reg );
%}
// Replicate scalar zero to packed char (2 byte) values in xmm
instruct Repl4C_immI0(regXD dst, immI0 zero) %{
predicate(UseSSE>=2);
match(Set dst (Replicate4C zero));
format %{ "PXOR $dst,$dst\t! replicate4C" %}
! ins_encode( pxor(dst, dst));
ins_pipe( fpu_reg_reg );
%}
// Replicate scalar to packed integer (4 byte) values in xmm
instruct Repl2I_reg(regXD dst, regXD src) %{
predicate(UseSSE>=2);
match(Set dst (Replicate2I src));
format %{ "PSHUFD $dst,$src,0x00\t! replicate2I" %}
! ins_encode( pshufd(dst, src, 0x00));
ins_pipe( fpu_reg_reg );
%}
// Replicate scalar to packed integer (4 byte) values in xmm
instruct Repl2I_eRegI(regXD dst, eRegI src) %{
predicate(UseSSE>=2);
match(Set dst (Replicate2I src));
format %{ "MOVD $dst,$src\n\t"
"PSHUFD $dst,$dst,0x00\t! replicate2I" %}
! ins_encode( mov_i2x(dst, src), pshufd(dst, dst, 0x00));
ins_pipe( fpu_reg_reg );
%}
// Replicate scalar zero to packed integer (2 byte) values in xmm
instruct Repl2I_immI0(regXD dst, immI0 zero) %{
predicate(UseSSE>=2);
match(Set dst (Replicate2I zero));
format %{ "PXOR $dst,$dst\t! replicate2I" %}
! ins_encode( pxor(dst, dst));
ins_pipe( fpu_reg_reg );
%}
// Replicate scalar to packed single precision floating point values in xmm
instruct Repl2F_reg(regXD dst, regXD src) %{
predicate(UseSSE>=2);
match(Set dst (Replicate2F src));
format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %}
! ins_encode( pshufd(dst, src, 0xe0));
ins_pipe( fpu_reg_reg );
%}
// Replicate scalar to packed single precision floating point values in xmm
instruct Repl2F_regX(regXD dst, regX src) %{
predicate(UseSSE>=2);
match(Set dst (Replicate2F src));
format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %}
! ins_encode( pshufd(dst, src, 0xe0));
ins_pipe( fpu_reg_reg );
%}
// Replicate scalar to packed single precision floating point values in xmm
instruct Repl2F_immXF0(regXD dst, immXF0 zero) %{
predicate(UseSSE>=2);
match(Set dst (Replicate2F zero));
format %{ "PXOR $dst,$dst\t! replicate2F" %}
! ins_encode( pxor(dst, dst));
ins_pipe( fpu_reg_reg );
%}
// =======================================================================
// fast clearing of an array
--- 12248,12411 ----
predicate(UseSSE>=2);
match(Set dst (Replicate8B src));
format %{ "MOVD $dst,$src\n\t"
"PUNPCKLBW $dst,$dst\n\t"
"PSHUFLW $dst,$dst,0x00\t! replicate8B" %}
! ins_encode %{
! __ movdl($dst$$XMMRegister, $src$$Register);
! __ punpcklbw($dst$$XMMRegister, $dst$$XMMRegister);
! __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
! %}
ins_pipe( pipe_slow );
%}
// Replicate scalar zero to packed byte (1 byte) values in xmm
instruct Repl8B_immI0(regXD dst, immI0 zero) %{
predicate(UseSSE>=2);
match(Set dst (Replicate8B zero));
format %{ "PXOR $dst,$dst\t! replicate8B" %}
! ins_encode %{
! __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
! %}
ins_pipe( fpu_reg_reg );
%}
// Replicate scalar to packed shore (2 byte) values in xmm
instruct Repl4S_reg(regXD dst, regXD src) %{
predicate(UseSSE>=2);
match(Set dst (Replicate4S src));
format %{ "PSHUFLW $dst,$src,0x00\t! replicate4S" %}
! ins_encode %{
! __ pshuflw($dst$$XMMRegister, $src$$XMMRegister, 0x00);
! %}
ins_pipe( fpu_reg_reg );
%}
// Replicate scalar to packed shore (2 byte) values in xmm
instruct Repl4S_eRegI(regXD dst, eRegI src) %{
predicate(UseSSE>=2);
match(Set dst (Replicate4S src));
format %{ "MOVD $dst,$src\n\t"
"PSHUFLW $dst,$dst,0x00\t! replicate4S" %}
! ins_encode %{
! __ movdl($dst$$XMMRegister, $src$$Register);
! __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
! %}
ins_pipe( fpu_reg_reg );
%}
// Replicate scalar zero to packed short (2 byte) values in xmm
instruct Repl4S_immI0(regXD dst, immI0 zero) %{
predicate(UseSSE>=2);
match(Set dst (Replicate4S zero));
format %{ "PXOR $dst,$dst\t! replicate4S" %}
! ins_encode %{
! __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
! %}
ins_pipe( fpu_reg_reg );
%}
// Replicate scalar to packed char (2 byte) values in xmm
instruct Repl4C_reg(regXD dst, regXD src) %{
predicate(UseSSE>=2);
match(Set dst (Replicate4C src));
format %{ "PSHUFLW $dst,$src,0x00\t! replicate4C" %}
! ins_encode %{
! __ pshuflw($dst$$XMMRegister, $src$$XMMRegister, 0x00);
! %}
ins_pipe( fpu_reg_reg );
%}
// Replicate scalar to packed char (2 byte) values in xmm
instruct Repl4C_eRegI(regXD dst, eRegI src) %{
predicate(UseSSE>=2);
match(Set dst (Replicate4C src));
format %{ "MOVD $dst,$src\n\t"
"PSHUFLW $dst,$dst,0x00\t! replicate4C" %}
! ins_encode %{
! __ movdl($dst$$XMMRegister, $src$$Register);
! __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
! %}
ins_pipe( fpu_reg_reg );
%}
// Replicate scalar zero to packed char (2 byte) values in xmm
instruct Repl4C_immI0(regXD dst, immI0 zero) %{
predicate(UseSSE>=2);
match(Set dst (Replicate4C zero));
format %{ "PXOR $dst,$dst\t! replicate4C" %}
! ins_encode %{
! __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
! %}
ins_pipe( fpu_reg_reg );
%}
// Replicate scalar to packed integer (4 byte) values in xmm
instruct Repl2I_reg(regXD dst, regXD src) %{
predicate(UseSSE>=2);
match(Set dst (Replicate2I src));
format %{ "PSHUFD $dst,$src,0x00\t! replicate2I" %}
! ins_encode %{
! __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0x00);
! %}
ins_pipe( fpu_reg_reg );
%}
// Replicate scalar to packed integer (4 byte) values in xmm
instruct Repl2I_eRegI(regXD dst, eRegI src) %{
predicate(UseSSE>=2);
match(Set dst (Replicate2I src));
format %{ "MOVD $dst,$src\n\t"
"PSHUFD $dst,$dst,0x00\t! replicate2I" %}
! ins_encode %{
! __ movdl($dst$$XMMRegister, $src$$Register);
! __ pshufd($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
! %}
ins_pipe( fpu_reg_reg );
%}
// Replicate scalar zero to packed integer (2 byte) values in xmm
instruct Repl2I_immI0(regXD dst, immI0 zero) %{
predicate(UseSSE>=2);
match(Set dst (Replicate2I zero));
format %{ "PXOR $dst,$dst\t! replicate2I" %}
! ins_encode %{
! __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
! %}
ins_pipe( fpu_reg_reg );
%}
// Replicate scalar to packed single precision floating point values in xmm
instruct Repl2F_reg(regXD dst, regXD src) %{
predicate(UseSSE>=2);
match(Set dst (Replicate2F src));
format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %}
! ins_encode %{
! __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0xe0);
! %}
ins_pipe( fpu_reg_reg );
%}
// Replicate scalar to packed single precision floating point values in xmm
instruct Repl2F_regX(regXD dst, regX src) %{
predicate(UseSSE>=2);
match(Set dst (Replicate2F src));
format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %}
! ins_encode %{
! __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0xe0);
! %}
ins_pipe( fpu_reg_reg );
%}
// Replicate scalar to packed single precision floating point values in xmm
instruct Repl2F_immXF0(regXD dst, immXF0 zero) %{
predicate(UseSSE>=2);
match(Set dst (Replicate2F zero));
format %{ "PXOR $dst,$dst\t! replicate2F" %}
! ins_encode %{
! __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
! %}
ins_pipe( fpu_reg_reg );
%}
// =======================================================================
// fast clearing of an array
src/cpu/x86/vm/x86_32.ad
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File