src/cpu/x86/vm/x86_32.ad
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File
*** old/src/cpu/x86/vm/x86_32.ad Mon Dec 19 12:30:03 2011
--- new/src/cpu/x86/vm/x86_32.ad Mon Dec 19 12:30:03 2011
*** 1773,1783 ****
--- 1773,1783 ----
enc_class enc_cmov(cmpOp cop ) %{ // CMOV
$$$emit8$primary;
emit_cc(cbuf, $secondary, $cop$$cmpcode);
%}
! enc_class enc_cmov_dpr(cmpOp cop, regDPR src ) %{ // CMOV
int op = 0xDA00 + $cop$$cmpcode + ($src$$reg-1);
emit_d8(cbuf, op >> 8 );
emit_d8(cbuf, op & 255);
%}
*** 2061,2078 ****
--- 2061,2078 ----
enc_class Con32 (immI src) %{ // Con32(storeImmI)
// Output immediate
$$$emit32$src$$constant;
%}
! enc_class Con32F_as_bits(immF src) %{ // storeF_imm
! enc_class Con32FPR_as_bits(immFPR src) %{ // storeF_imm
// Output Float immediate bits
jfloat jf = $src$$constant;
int jf_as_bits = jint_cast( jf );
emit_d32(cbuf, jf_as_bits);
%}
! enc_class Con32XF_as_bits(immXF src) %{ // storeX_imm
! enc_class Con32F_as_bits(immF src) %{ // storeX_imm
// Output Float immediate bits
jfloat jf = $src$$constant;
int jf_as_bits = jint_cast( jf );
emit_d32(cbuf, jf_as_bits);
%}
*** 2281,2291 ****
--- 2281,2291 ----
// move dst,src
emit_opcode(cbuf,0x8B);
emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
%}
! enc_class enc_FP_store(memory mem, regD src) %{
! enc_class enc_FPR_store(memory mem, regDPR src) %{
// If src is FPR1, we can just FST to store it.
// Else we need to FLD it to FPR1, then FSTP to store/pop it.
int reg_encoding = 0x2; // Just store
int base = $mem$$base;
int index = $mem$$index;
*** 2430,2440 ****
--- 2430,2440 ----
%}
// ----------------- Encodings for floating point unit -----------------
// May leave result in FPU-TOS or FPU reg depending on opcodes
! enc_class OpcReg_F (regF src) %{ // FMUL, FDIV
! enc_class OpcReg_FPR(regFPR src) %{ // FMUL, FDIV
$$$emit8$primary;
emit_rm(cbuf, 0x3, $secondary, $src$$reg );
%}
// Pop argument in FPR0 with FSTP ST(0)
*** 2442,2470 ****
--- 2442,2470 ----
emit_opcode( cbuf, 0xDD );
emit_d8( cbuf, 0xD8 );
%}
// !!!!! equivalent to Pop_Reg_F
! enc_class Pop_Reg_DPR( regDPR dst ) %{
emit_opcode( cbuf, 0xDD ); // FSTP ST(i)
emit_d8( cbuf, 0xD8+$dst$$reg );
%}
! enc_class Push_Reg_DPR( regDPR dst ) %{
emit_opcode( cbuf, 0xD9 );
emit_d8( cbuf, 0xC0-1+$dst$$reg ); // FLD ST(i-1)
%}
! enc_class strictfp_bias1( regDPR dst ) %{
emit_opcode( cbuf, 0xDB ); // FLD m80real
emit_opcode( cbuf, 0x2D );
emit_d32( cbuf, (int)StubRoutines::addr_fpu_subnormal_bias1() );
emit_opcode( cbuf, 0xDE ); // FMULP ST(dst), ST0
emit_opcode( cbuf, 0xC8+$dst$$reg );
%}
! enc_class strictfp_bias2( regDPR dst ) %{
emit_opcode( cbuf, 0xDB ); // FLD m80real
emit_opcode( cbuf, 0x2D );
emit_d32( cbuf, (int)StubRoutines::addr_fpu_subnormal_bias2() );
emit_opcode( cbuf, 0xDE ); // FMULP ST(dst), ST0
emit_opcode( cbuf, 0xC8+$dst$$reg );
*** 2486,2528 ****
--- 2486,2518 ----
// Push the integer in stackSlot 'src' onto FP-stack
enc_class Push_Mem_I( memory src ) %{ // FILD [ESP+src]
store_to_stackslot( cbuf, $primary, $secondary, $src$$disp );
%}
// Push the float in stackSlot 'src' onto FP-stack
enc_class Push_Mem_F( memory src ) %{ // FLD_S [ESP+src]
store_to_stackslot( cbuf, 0xD9, 0x00, $src$$disp );
%}
// Push the double in stackSlot 'src' onto FP-stack
enc_class Push_Mem_D( memory src ) %{ // FLD_D [ESP+src]
store_to_stackslot( cbuf, 0xDD, 0x00, $src$$disp );
%}
// Push FPU's TOS float to a stack-slot, and pop FPU-stack
! enc_class Pop_Mem_FPR( stackSlotF dst ) %{ // FSTP_S [ESP+dst]
store_to_stackslot( cbuf, 0xD9, 0x03, $dst$$disp );
%}
// Same as Pop_Mem_F except for opcode
// Push FPU's TOS double to a stack-slot, and pop FPU-stack
! enc_class Pop_Mem_DPR( stackSlotD dst ) %{ // FSTP_D [ESP+dst]
store_to_stackslot( cbuf, 0xDD, 0x03, $dst$$disp );
%}
! enc_class Pop_Reg_FPR( regFPR dst ) %{
emit_opcode( cbuf, 0xDD ); // FSTP ST(i)
emit_d8( cbuf, 0xD8+$dst$$reg );
%}
! enc_class Push_Reg_FPR( regFPR dst ) %{
emit_opcode( cbuf, 0xD9 ); // FLD ST(i-1)
emit_d8( cbuf, 0xC0-1+$dst$$reg );
%}
// Push FPU's float to a stack-slot, and pop FPU-stack
! enc_class Pop_Mem_Reg_FPR( stackSlotF dst, regFPR src ) %{
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;
*** 2529,2539 ****
--- 2519,2529 ----
}
store_to_stackslot( cbuf, 0xD9, pop, $dst$$disp ); // FST<P>_S [ESP+dst]
%}
// Push FPU's double to a stack-slot, and pop FPU-stack
! enc_class Pop_Mem_Reg_DPR( stackSlotD dst, regDPR src ) %{
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;
*** 2540,2550 ****
--- 2530,2540 ----
}
store_to_stackslot( cbuf, 0xDD, pop, $dst$$disp ); // FST<P>_D [ESP+dst]
%}
// Push FPU's double to a FPU-stack-slot, and pop FPU-stack
! enc_class Pop_Reg_Reg_D( regD dst, regF src ) %{
! enc_class Pop_Reg_Reg_DPR( regDPR dst, regFPR src ) %{
int pop = 0xD0 - 1; // -1 since we skip FLD
if ($src$$reg != FPR1L_enc) {
emit_opcode( cbuf, 0xD9 ); // FLD ST(src-1)
emit_d8( cbuf, 0xC0-1+$src$$reg );
pop = 0xD8;
*** 2552,2571 ****
--- 2542,2552 ----
emit_opcode( cbuf, 0xDD );
emit_d8( cbuf, pop+$dst$$reg ); // FST<P> ST(i)
%}
! enc_class Mul_Add_F( regF dst, regF src, regF src1, regF src2 ) %{
MacroAssembler masm(&cbuf);
masm.fld_s( $src1$$reg-1); // nothing at TOS, load TOS from src1.reg
masm.fmul( $src2$$reg+0); // value at TOS
masm.fadd( $src$$reg+0); // value at TOS
masm.fstp_d( $dst$$reg+0); // value at TOS, popped off after store
%}
enc_class Push_Reg_Mod_D( regD dst, regD src) %{
! enc_class Push_Reg_Mod_DPR( regDPR dst, regDPR src) %{
// load dst in FPR0
emit_opcode( cbuf, 0xD9 );
emit_d8( cbuf, 0xC0-1+$dst$$reg );
if ($src$$reg != FPR1L_enc) {
// fincstp
*** 2579,2621 ****
--- 2560,2602 ----
emit_opcode (cbuf, 0xD9);
emit_opcode (cbuf, 0xF6);
}
%}
! enc_class Push_ModD_encoding(regXD src0, regXD src1) %{
! enc_class Push_ModD_encoding(regD src0, regD 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) %{
! enc_class Push_ModF_encoding(regF src0, regF 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) %{
! enc_class Push_ResultD(regD 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) %{
! enc_class Push_ResultF(regF 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) %{
! enc_class Push_SrcD(regD src) %{
MacroAssembler _masm(&cbuf);
__ subptr(rsp, 8);
__ movdbl(Address(rsp, 0), $src$$XMMRegister);
__ fld_d(Address(rsp, 0));
%}
*** 2628,2638 ****
--- 2609,2619 ----
enc_class pop_stack_temp_qword() %{
MacroAssembler _masm(&cbuf);
__ addptr(rsp, 8);
%}
! enc_class push_xmm_to_fpr1(regXD src) %{
! enc_class push_xmm_to_fpr1(regD src) %{
MacroAssembler _masm(&cbuf);
__ movdbl(Address(rsp, 0), $src$$XMMRegister);
__ fld_d(Address(rsp, 0));
%}
*** 2673,2686 ****
--- 2654,2664 ----
emit_d32(cbuf,0);
emit_opcode(cbuf,0xDC); // fmul dword st(0),[esp+0]; FPR1 = 2^int(Q)*2^frac(Q) = 2^Q
encode_RegMem(cbuf, 0x1, ESP_enc, 0x4, 0, 0, false);
%}
// enc_class Pop_Reg_Mod_D( regD dst, regD src)
// was replaced by Push_Result_Mod_D followed by Pop_Reg_X() or Pop_Mem_X()
enc_class Push_Result_Mod_D( regD src) %{
+ enc_class Push_Result_Mod_DPR( regDPR src) %{
if ($src$$reg != FPR1L_enc) {
// fincstp
emit_opcode (cbuf, 0xD9);
emit_opcode (cbuf, 0xF7);
// FXCH FPR1 with src
*** 2705,2715 ****
--- 2683,2693 ----
// jnp ::skip
emit_opcode( cbuf, 0x7B );
emit_opcode( cbuf, 0x05 );
%}
! enc_class emitModDPR() %{
// fprem must be iterative
// :: loop
// fprem
emit_opcode( cbuf, 0xD9 );
emit_opcode( cbuf, 0xF8 );
*** 3585,3595 ****
--- 3563,3573 ----
// Convert a double to an int. Java semantics require we do complex
// manglelations in the corner cases. So we set the rounding mode to
// 'zero', store the darned double down as an int, and reset the
// rounding mode to 'nearest'. The hardware throws an exception which
// patches up the correct value directly to the stack.
! enc_class D2I_encoding( regD src ) %{
! enc_class DPR2I_encoding( regDPR src ) %{
// Flip to round-to-zero mode. We attempted to allow invalid-op
// exceptions here, so that a NAN or other corner-case value will
// thrown an exception (but normal values get converted at full speed).
// However, I2C adapters and other float-stack manglers leave pending
// invalid-op exceptions hanging. We would have to clear them before
*** 3628,3638 ****
--- 3606,3616 ----
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 D2L_encoding( regD src ) %{
! enc_class DPR2L_encoding( regDPR src ) %{
emit_opcode(cbuf,0xD9); // FLDCW trunc
emit_opcode(cbuf,0x2D);
emit_d32(cbuf,(int)StubRoutines::addr_fpu_cntrl_wrd_trunc());
// Allocate a word
emit_opcode(cbuf,0x83); // SUB ESP,8
*** 3670,3700 ****
--- 3648,3678 ----
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 FMul_ST_reg( eRegFPR 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);
%}
! enc_class FAdd_ST_reg( eRegFPR src2 ) %{
// FADDP ST,src2 /* D8 C0+i */
emit_opcode(cbuf, 0xD8);
emit_opcode(cbuf, 0xC0 + $src2$$reg);
//could use FADDP src2,fpST /* DE C0+i */
%}
! enc_class FAddP_reg_ST( eRegFPR src2 ) %{
// FADDP src2,ST /* DE C0+i */
emit_opcode(cbuf, 0xDE);
emit_opcode(cbuf, 0xC0 + $src2$$reg);
%}
! enc_class subF_divF_encode( eRegF src1, eRegF src2) %{
! enc_class subFPR_divFPR_encode( eRegFPR src1, eRegFPR src2) %{
// Operand has been loaded into fp ST (stack top)
// FSUB ST,$src1
emit_opcode(cbuf, 0xD8);
emit_opcode(cbuf, 0xE0 + $src1$$reg);
*** 3701,3711 ****
--- 3679,3689 ----
// FDIV
emit_opcode(cbuf, 0xD8);
emit_opcode(cbuf, 0xF0 + $src2$$reg);
%}
! enc_class MulFAddF (eRegFPR src1, eRegFPR src2) %{
// Operand was loaded from memory into fp ST (stack top)
// FADD ST,$src /* D8 C0+i */
emit_opcode(cbuf, 0xD8);
emit_opcode(cbuf, 0xC0 + $src1$$reg);
*** 3713,3723 ****
--- 3691,3701 ----
emit_opcode(cbuf, 0xD8);
emit_opcode(cbuf, 0xC8 + $src2$$reg);
%}
! enc_class MulFAddFreverse (eRegFPR src1, eRegFPR src2) %{
// Operand was loaded from memory into fp ST (stack top)
// FADD ST,$src /* D8 C0+i */
emit_opcode(cbuf, 0xD8);
emit_opcode(cbuf, 0xC0 + $src1$$reg);
*** 4146,4156 ****
--- 4124,4134 ----
format %{ %}
interface(CONST_INTER);
%}
//Double Immediate zero
! operand immD0() %{
! operand immDPR0() %{
// Do additional (and counter-intuitive) test against NaN to work around VC++
// bug that generates code such that NaNs compare equal to 0.0
predicate( UseSSE<=1 && n->getd() == 0.0 && !g_isnan(n->getd()) );
match(ConD);
*** 4158,4197 ****
--- 4136,4175 ----
format %{ %}
interface(CONST_INTER);
%}
// Double Immediate one
! operand immD1() %{
! operand immDPR1() %{
predicate( UseSSE<=1 && n->getd() == 1.0 );
match(ConD);
op_cost(5);
format %{ %}
interface(CONST_INTER);
%}
// Double Immediate
! operand immDPR() %{
predicate(UseSSE<=1);
match(ConD);
op_cost(5);
format %{ %}
interface(CONST_INTER);
%}
! operand immXD() %{
! operand immD() %{
predicate(UseSSE>=2);
match(ConD);
op_cost(5);
format %{ %}
interface(CONST_INTER);
%}
// Double Immediate zero
! operand immXD0() %{
! operand immD0() %{
// Do additional (and counter-intuitive) test against NaN to work around VC++
// bug that generates code such that NaNs compare equal to 0.0 AND do not
// compare equal to -0.0.
predicate( UseSSE>=2 && jlong_cast(n->getd()) == 0 );
match(ConD);
*** 4199,4249 ****
--- 4177,4227 ----
format %{ %}
interface(CONST_INTER);
%}
// Float Immediate zero
! operand immF0() %{
! operand immFPR0() %{
predicate(UseSSE == 0 && n->getf() == 0.0F);
match(ConF);
op_cost(5);
format %{ %}
interface(CONST_INTER);
%}
// Float Immediate one
! operand immF1() %{
! operand immFPR1() %{
predicate(UseSSE == 0 && n->getf() == 1.0F);
match(ConF);
op_cost(5);
format %{ %}
interface(CONST_INTER);
%}
// Float Immediate
! operand immFPR() %{
predicate( UseSSE == 0 );
match(ConF);
op_cost(5);
format %{ %}
interface(CONST_INTER);
%}
// Float Immediate
! operand immXF() %{
! operand immF() %{
predicate(UseSSE >= 1);
match(ConF);
op_cost(5);
format %{ %}
interface(CONST_INTER);
%}
// Float Immediate zero. Zero and not -0.0
! operand immXF0() %{
! operand immF0() %{
predicate( UseSSE >= 1 && jint_cast(n->getf()) == 0 );
match(ConF);
op_cost(5);
format %{ %}
*** 4615,4708 ****
--- 4593,4686 ----
format %{ "FLAGS_LEGT" %}
interface(REG_INTER);
%}
// Float register operands
! operand regDPR() %{
predicate( UseSSE < 2 );
constraint(ALLOC_IN_RC(dbl_reg));
match(RegD);
match(regDPR1);
match(regDPR2);
format %{ %}
interface(REG_INTER);
%}
! operand regDPR1(regDPR reg) %{
predicate( UseSSE < 2 );
constraint(ALLOC_IN_RC(dbl_reg0));
match(reg);
format %{ "FPR1" %}
interface(REG_INTER);
%}
! operand regDPR2(regDPR reg) %{
predicate( UseSSE < 2 );
constraint(ALLOC_IN_RC(dbl_reg1));
match(reg);
format %{ "FPR2" %}
interface(REG_INTER);
%}
! operand regnotDPR1(regDPR reg) %{
predicate( UseSSE < 2 );
constraint(ALLOC_IN_RC(dbl_notreg0));
match(reg);
format %{ %}
interface(REG_INTER);
%}
// XMM Double register operands
! operand regXD() %{
! operand regD() %{
predicate( UseSSE>=2 );
constraint(ALLOC_IN_RC(xdb_reg));
match(RegD);
! match(regXD6);
! match(regXD7);
! match(regD6);
! match(regD7);
format %{ %}
interface(REG_INTER);
%}
// XMM6 double register operands
! operand regXD6(regXD reg) %{
! operand regD6(regD reg) %{
predicate( UseSSE>=2 );
constraint(ALLOC_IN_RC(xdb_reg6));
match(reg);
format %{ "XMM6" %}
interface(REG_INTER);
%}
// XMM7 double register operands
! operand regXD7(regXD reg) %{
! operand regD7(regD reg) %{
predicate( UseSSE>=2 );
constraint(ALLOC_IN_RC(xdb_reg7));
match(reg);
format %{ "XMM7" %}
interface(REG_INTER);
%}
// Float register operands
! operand regFPR() %{
predicate( UseSSE < 2 );
constraint(ALLOC_IN_RC(flt_reg));
match(RegF);
match(regFPR1);
format %{ %}
interface(REG_INTER);
%}
// Float register operands
! operand regFPR1(regFPR reg) %{
predicate( UseSSE < 2 );
constraint(ALLOC_IN_RC(flt_reg0));
match(reg);
format %{ "FPR1" %}
interface(REG_INTER);
%}
// XMM register operands
! operand regX() %{
! operand regF() %{
predicate( UseSSE>=1 );
constraint(ALLOC_IN_RC(xmm_reg));
match(RegF);
format %{ %}
interface(REG_INTER);
*** 5442,5488 ****
--- 5420,5466 ----
cr : S3(read);
DECODE : S0(2); // any 2 decoders
%}
// Conditional move double reg-reg
! pipe_class pipe_cmovD_reg( eFlagsReg cr, regDPR1 dst, regD src) %{
! pipe_class pipe_cmovDPR_reg( eFlagsReg cr, regDPR1 dst, regDPR src) %{
single_instruction;
dst : S4(write);
src : S3(read);
cr : S3(read);
DECODE : S0; // any decoder
%}
// Float reg-reg operation
! pipe_class fpu_reg(regDPR dst) %{
instruction_count(2);
dst : S3(read);
DECODE : S0(2); // any 2 decoders
FPU : S3;
%}
// Float reg-reg operation
! pipe_class fpu_reg_reg(regDPR dst, regDPR src) %{
instruction_count(2);
dst : S4(write);
src : S3(read);
DECODE : S0(2); // any 2 decoders
FPU : S3;
%}
// Float reg-reg operation
! pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) %{
! pipe_class fpu_reg_reg_reg(regDPR dst, regDPR src1, regDPR src2) %{
instruction_count(3);
dst : S4(write);
src1 : S3(read);
src2 : S3(read);
DECODE : S0(3); // any 3 decoders
FPU : S3(2);
%}
// Float reg-reg operation
! pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
! pipe_class fpu_reg_reg_reg_reg(regDPR dst, regDPR src1, regDPR src2, regDPR src3) %{
instruction_count(4);
dst : S4(write);
src1 : S3(read);
src2 : S3(read);
src3 : S3(read);
*** 5489,5499 ****
--- 5467,5477 ----
DECODE : S0(4); // any 3 decoders
FPU : S3(2);
%}
// Float reg-reg operation
! pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) %{
! pipe_class fpu_reg_mem_reg_reg(regDPR dst, memory src1, regDPR src2, regDPR src3) %{
instruction_count(4);
dst : S4(write);
src1 : S3(read);
src2 : S3(read);
src3 : S3(read);
*** 5502,5512 ****
--- 5480,5490 ----
FPU : S3(2);
MEM : S3;
%}
// Float reg-mem operation
! pipe_class fpu_reg_mem(regDPR dst, memory mem) %{
instruction_count(2);
dst : S5(write);
mem : S3(read);
D0 : S0; // big decoder only
DECODE : S1; // any decoder for FPU POP
*** 5513,5523 ****
--- 5491,5501 ----
FPU : S4;
MEM : S3; // any mem
%}
// Float reg-mem operation
! pipe_class fpu_reg_reg_mem(regDPR dst, regDPR src1, memory mem) %{
instruction_count(3);
dst : S5(write);
src1 : S3(read);
mem : S3(read);
D0 : S0; // big decoder only
*** 5525,5545 ****
--- 5503,5523 ----
FPU : S4;
MEM : S3; // any mem
%}
// Float mem-reg operation
! pipe_class fpu_mem_reg(memory mem, regDPR src) %{
instruction_count(2);
src : S5(read);
mem : S3(read);
DECODE : S0; // any decoder for FPU PUSH
D0 : S1; // big decoder only
FPU : S4;
MEM : S3; // any mem
%}
! pipe_class fpu_mem_reg_reg(memory mem, regDPR src1, regDPR src2) %{
instruction_count(3);
src1 : S3(read);
src2 : S3(read);
mem : S3(read);
DECODE : S0(2); // any decoder for FPU PUSH
*** 5546,5556 ****
--- 5524,5534 ----
D0 : S1; // big decoder only
FPU : S4;
MEM : S3; // any mem
%}
! pipe_class fpu_mem_reg_mem(memory mem, regDPR src1, memory src2) %{
instruction_count(3);
src1 : S3(read);
src2 : S3(read);
mem : S4(read);
DECODE : S0; // any decoder for FPU PUSH
*** 5575,5585 ****
--- 5553,5563 ----
D0 : S0(3); // big decoder only
FPU : S4;
MEM : S3(3); // any mem
%}
! pipe_class fpu_mem_reg_con(memory mem, regDPR src1) %{
instruction_count(3);
src1 : S4(read);
mem : S4(read);
DECODE : S0; // any decoder for FPU PUSH
D0 : S0(2); // big decoder only
*** 5586,5606 ****
--- 5564,5584 ----
FPU : S4;
MEM : S3(2); // any mem
%}
// Float load constant
! pipe_class fpu_reg_con(regDPR dst) %{
instruction_count(2);
dst : S5(write);
D0 : S0; // big decoder only for the load
DECODE : S1; // any decoder for FPU POP
FPU : S4;
MEM : S3; // any mem
%}
// Float load constant
! pipe_class fpu_reg_reg_con(regDPR dst, regDPR src) %{
instruction_count(3);
dst : S5(write);
src : S3(read);
D0 : S0; // big decoder only for the load
DECODE : S1(2); // any decoder for FPU POP
*** 6311,6321 ****
--- 6289,6299 ----
"FISTp $dst" %}
ins_encode(enc_loadL_volatile(mem,dst));
ins_pipe( fpu_reg_mem );
%}
! instruct loadLX_volatile(stackSlotL dst, memory mem, regXD tmp) %{
! instruct loadLX_volatile(stackSlotL dst, memory mem, regD tmp) %{
predicate(UseSSE>=2 && ((LoadLNode*)n)->require_atomic_access());
match(Set dst (LoadL mem));
effect(TEMP tmp);
ins_cost(180);
format %{ "MOVSD $tmp,$mem\t# Atomic volatile long load\n\t"
*** 6325,6335 ****
--- 6303,6313 ----
__ movdbl(Address(rsp, $dst$$disp), $tmp$$XMMRegister);
%}
ins_pipe( pipe_slow );
%}
! instruct loadLX_reg_volatile(eRegL dst, memory mem, regXD tmp) %{
! instruct loadLX_reg_volatile(eRegL dst, memory mem, regD tmp) %{
predicate(UseSSE>=2 && ((LoadLNode*)n)->require_atomic_access());
match(Set dst (LoadL mem));
effect(TEMP tmp);
ins_cost(160);
format %{ "MOVSD $tmp,$mem\t# Atomic volatile long load\n\t"
*** 6378,6402 ****
--- 6356,6380 ----
ins_encode( OpcP, RegMem(dst,mem));
ins_pipe( ialu_reg_mem );
%}
// Load Double
! instruct loadDPR(regDPR dst, memory mem) %{
predicate(UseSSE<=1);
match(Set dst (LoadD mem));
ins_cost(150);
format %{ "FLD_D ST,$mem\n\t"
"FSTP $dst" %}
opcode(0xDD); /* DD /0 */
ins_encode( OpcP, RMopc_Mem(0x00,mem),
! Pop_Reg_DPR(dst) );
ins_pipe( fpu_reg_mem );
%}
// Load Double to XMM
! instruct loadXD(regXD dst, memory mem) %{
! instruct loadD(regD dst, memory mem) %{
predicate(UseSSE>=2 && UseXmmLoadAndClearUpper);
match(Set dst (LoadD mem));
ins_cost(145);
format %{ "MOVSD $dst,$mem" %}
ins_encode %{
*** 6403,6413 ****
--- 6381,6391 ----
__ movdbl ($dst$$XMMRegister, $mem$$Address);
%}
ins_pipe( pipe_slow );
%}
! instruct loadXD_partial(regXD dst, memory mem) %{
! instruct loadD_partial(regD dst, memory mem) %{
predicate(UseSSE>=2 && !UseXmmLoadAndClearUpper);
match(Set dst (LoadD mem));
ins_cost(145);
format %{ "MOVLPD $dst,$mem" %}
ins_encode %{
*** 6416,6426 ****
--- 6394,6404 ----
ins_pipe( pipe_slow );
%}
// Load to XMM register (single-precision floating point)
// MOVSS instruction
! instruct loadX(regX dst, memory mem) %{
! instruct loadF(regF dst, memory mem) %{
predicate(UseSSE>=1);
match(Set dst (LoadF mem));
ins_cost(145);
format %{ "MOVSS $dst,$mem" %}
ins_encode %{
*** 6428,6452 ****
--- 6406,6430 ----
%}
ins_pipe( pipe_slow );
%}
// Load Float
! instruct loadFPR(regFPR dst, memory mem) %{
predicate(UseSSE==0);
match(Set dst (LoadF mem));
ins_cost(150);
format %{ "FLD_S ST,$mem\n\t"
"FSTP $dst" %}
opcode(0xD9); /* D9 /0 */
ins_encode( OpcP, RMopc_Mem(0x00,mem),
! Pop_Reg_FPR(dst) );
ins_pipe( fpu_reg_mem );
%}
// Load Aligned Packed Byte to XMM register
! instruct loadA8B(regXD dst, memory mem) %{
! instruct loadA8B(regD dst, memory mem) %{
predicate(UseSSE>=1);
match(Set dst (Load8B mem));
ins_cost(125);
format %{ "MOVQ $dst,$mem\t! packed8B" %}
ins_encode %{
*** 6454,6464 ****
--- 6432,6442 ----
%}
ins_pipe( pipe_slow );
%}
// Load Aligned Packed Short to XMM register
! instruct loadA4S(regXD dst, memory mem) %{
! instruct loadA4S(regD dst, memory mem) %{
predicate(UseSSE>=1);
match(Set dst (Load4S mem));
ins_cost(125);
format %{ "MOVQ $dst,$mem\t! packed4S" %}
ins_encode %{
*** 6466,6476 ****
--- 6444,6454 ----
%}
ins_pipe( pipe_slow );
%}
// Load Aligned Packed Char to XMM register
! instruct loadA4C(regXD dst, memory mem) %{
! instruct loadA4C(regD dst, memory mem) %{
predicate(UseSSE>=1);
match(Set dst (Load4C mem));
ins_cost(125);
format %{ "MOVQ $dst,$mem\t! packed4C" %}
ins_encode %{
*** 6478,6488 ****
--- 6456,6466 ----
%}
ins_pipe( pipe_slow );
%}
// Load Aligned Packed Integer to XMM register
! instruct load2IU(regXD dst, memory mem) %{
! instruct load2IU(regD dst, memory mem) %{
predicate(UseSSE>=1);
match(Set dst (Load2I mem));
ins_cost(125);
format %{ "MOVQ $dst,$mem\t! packed2I" %}
ins_encode %{
*** 6490,6500 ****
--- 6468,6478 ----
%}
ins_pipe( pipe_slow );
%}
// Load Aligned Packed Single to XMM
! instruct loadA2F(regXD dst, memory mem) %{
! instruct loadA2F(regD dst, memory mem) %{
predicate(UseSSE>=1);
match(Set dst (Load2F mem));
ins_cost(145);
format %{ "MOVQ $dst,$mem\t! packed2F" %}
ins_encode %{
*** 6604,6615 ****
--- 6582,6593 ----
opcode(0x33,0x33);
ins_encode( RegReg_Lo(dst,dst), RegReg_Hi(dst, dst) );
ins_pipe( ialu_reg_long );
%}
! // The instruction usage is guarded by predicate in operand immFPR().
! instruct loadConF(regF dst, immF con) %{
! instruct loadConFPR(regFPR dst, immFPR con) %{
match(Set dst con);
ins_cost(125);
format %{ "FLD_S ST,[$constantaddress]\t# load from constant table: float=$con\n\t"
"FSTP $dst" %}
ins_encode %{
*** 6617,6628 ****
--- 6595,6606 ----
__ fstp_d($dst$$reg);
%}
ins_pipe(fpu_reg_con);
%}
! // The instruction usage is guarded by predicate in operand immF0().
! instruct loadConF0(regF dst, immF0 con) %{
! // The instruction usage is guarded by predicate in operand immFPR0().
! instruct loadConFPR0(regFPR dst, immFPR0 con) %{
match(Set dst con);
ins_cost(125);
format %{ "FLDZ ST\n\t"
"FSTP $dst" %}
ins_encode %{
*** 6630,6641 ****
--- 6608,6619 ----
__ fstp_d($dst$$reg);
%}
ins_pipe(fpu_reg_con);
%}
! // The instruction usage is guarded by predicate in operand immF1().
! instruct loadConF1(regF dst, immF1 con) %{
! // The instruction usage is guarded by predicate in operand immFPR1().
! instruct loadConFPR1(regFPR dst, immFPR1 con) %{
match(Set dst con);
ins_cost(125);
format %{ "FLD1 ST\n\t"
"FSTP $dst" %}
ins_encode %{
*** 6643,6676 ****
--- 6621,6654 ----
__ fstp_d($dst$$reg);
%}
ins_pipe(fpu_reg_con);
%}
! // The instruction usage is guarded by predicate in operand immXF().
! instruct loadConX(regX dst, immXF con) %{
! // The instruction usage is guarded by predicate in operand immF().
! instruct loadConF(regF dst, immF con) %{
match(Set dst con);
ins_cost(125);
format %{ "MOVSS $dst,[$constantaddress]\t# load from constant table: float=$con" %}
ins_encode %{
__ movflt($dst$$XMMRegister, $constantaddress($con));
%}
ins_pipe(pipe_slow);
%}
! // The instruction usage is guarded by predicate in operand immXF0().
! instruct loadConX0(regX dst, immXF0 src) %{
! // The instruction usage is guarded by predicate in operand immF0().
! instruct loadConF0(regF dst, immF0 src) %{
match(Set dst src);
ins_cost(100);
format %{ "XORPS $dst,$dst\t# float 0.0" %}
ins_encode %{
__ xorps($dst$$XMMRegister, $dst$$XMMRegister);
%}
ins_pipe(pipe_slow);
%}
! // The instruction usage is guarded by predicate in operand immDPR().
! instruct loadConD(regD dst, immD con) %{
! instruct loadConDPR(regDPR dst, immDPR con) %{
match(Set dst con);
ins_cost(125);
format %{ "FLD_D ST,[$constantaddress]\t# load from constant table: double=$con\n\t"
"FSTP $dst" %}
*** 6679,6690 ****
--- 6657,6668 ----
__ fstp_d($dst$$reg);
%}
ins_pipe(fpu_reg_con);
%}
! // The instruction usage is guarded by predicate in operand immD0().
! instruct loadConD0(regD dst, immD0 con) %{
! // The instruction usage is guarded by predicate in operand immDPR0().
! instruct loadConDPR0(regDPR dst, immDPR0 con) %{
match(Set dst con);
ins_cost(125);
format %{ "FLDZ ST\n\t"
"FSTP $dst" %}
*** 6693,6704 ****
--- 6671,6682 ----
__ fstp_d($dst$$reg);
%}
ins_pipe(fpu_reg_con);
%}
! // The instruction usage is guarded by predicate in operand immD1().
! instruct loadConD1(regD dst, immD1 con) %{
! // The instruction usage is guarded by predicate in operand immDPR1().
! instruct loadConDPR1(regDPR dst, immDPR1 con) %{
match(Set dst con);
ins_cost(125);
format %{ "FLD1 ST\n\t"
"FSTP $dst" %}
*** 6707,6729 ****
--- 6685,6707 ----
__ fstp_d($dst$$reg);
%}
ins_pipe(fpu_reg_con);
%}
! // The instruction usage is guarded by predicate in operand immXD().
! instruct loadConXD(regXD dst, immXD con) %{
! // The instruction usage is guarded by predicate in operand immD().
! instruct loadConD(regD dst, immD con) %{
match(Set dst con);
ins_cost(125);
format %{ "MOVSD $dst,[$constantaddress]\t# load from constant table: double=$con" %}
ins_encode %{
__ movdbl($dst$$XMMRegister, $constantaddress($con));
%}
ins_pipe(pipe_slow);
%}
! // The instruction usage is guarded by predicate in operand immXD0().
! instruct loadConXD0(regXD dst, immXD0 src) %{
! // The instruction usage is guarded by predicate in operand immD0().
! instruct loadConD0(regD dst, immD0 src) %{
match(Set dst src);
ins_cost(100);
format %{ "XORPD $dst,$dst\t# double 0.0" %}
ins_encode %{
__ xorpd ($dst$$XMMRegister, $dst$$XMMRegister);
*** 6763,6794 ****
--- 6741,6772 ----
ins_encode( OpcP, RegMem(dst,src));
ins_pipe( ialu_reg_mem );
%}
// Load Stack Slot
! instruct loadSSF(regFPR dst, stackSlotF src) %{
match(Set dst src);
ins_cost(125);
format %{ "FLD_S $src\n\t"
"FSTP $dst" %}
opcode(0xD9); /* D9 /0, FLD m32real */
ins_encode( OpcP, RMopc_Mem_no_oop(0x00,src),
! Pop_Reg_FPR(dst) );
ins_pipe( fpu_reg_mem );
%}
// Load Stack Slot
! instruct loadSSD(regDPR dst, stackSlotD src) %{
match(Set dst src);
ins_cost(125);
format %{ "FLD_D $src\n\t"
"FSTP $dst" %}
opcode(0xDD); /* DD /0, FLD m64real */
ins_encode( OpcP, RMopc_Mem_no_oop(0x00,src),
! Pop_Reg_DPR(dst) );
ins_pipe( fpu_reg_mem );
%}
// Prefetch instructions.
// Must be safe to execute with invalid address (cannot fault).
*** 7019,7029 ****
--- 6997,7007 ----
opcode(0x3B);
ins_encode( OpcP, RegMem( EAX, mem ), enc_storeL_volatile(mem,src));
ins_pipe( fpu_reg_mem );
%}
! instruct storeLX_volatile(memory mem, stackSlotL src, regXD tmp, eFlagsReg cr) %{
! instruct storeLX_volatile(memory mem, stackSlotL src, regD tmp, eFlagsReg cr) %{
predicate(UseSSE>=2 && ((StoreLNode*)n)->require_atomic_access());
match(Set mem (StoreL mem src));
effect( TEMP tmp, KILL cr );
ins_cost(380);
format %{ "CMP $mem,EAX\t# Probe address for implicit null check\n\t"
*** 7035,7045 ****
--- 7013,7023 ----
__ movdbl($mem$$Address, $tmp$$XMMRegister);
%}
ins_pipe( pipe_slow );
%}
! instruct storeLX_reg_volatile(memory mem, eRegL src, regXD tmp2, regXD tmp, eFlagsReg cr) %{
! instruct storeLX_reg_volatile(memory mem, eRegL src, regD tmp2, regD tmp, eFlagsReg cr) %{
predicate(UseSSE>=2 && ((StoreLNode*)n)->require_atomic_access());
match(Set mem (StoreL mem src));
effect( TEMP tmp2 , TEMP tmp, KILL cr );
ins_cost(360);
format %{ "CMP $mem,EAX\t# Probe address for implicit null check\n\t"
*** 7113,7123 ****
--- 7091,7101 ----
ins_encode( OpcP, RMopc_Mem(0x00,mem), Con8or32( src ));
ins_pipe( ialu_mem_imm );
%}
// Store Aligned Packed Byte XMM register to memory
! instruct storeA8B(memory mem, regXD src) %{
! instruct storeA8B(memory mem, regD src) %{
predicate(UseSSE>=1);
match(Set mem (Store8B mem src));
ins_cost(145);
format %{ "MOVQ $mem,$src\t! packed8B" %}
ins_encode %{
*** 7125,7135 ****
--- 7103,7113 ----
%}
ins_pipe( pipe_slow );
%}
// Store Aligned Packed Char/Short XMM register to memory
! instruct storeA4C(memory mem, regXD src) %{
! instruct storeA4C(memory mem, regD src) %{
predicate(UseSSE>=1);
match(Set mem (Store4C mem src));
ins_cost(145);
format %{ "MOVQ $mem,$src\t! packed4C" %}
ins_encode %{
*** 7137,7147 ****
--- 7115,7125 ----
%}
ins_pipe( pipe_slow );
%}
// Store Aligned Packed Integer XMM register to memory
! instruct storeA2I(memory mem, regXD src) %{
! instruct storeA2I(memory mem, regD src) %{
predicate(UseSSE>=1);
match(Set mem (Store2I mem src));
ins_cost(145);
format %{ "MOVQ $mem,$src\t! packed2I" %}
ins_encode %{
*** 7160,7195 ****
--- 7138,7173 ----
ins_encode( OpcP, RMopc_Mem(0x00,mem), Con8or32( src ));
ins_pipe( ialu_mem_imm );
%}
// Store Double
! instruct storeDPR( memory mem, regDPR1 src) %{
predicate(UseSSE<=1);
match(Set mem (StoreD mem src));
ins_cost(100);
format %{ "FST_D $mem,$src" %}
opcode(0xDD); /* DD /2 */
! ins_encode( enc_FP_store(mem,src) );
! ins_encode( enc_FPR_store(mem,src) );
ins_pipe( fpu_mem_reg );
%}
// Store double does rounding on x86
! instruct storeD_rounded( memory mem, regDPR1 src) %{
! instruct storeDPR_rounded( memory mem, regDPR1 src) %{
predicate(UseSSE<=1);
match(Set mem (StoreD mem (RoundDouble src)));
ins_cost(100);
format %{ "FST_D $mem,$src\t# round" %}
opcode(0xDD); /* DD /2 */
! ins_encode( enc_FP_store(mem,src) );
! ins_encode( enc_FPR_store(mem,src) );
ins_pipe( fpu_mem_reg );
%}
// Store XMM register to memory (double-precision floating points)
// MOVSD instruction
! instruct storeXD(memory mem, regXD src) %{
! instruct storeD(memory mem, regD src) %{
predicate(UseSSE>=2);
match(Set mem (StoreD mem src));
ins_cost(95);
format %{ "MOVSD $mem,$src" %}
ins_encode %{
*** 7198,7208 ****
--- 7176,7186 ----
ins_pipe( pipe_slow );
%}
// Store XMM register to memory (single-precision floating point)
// MOVSS instruction
! instruct storeX(memory mem, regX src) %{
! instruct storeF(memory mem, regF src) %{
predicate(UseSSE>=1);
match(Set mem (StoreF mem src));
ins_cost(95);
format %{ "MOVSS $mem,$src" %}
ins_encode %{
*** 7210,7220 ****
--- 7188,7198 ----
%}
ins_pipe( pipe_slow );
%}
// Store Aligned Packed Single Float XMM register to memory
! instruct storeA2F(memory mem, regXD src) %{
! instruct storeA2F(memory mem, regD src) %{
predicate(UseSSE>=1);
match(Set mem (Store2F mem src));
ins_cost(145);
format %{ "MOVQ $mem,$src\t! packed2F" %}
ins_encode %{
*** 7222,7287 ****
--- 7200,7265 ----
%}
ins_pipe( pipe_slow );
%}
// Store Float
! instruct storeFPR( memory mem, regFPR1 src) %{
predicate(UseSSE==0);
match(Set mem (StoreF mem src));
ins_cost(100);
format %{ "FST_S $mem,$src" %}
opcode(0xD9); /* D9 /2 */
! ins_encode( enc_FP_store(mem,src) );
! ins_encode( enc_FPR_store(mem,src) );
ins_pipe( fpu_mem_reg );
%}
// Store Float does rounding on x86
! instruct storeF_rounded( memory mem, regFPR1 src) %{
! instruct storeFPR_rounded( memory mem, regFPR1 src) %{
predicate(UseSSE==0);
match(Set mem (StoreF mem (RoundFloat src)));
ins_cost(100);
format %{ "FST_S $mem,$src\t# round" %}
opcode(0xD9); /* D9 /2 */
! ins_encode( enc_FP_store(mem,src) );
! ins_encode( enc_FPR_store(mem,src) );
ins_pipe( fpu_mem_reg );
%}
// Store Float does rounding on x86
! instruct storeF_Drounded( memory mem, regDPR1 src) %{
! instruct storeFPR_Drounded( memory mem, regDPR1 src) %{
predicate(UseSSE<=1);
match(Set mem (StoreF mem (ConvD2F src)));
ins_cost(100);
format %{ "FST_S $mem,$src\t# D-round" %}
opcode(0xD9); /* D9 /2 */
! ins_encode( enc_FP_store(mem,src) );
! ins_encode( enc_FPR_store(mem,src) );
ins_pipe( fpu_mem_reg );
%}
// Store immediate Float value (it is faster than store from FPU register)
! // The instruction usage is guarded by predicate in operand immFPR().
! instruct storeF_imm( memory mem, immF src) %{
! instruct storeFPR_imm( memory mem, immFPR src) %{
match(Set mem (StoreF mem src));
ins_cost(50);
format %{ "MOV $mem,$src\t# store float" %}
opcode(0xC7); /* C7 /0 */
! ins_encode( OpcP, RMopc_Mem(0x00,mem), Con32F_as_bits( src ));
! ins_encode( OpcP, RMopc_Mem(0x00,mem), Con32FPR_as_bits( src ));
ins_pipe( ialu_mem_imm );
%}
// Store immediate Float value (it is faster than store from XMM register)
! // The instruction usage is guarded by predicate in operand immXF().
! instruct storeX_imm( memory mem, immXF src) %{
! // The instruction usage is guarded by predicate in operand immF().
! instruct storeF_imm( memory mem, immF src) %{
match(Set mem (StoreF mem src));
ins_cost(50);
format %{ "MOV $mem,$src\t# store float" %}
opcode(0xC7); /* C7 /0 */
! ins_encode( OpcP, RMopc_Mem(0x00,mem), Con32XF_as_bits( src ));
! ins_encode( OpcP, RMopc_Mem(0x00,mem), Con32F_as_bits( src ));
ins_pipe( ialu_mem_imm );
%}
// Store Integer to stack slot
instruct storeSSI(stackSlotI dst, eRegI src) %{
*** 7575,7633 ****
--- 7553,7611 ----
// ins_encode( enc_cmov(cop), RegMem( dst, src ) );
// ins_pipe( pipe_cmov_mem );
//%}
// Conditional move
! instruct fcmovD_regU(cmpOp_fcmov cop, eFlagsRegU cr, regDPR1 dst, regD src) %{
! instruct fcmovDPR_regU(cmpOp_fcmov cop, eFlagsRegU cr, regDPR1 dst, regDPR src) %{
predicate(UseSSE<=1);
match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
ins_cost(200);
format %{ "FCMOV$cop $dst,$src\t# double" %}
opcode(0xDA);
! ins_encode( enc_cmov_dpr(cop,src) );
! ins_pipe( pipe_cmovD_reg );
! ins_pipe( pipe_cmovDPR_reg );
%}
// Conditional move
! instruct fcmovF_regU(cmpOp_fcmov cop, eFlagsRegU cr, regFPR1 dst, regF src) %{
! instruct fcmovFPR_regU(cmpOp_fcmov cop, eFlagsRegU cr, regFPR1 dst, regFPR src) %{
predicate(UseSSE==0);
match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
ins_cost(200);
format %{ "FCMOV$cop $dst,$src\t# float" %}
opcode(0xDA);
! ins_encode( enc_cmov_dpr(cop,src) );
! ins_pipe( pipe_cmovD_reg );
! ins_pipe( pipe_cmovDPR_reg );
%}
// Float CMOV on Intel doesn't handle *signed* compares, only unsigned.
! instruct fcmovD_regS(cmpOp cop, eFlagsReg cr, regD dst, regD src) %{
! instruct fcmovDPR_regS(cmpOp cop, eFlagsReg cr, regDPR dst, regDPR src) %{
predicate(UseSSE<=1);
match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
ins_cost(200);
format %{ "Jn$cop skip\n\t"
"MOV $dst,$src\t# double\n"
"skip:" %}
opcode (0xdd, 0x3); /* DD D8+i or DD /3 */
! ins_encode( enc_cmov_branch( cop, 0x4 ), Push_Reg_DPR(src), OpcP, RegOpc(dst) );
! ins_pipe( pipe_cmovD_reg );
! ins_pipe( pipe_cmovDPR_reg );
%}
// Float CMOV on Intel doesn't handle *signed* compares, only unsigned.
! instruct fcmovF_regS(cmpOp cop, eFlagsReg cr, regF dst, regF src) %{
! instruct fcmovFPR_regS(cmpOp cop, eFlagsReg cr, regFPR dst, regFPR src) %{
predicate(UseSSE==0);
match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
ins_cost(200);
format %{ "Jn$cop skip\n\t"
"MOV $dst,$src\t# float\n"
"skip:" %}
opcode (0xdd, 0x3); /* DD D8+i or DD /3 */
! ins_encode( enc_cmov_branch( cop, 0x4 ), Push_Reg_FPR(src), OpcP, RegOpc(dst) );
! ins_pipe( pipe_cmovD_reg );
! ins_pipe( pipe_cmovDPR_reg );
%}
// No CMOVE with SSE/SSE2
! instruct fcmovX_regS(cmpOp cop, eFlagsReg cr, regX dst, regX src) %{
! instruct fcmovF_regS(cmpOp cop, eFlagsReg cr, regF dst, regF src) %{
predicate (UseSSE>=1);
match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
ins_cost(200);
format %{ "Jn$cop skip\n\t"
"MOVSS $dst,$src\t# float\n"
*** 7641,7651 ****
--- 7619,7629 ----
%}
ins_pipe( pipe_slow );
%}
// No CMOVE with SSE/SSE2
! instruct fcmovXD_regS(cmpOp cop, eFlagsReg cr, regXD dst, regXD src) %{
! instruct fcmovD_regS(cmpOp cop, eFlagsReg cr, regD dst, regD src) %{
predicate (UseSSE>=2);
match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
ins_cost(200);
format %{ "Jn$cop skip\n\t"
"MOVSD $dst,$src\t# float\n"
*** 7659,7669 ****
--- 7637,7647 ----
%}
ins_pipe( pipe_slow );
%}
// unsigned version
! instruct fcmovX_regU(cmpOpU cop, eFlagsRegU cr, regX dst, regX src) %{
! instruct fcmovF_regU(cmpOpU cop, eFlagsRegU cr, regF dst, regF src) %{
predicate (UseSSE>=1);
match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
ins_cost(200);
format %{ "Jn$cop skip\n\t"
"MOVSS $dst,$src\t# float\n"
*** 7676,7696 ****
--- 7654,7674 ----
__ bind(skip);
%}
ins_pipe( pipe_slow );
%}
! instruct fcmovX_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, regX dst, regX src) %{
! instruct fcmovF_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, regF dst, regF src) %{
predicate (UseSSE>=1);
match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
ins_cost(200);
expand %{
! fcmovX_regU(cop, cr, dst, src);
! fcmovF_regU(cop, cr, dst, src);
%}
%}
// unsigned version
! instruct fcmovXD_regU(cmpOpU cop, eFlagsRegU cr, regXD dst, regXD src) %{
! instruct fcmovD_regU(cmpOpU cop, eFlagsRegU cr, regD dst, regD src) %{
predicate (UseSSE>=2);
match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
ins_cost(200);
format %{ "Jn$cop skip\n\t"
"MOVSD $dst,$src\t# float\n"
*** 7703,7718 ****
--- 7681,7696 ----
__ bind(skip);
%}
ins_pipe( pipe_slow );
%}
! instruct fcmovXD_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, regXD dst, regXD src) %{
! instruct fcmovD_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, regD dst, regD src) %{
predicate (UseSSE>=2);
match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
ins_cost(200);
expand %{
! fcmovXD_regU(cop, cr, dst, src);
! fcmovD_regU(cop, cr, dst, src);
%}
%}
instruct cmovL_reg(cmpOp cop, eFlagsReg cr, eRegL dst, eRegL src) %{
predicate(VM_Version::supports_cmov() );
*** 7938,7948 ****
--- 7916,7926 ----
"FISTp $dst" %}
ins_encode(enc_loadL_volatile(mem,dst));
ins_pipe( fpu_reg_mem );
%}
! instruct loadLX_Locked(stackSlotL dst, memory mem, regXD tmp) %{
! instruct loadLX_Locked(stackSlotL dst, memory mem, regD 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"
*** 7952,7962 ****
--- 7930,7940 ----
__ movdbl(Address(rsp, $dst$$disp), $tmp$$XMMRegister);
%}
ins_pipe( pipe_slow );
%}
! instruct loadLX_reg_Locked(eRegL dst, memory mem, regXD tmp) %{
! instruct loadLX_reg_Locked(eRegL dst, memory mem, regD 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"
*** 9549,9559 ****
--- 9527,9537 ----
// Double Math
// Compare & branch
// P6 version of float compare, sets condition codes in EFLAGS
! instruct cmpD_cc_P6(eFlagsRegU cr, regD src1, regD src2, eAXRegI rax) %{
! instruct cmpDPR_cc_P6(eFlagsRegU cr, regDPR src1, regDPR src2, eAXRegI rax) %{
predicate(VM_Version::supports_cmov() && UseSSE <=1);
match(Set cr (CmpD src1 src2));
effect(KILL rax);
ins_cost(150);
format %{ "FLD $src1\n\t"
*** 9561,9590 ****
--- 9539,9568 ----
"JNP exit\n\t"
"MOV ah,1 // saw a NaN, set CF\n\t"
"SAHF\n"
"exit:\tNOP // avoid branch to branch" %}
opcode(0xDF, 0x05); /* DF E8+i or DF /5 */
! ins_encode( Push_Reg_DPR(src1),
OpcP, RegOpc(src2),
cmpF_P6_fixup );
ins_pipe( pipe_slow );
%}
! instruct cmpD_cc_P6CF(eFlagsRegUCF cr, regD src1, regD src2) %{
! instruct cmpDPR_cc_P6CF(eFlagsRegUCF cr, regDPR src1, regDPR src2) %{
predicate(VM_Version::supports_cmov() && UseSSE <=1);
match(Set cr (CmpD src1 src2));
ins_cost(150);
format %{ "FLD $src1\n\t"
"FUCOMIP ST,$src2 // P6 instruction" %}
opcode(0xDF, 0x05); /* DF E8+i or DF /5 */
! ins_encode( Push_Reg_DPR(src1),
OpcP, RegOpc(src2));
ins_pipe( pipe_slow );
%}
// Compare & branch
! instruct cmpD_cc(eFlagsRegU cr, regD src1, regD src2, eAXRegI rax) %{
! instruct cmpDPR_cc(eFlagsRegU cr, regDPR src1, regDPR src2, eAXRegI rax) %{
predicate(UseSSE<=1);
match(Set cr (CmpD src1 src2));
effect(KILL rax);
ins_cost(200);
format %{ "FLD $src1\n\t"
*** 9593,9638 ****
--- 9571,9616 ----
"TEST AX,0x400\n\t"
"JZ,s flags\n\t"
"MOV AH,1\t# unordered treat as LT\n"
"flags:\tSAHF" %}
opcode(0xD8, 0x3); /* D8 D8+i or D8 /3 */
! ins_encode( Push_Reg_DPR(src1),
OpcP, RegOpc(src2),
fpu_flags);
ins_pipe( pipe_slow );
%}
// Compare vs zero into -1,0,1
! instruct cmpD_0(eRegI dst, regD src1, immD0 zero, eAXRegI rax, eFlagsReg cr) %{
! instruct cmpDPR_0(eRegI dst, regDPR src1, immDPR0 zero, eAXRegI rax, eFlagsReg cr) %{
predicate(UseSSE<=1);
match(Set dst (CmpD3 src1 zero));
effect(KILL cr, KILL rax);
ins_cost(280);
format %{ "FTSTD $dst,$src1" %}
opcode(0xE4, 0xD9);
! ins_encode( Push_Reg_DPR(src1),
OpcS, OpcP, PopFPU,
CmpF_Result(dst));
ins_pipe( pipe_slow );
%}
// Compare into -1,0,1
! instruct cmpD_reg(eRegI dst, regD src1, regD src2, eAXRegI rax, eFlagsReg cr) %{
! instruct cmpDPR_reg(eRegI dst, regDPR src1, regDPR src2, eAXRegI rax, eFlagsReg cr) %{
predicate(UseSSE<=1);
match(Set dst (CmpD3 src1 src2));
effect(KILL cr, KILL rax);
ins_cost(300);
format %{ "FCMPD $dst,$src1,$src2" %}
opcode(0xD8, 0x3); /* D8 D8+i or D8 /3 */
! ins_encode( Push_Reg_DPR(src1),
OpcP, RegOpc(src2),
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) %{
! instruct cmpD_cc(eFlagsRegU cr, regD src1, regD src2) %{
predicate(UseSSE>=2);
match(Set cr (CmpD src1 src2));
ins_cost(145);
format %{ "UCOMISD $src1,$src2\n\t"
"JNP,s exit\n\t"
*** 9645,9655 ****
--- 9623,9633 ----
emit_cmpfp_fixup(_masm);
%}
ins_pipe( pipe_slow );
%}
! instruct cmpXD_ccCF(eFlagsRegUCF cr, regXD src1, regXD src2) %{
! instruct cmpD_ccCF(eFlagsRegUCF cr, regD src1, regD src2) %{
predicate(UseSSE>=2);
match(Set cr (CmpD src1 src2));
ins_cost(100);
format %{ "UCOMISD $src1,$src2" %}
ins_encode %{
*** 9657,9667 ****
--- 9635,9645 ----
%}
ins_pipe( pipe_slow );
%}
// float compare and set condition codes in EFLAGS by XMM regs
! instruct cmpXD_ccmem(eFlagsRegU cr, regXD src1, memory src2) %{
! instruct cmpD_ccmem(eFlagsRegU cr, regD 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"
*** 9674,9684 ****
--- 9652,9662 ----
emit_cmpfp_fixup(_masm);
%}
ins_pipe( pipe_slow );
%}
! instruct cmpXD_ccmemCF(eFlagsRegUCF cr, regXD src1, memory src2) %{
! instruct cmpD_ccmemCF(eFlagsRegUCF cr, regD src1, memory src2) %{
predicate(UseSSE>=2);
match(Set cr (CmpD src1 (LoadD src2)));
ins_cost(100);
format %{ "UCOMISD $src1,$src2" %}
ins_encode %{
*** 9686,9696 ****
--- 9664,9674 ----
%}
ins_pipe( pipe_slow );
%}
// Compare into -1,0,1 in XMM
! instruct cmpXD_reg(xRegI dst, regXD src1, regXD src2, eFlagsReg cr) %{
! instruct cmpD_reg(xRegI dst, regD src1, regD src2, eFlagsReg cr) %{
predicate(UseSSE>=2);
match(Set dst (CmpD3 src1 src2));
effect(KILL cr);
ins_cost(255);
format %{ "UCOMISD $src1, $src2\n\t"
*** 9706,9716 ****
--- 9684,9694 ----
%}
ins_pipe( pipe_slow );
%}
// Compare into -1,0,1 in XMM and memory
! instruct cmpXD_regmem(xRegI dst, regXD src1, memory src2, eFlagsReg cr) %{
! instruct cmpD_regmem(xRegI dst, regD 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"
*** 9726,9764 ****
--- 9704,9742 ----
%}
ins_pipe( pipe_slow );
%}
! instruct subD_reg(regD dst, regD src) %{
! instruct subDPR_reg(regDPR dst, regDPR src) %{
predicate (UseSSE <=1);
match(Set dst (SubD dst src));
format %{ "FLD $src\n\t"
"DSUBp $dst,ST" %}
opcode(0xDE, 0x5); /* DE E8+i or DE /5 */
ins_cost(150);
! ins_encode( Push_Reg_DPR(src),
OpcP, RegOpc(dst) );
ins_pipe( fpu_reg_reg );
%}
! instruct subD_reg_round(stackSlotD dst, regD src1, regD src2) %{
! instruct subDPR_reg_round(stackSlotD dst, regDPR src1, regDPR src2) %{
predicate (UseSSE <=1);
match(Set dst (RoundDouble (SubD src1 src2)));
ins_cost(250);
format %{ "FLD $src2\n\t"
"DSUB ST,$src1\n\t"
"FSTP_D $dst\t# D-round" %}
opcode(0xD8, 0x5);
! ins_encode( Push_Reg_DPR(src2),
! OpcP, RegOpc(src1), Pop_Mem_DPR(dst) );
ins_pipe( fpu_mem_reg_reg );
%}
! instruct subD_reg_mem(regD dst, memory src) %{
! instruct subDPR_reg_mem(regDPR dst, memory src) %{
predicate (UseSSE <=1);
match(Set dst (SubD dst (LoadD src)));
ins_cost(150);
format %{ "FLD $src\n\t"
*** 9767,9850 ****
--- 9745,9804 ----
ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src),
OpcP, RegOpc(dst) );
ins_pipe( fpu_reg_mem );
%}
! instruct absD_reg(regDPR1 dst, regDPR1 src) %{
! instruct absDPR_reg(regDPR1 dst, regDPR1 src) %{
predicate (UseSSE<=1);
match(Set dst (AbsD src));
ins_cost(100);
format %{ "FABS" %}
opcode(0xE1, 0xD9);
ins_encode( OpcS, OpcP );
ins_pipe( fpu_reg_reg );
%}
! 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) %{
! instruct negDPR_reg(regDPR1 dst, regDPR1 src) %{
predicate(UseSSE<=1);
match(Set dst (NegD src));
ins_cost(100);
format %{ "FCHS" %}
opcode(0xE0, 0xD9);
ins_encode( OpcS, OpcP );
ins_pipe( fpu_reg_reg );
%}
! 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));
%}
ins_pipe( pipe_slow );
%}
instruct addD_reg(regD dst, regD src) %{
! instruct addDPR_reg(regDPR dst, regDPR src) %{
predicate(UseSSE<=1);
match(Set dst (AddD dst src));
format %{ "FLD $src\n\t"
"DADD $dst,ST" %}
size(4);
ins_cost(150);
opcode(0xDE, 0x0); /* DE C0+i or DE /0*/
! ins_encode( Push_Reg_DPR(src),
OpcP, RegOpc(dst) );
ins_pipe( fpu_reg_reg );
%}
! instruct addD_reg_round(stackSlotD dst, regD src1, regD src2) %{
! instruct addDPR_reg_round(stackSlotD dst, regDPR src1, regDPR src2) %{
predicate(UseSSE<=1);
match(Set dst (RoundDouble (AddD src1 src2)));
ins_cost(250);
format %{ "FLD $src2\n\t"
"DADD ST,$src1\n\t"
"FSTP_D $dst\t# D-round" %}
opcode(0xD8, 0x0); /* D8 C0+i or D8 /0*/
! ins_encode( Push_Reg_DPR(src2),
! OpcP, RegOpc(src1), Pop_Mem_DPR(dst) );
ins_pipe( fpu_mem_reg_reg );
%}
! instruct addD_reg_mem(regD dst, memory src) %{
! instruct addDPR_reg_mem(regDPR dst, memory src) %{
predicate(UseSSE<=1);
match(Set dst (AddD dst (LoadD src)));
ins_cost(150);
format %{ "FLD $src\n\t"
*** 9854,9864 ****
--- 9808,9818 ----
OpcP, RegOpc(dst) );
ins_pipe( fpu_reg_mem );
%}
// add-to-memory
! instruct addD_mem_reg(memory dst, regD src) %{
! instruct addDPR_mem_reg(memory dst, regDPR src) %{
predicate(UseSSE<=1);
match(Set dst (StoreD dst (RoundDouble (AddD (LoadD dst) src))));
ins_cost(150);
format %{ "FLD_D $dst\n\t"
*** 9870,9880 ****
--- 9824,9834 ----
set_instruction_start,
Opcode(0xDD), RMopc_Mem(0x03,dst) );
ins_pipe( fpu_reg_mem );
%}
! instruct addD_reg_imm1(regD dst, immD1 con) %{
! instruct addDPR_reg_imm1(regDPR dst, immDPR1 con) %{
predicate(UseSSE<=1);
match(Set dst (AddD dst con));
ins_cost(125);
format %{ "FLD1\n\t"
"DADDp $dst,ST" %}
*** 9883,9893 ****
--- 9837,9847 ----
__ faddp($dst$$reg);
%}
ins_pipe(fpu_reg);
%}
! instruct addD_reg_imm(regD dst, immD con) %{
! instruct addDPR_reg_imm(regDPR dst, immDPR con) %{
predicate(UseSSE<=1 && _kids[1]->_leaf->getd() != 0.0 && _kids[1]->_leaf->getd() != 1.0 );
match(Set dst (AddD dst con));
ins_cost(200);
format %{ "FLD_D [$constantaddress]\t# load from constant table: double=$con\n\t"
"DADDp $dst,ST" %}
*** 9896,9906 ****
--- 9850,9860 ----
__ faddp($dst$$reg);
%}
ins_pipe(fpu_reg_mem);
%}
! instruct addD_reg_imm_round(stackSlotD dst, regD src, immD con) %{
! instruct addDPR_reg_imm_round(stackSlotD dst, regDPR src, immDPR con) %{
predicate(UseSSE<=1 && _kids[0]->_kids[1]->_leaf->getd() != 0.0 && _kids[0]->_kids[1]->_leaf->getd() != 1.0 );
match(Set dst (RoundDouble (AddD src con)));
ins_cost(200);
format %{ "FLD_D [$constantaddress]\t# load from constant table: double=$con\n\t"
"DADD ST,$src\n\t"
*** 9911,10057 ****
--- 9865,9882 ----
__ fstp_d(Address(rsp, $dst$$disp));
%}
ins_pipe(fpu_mem_reg_con);
%}
// 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);
match(Set dst (AddD dst con));
format %{ "ADDSD $dst,[$constantaddress]\t# load from constant table: double=$con" %}
ins_encode %{
__ addsd($dst$$XMMRegister, $constantaddress($con));
%}
ins_pipe(pipe_slow);
%}
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);
%}
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);
match(Set dst (MulD dst con));
format %{ "MULSD $dst,[$constantaddress]\t# load from constant table: double=$con" %}
ins_encode %{
__ mulsd($dst$$XMMRegister, $constantaddress($con));
%}
ins_pipe(pipe_slow);
%}
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);
match(Set dst (DivD dst con));
format %{ "DIVSD $dst,[$constantaddress]\t# load from constant table: double=$con" %}
ins_encode %{
__ divsd($dst$$XMMRegister, $constantaddress($con));
%}
ins_pipe(pipe_slow);
%}
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) %{
+ instruct mulDPR_reg(regDPR dst, regDPR src) %{
predicate(UseSSE<=1);
match(Set dst (MulD dst src));
format %{ "FLD $src\n\t"
"DMULp $dst,ST" %}
opcode(0xDE, 0x1); /* DE C8+i or DE /1*/
ins_cost(150);
! ins_encode( Push_Reg_DPR(src),
OpcP, RegOpc(dst) );
ins_pipe( fpu_reg_reg );
%}
// Strict FP instruction biases argument before multiply then
*** 10060,10070 ****
--- 9885,9895 ----
// scale arg1 by multiplying arg1 by 2^(-15360)
// load arg2
// multiply scaled arg1 by arg2
// rescale product by 2^(15360)
//
! instruct strictfp_mulD_reg(regDPR1 dst, regnotDPR1 src) %{
! instruct strictfp_mulDPR_reg(regDPR1 dst, regnotDPR1 src) %{
predicate( UseSSE<=1 && Compile::current()->has_method() && Compile::current()->method()->is_strict() );
match(Set dst (MulD dst src));
ins_cost(1); // Select this instruction for all strict FP double multiplies
format %{ "FLD StubRoutines::_fpu_subnormal_bias1\n\t"
*** 10073,10089 ****
--- 9898,9914 ----
"DMULp $dst,ST\n\t"
"FLD StubRoutines::_fpu_subnormal_bias2\n\t"
"DMULp $dst,ST\n\t" %}
opcode(0xDE, 0x1); /* DE C8+i or DE /1*/
ins_encode( strictfp_bias1(dst),
! Push_Reg_DPR(src),
OpcP, RegOpc(dst),
strictfp_bias2(dst) );
ins_pipe( fpu_reg_reg );
%}
! instruct mulD_reg_imm(regD dst, immD con) %{
! instruct mulDPR_reg_imm(regDPR dst, immDPR con) %{
predicate( UseSSE<=1 && _kids[1]->_leaf->getd() != 0.0 && _kids[1]->_leaf->getd() != 1.0 );
match(Set dst (MulD dst con));
ins_cost(200);
format %{ "FLD_D [$constantaddress]\t# load from constant table: double=$con\n\t"
"DMULp $dst,ST" %}
*** 10093,10103 ****
--- 9918,9928 ----
%}
ins_pipe(fpu_reg_mem);
%}
! instruct mulD_reg_mem(regD dst, memory src) %{
! instruct mulDPR_reg_mem(regDPR dst, memory src) %{
predicate( UseSSE<=1 );
match(Set dst (MulD dst (LoadD src)));
ins_cost(200);
format %{ "FLD_D $src\n\t"
"DMULp $dst,ST" %}
*** 10107,10174 ****
--- 9932,9999 ----
ins_pipe( fpu_reg_mem );
%}
//
// Cisc-alternate to reg-reg multiply
! instruct mulD_reg_mem_cisc(regD dst, regD src, memory mem) %{
! instruct mulDPR_reg_mem_cisc(regDPR dst, regDPR src, memory mem) %{
predicate( UseSSE<=1 );
match(Set dst (MulD src (LoadD mem)));
ins_cost(250);
format %{ "FLD_D $mem\n\t"
"DMUL ST,$src\n\t"
"FSTP_D $dst" %}
opcode(0xD8, 0x1, 0xD9); /* D8 C8+i */ /* LoadD D9 /0 */
ins_encode( Opcode(tertiary), RMopc_Mem(0x00,mem),
! OpcReg_FPR(src),
! Pop_Reg_DPR(dst) );
ins_pipe( fpu_reg_reg_mem );
%}
! // MACRO3 -- addDPR a mulDPR
// This instruction is a '2-address' instruction in that the result goes
// back to src2. This eliminates a move from the macro; possibly the
// register allocator will have to add it back (and maybe not).
! instruct addD_mulD_reg(regD src2, regD src1, regD src0) %{
! instruct addDPR_mulDPR_reg(regDPR src2, regDPR src1, regDPR src0) %{
predicate( UseSSE<=1 );
match(Set src2 (AddD (MulD src0 src1) src2));
format %{ "FLD $src0\t# ===MACRO3d===\n\t"
"DMUL ST,$src1\n\t"
"DADDp $src2,ST" %}
ins_cost(250);
opcode(0xDD); /* LoadD DD /0 */
! ins_encode( Push_Reg_FPR(src0),
FMul_ST_reg(src1),
FAddP_reg_ST(src2) );
ins_pipe( fpu_reg_reg_reg );
%}
! // MACRO3 -- subDPR a mulDPR
! instruct subD_mulD_reg(regD src2, regD src1, regD src0) %{
! instruct subDPR_mulDPR_reg(regDPR src2, regDPR src1, regDPR src0) %{
predicate( UseSSE<=1 );
match(Set src2 (SubD (MulD src0 src1) src2));
format %{ "FLD $src0\t# ===MACRO3d===\n\t"
"DMUL ST,$src1\n\t"
"DSUBRp $src2,ST" %}
ins_cost(250);
! ins_encode( Push_Reg_FPR(src0),
FMul_ST_reg(src1),
Opcode(0xDE), Opc_plus(0xE0,src2));
ins_pipe( fpu_reg_reg_reg );
%}
! instruct divD_reg(regD dst, regD src) %{
! instruct divDPR_reg(regDPR dst, regDPR src) %{
predicate( UseSSE<=1 );
match(Set dst (DivD dst src));
format %{ "FLD $src\n\t"
"FDIVp $dst,ST" %}
opcode(0xDE, 0x7); /* DE F8+i or DE /7*/
ins_cost(150);
! ins_encode( Push_Reg_DPR(src),
OpcP, RegOpc(dst) );
ins_pipe( fpu_reg_reg );
%}
// Strict FP instruction biases argument before division then
*** 10177,10187 ****
--- 10002,10012 ----
// scale dividend by multiplying dividend by 2^(-15360)
// load divisor
// divide scaled dividend by divisor
// rescale quotient by 2^(15360)
//
! instruct strictfp_divD_reg(regDPR1 dst, regnotDPR1 src) %{
! instruct strictfp_divDPR_reg(regDPR1 dst, regnotDPR1 src) %{
predicate (UseSSE<=1);
match(Set dst (DivD dst src));
predicate( UseSSE<=1 && Compile::current()->has_method() && Compile::current()->method()->is_strict() );
ins_cost(01);
*** 10191,10235 ****
--- 10016,10060 ----
"FDIVp $dst,ST\n\t"
"FLD StubRoutines::_fpu_subnormal_bias2\n\t"
"DMULp $dst,ST\n\t" %}
opcode(0xDE, 0x7); /* DE F8+i or DE /7*/
ins_encode( strictfp_bias1(dst),
! Push_Reg_DPR(src),
OpcP, RegOpc(dst),
strictfp_bias2(dst) );
ins_pipe( fpu_reg_reg );
%}
! instruct divD_reg_round(stackSlotD dst, regD src1, regD src2) %{
! instruct divDPR_reg_round(stackSlotD dst, regDPR src1, regDPR src2) %{
predicate( UseSSE<=1 && !(Compile::current()->has_method() && Compile::current()->method()->is_strict()) );
match(Set dst (RoundDouble (DivD src1 src2)));
format %{ "FLD $src1\n\t"
"FDIV ST,$src2\n\t"
"FSTP_D $dst\t# D-round" %}
opcode(0xD8, 0x6); /* D8 F0+i or D8 /6 */
! ins_encode( Push_Reg_DPR(src1),
! OpcP, RegOpc(src2), Pop_Mem_DPR(dst) );
ins_pipe( fpu_mem_reg_reg );
%}
! instruct modD_reg(regD dst, regD src, eAXRegI rax, eFlagsReg cr) %{
! instruct modDPR_reg(regDPR dst, regDPR src, eAXRegI rax, eFlagsReg cr) %{
predicate(UseSSE<=1);
match(Set dst (ModD dst src));
! effect(KILL rax, KILL cr); // emitModDPR() uses EAX and EFLAGS
format %{ "DMOD $dst,$src" %}
ins_cost(250);
! ins_encode(Push_Reg_Mod_DPR(dst, src),
! emitModDPR(),
! Push_Result_Mod_DPR(src),
! Pop_Reg_DPR(dst));
ins_pipe( pipe_slow );
%}
! instruct modXD_reg(regXD dst, regXD src0, regXD src1, eAXRegI rax, eFlagsReg cr) %{
! instruct modD_reg(regD dst, regD src0, regD src1, eAXRegI rax, eFlagsReg cr) %{
predicate(UseSSE>=2);
match(Set dst (ModD src0 src1));
effect(KILL rax, KILL cr);
format %{ "SUB ESP,8\t # DMOD\n"
*** 10246,10354 ****
--- 10071,10179 ----
"\tMOVSD $dst,[ESP+0]\n"
"\tADD ESP,8\n"
"\tFSTP ST0\t # Restore FPU Stack"
%}
ins_cost(250);
! ins_encode( Push_ModD_encoding(src0, src1), emitModD(), Push_ResultXD(dst), PopFPU);
! ins_encode( Push_ModD_encoding(src0, src1), emitModDPR(), Push_ResultD(dst), PopFPU);
ins_pipe( pipe_slow );
%}
! instruct sinD_reg(regDPR1 dst, regDPR1 src) %{
! instruct sinDPR_reg(regDPR1 dst, regDPR1 src) %{
predicate (UseSSE<=1);
match(Set dst (SinD src));
ins_cost(1800);
format %{ "DSIN $dst" %}
opcode(0xD9, 0xFE);
ins_encode( OpcP, OpcS );
ins_pipe( pipe_slow );
%}
! instruct sinXD_reg(regXD dst, eFlagsReg cr) %{
! instruct sinD_reg(regD dst, eFlagsReg cr) %{
predicate (UseSSE>=2);
match(Set dst (SinD dst));
- effect(KILL cr); // Push_{Src|Result}XD() uses "{SUB|ADD} ESP,8"
ins_cost(1800);
format %{ "DSIN $dst" %}
opcode(0xD9, 0xFE);
! ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) );
! ins_encode( Push_SrcD(dst), OpcP, OpcS, Push_ResultD(dst) );
ins_pipe( pipe_slow );
%}
! instruct cosD_reg(regDPR1 dst, regDPR1 src) %{
! instruct cosDPR_reg(regDPR1 dst, regDPR1 src) %{
predicate (UseSSE<=1);
match(Set dst (CosD src));
ins_cost(1800);
format %{ "DCOS $dst" %}
opcode(0xD9, 0xFF);
ins_encode( OpcP, OpcS );
ins_pipe( pipe_slow );
%}
! instruct cosXD_reg(regXD dst, eFlagsReg cr) %{
! instruct cosD_reg(regD dst, eFlagsReg cr) %{
predicate (UseSSE>=2);
match(Set dst (CosD dst));
- effect(KILL cr); // Push_{Src|Result}XD() uses "{SUB|ADD} ESP,8"
ins_cost(1800);
format %{ "DCOS $dst" %}
opcode(0xD9, 0xFF);
! ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) );
! ins_encode( Push_SrcD(dst), OpcP, OpcS, Push_ResultD(dst) );
ins_pipe( pipe_slow );
%}
! instruct tanD_reg(regDPR1 dst, regDPR1 src) %{
! instruct tanDPR_reg(regDPR1 dst, regDPR1 src) %{
predicate (UseSSE<=1);
match(Set dst(TanD src));
format %{ "DTAN $dst" %}
ins_encode( Opcode(0xD9), Opcode(0xF2), // fptan
Opcode(0xDD), Opcode(0xD8)); // fstp st
ins_pipe( pipe_slow );
%}
! instruct tanXD_reg(regXD dst, eFlagsReg cr) %{
! instruct tanD_reg(regD dst, eFlagsReg cr) %{
predicate (UseSSE>=2);
match(Set dst(TanD dst));
- effect(KILL cr); // Push_{Src|Result}XD() uses "{SUB|ADD} ESP,8"
format %{ "DTAN $dst" %}
! ins_encode( Push_SrcXD(dst),
! ins_encode( Push_SrcD(dst),
Opcode(0xD9), Opcode(0xF2), // fptan
Opcode(0xDD), Opcode(0xD8), // fstp st
! Push_ResultXD(dst) );
! Push_ResultD(dst) );
ins_pipe( pipe_slow );
%}
! instruct atanD_reg(regD dst, regD src) %{
! instruct atanDPR_reg(regDPR dst, regDPR src) %{
predicate (UseSSE<=1);
match(Set dst(AtanD dst src));
format %{ "DATA $dst,$src" %}
opcode(0xD9, 0xF3);
! ins_encode( Push_Reg_DPR(src),
OpcP, OpcS, RegOpc(dst) );
ins_pipe( pipe_slow );
%}
! instruct atanXD_reg(regXD dst, regXD src, eFlagsReg cr) %{
! instruct atanD_reg(regD dst, regD src, eFlagsReg cr) %{
predicate (UseSSE>=2);
match(Set dst(AtanD dst src));
- effect(KILL cr); // Push_{Src|Result}XD() uses "{SUB|ADD} ESP,8"
format %{ "DATA $dst,$src" %}
opcode(0xD9, 0xF3);
! ins_encode( Push_SrcXD(src),
! OpcP, OpcS, Push_ResultXD(dst) );
! ins_encode( Push_SrcD(src),
! OpcP, OpcS, Push_ResultD(dst) );
ins_pipe( pipe_slow );
%}
! instruct sqrtD_reg(regD dst, regD src) %{
! instruct sqrtDPR_reg(regDPR dst, regDPR src) %{
predicate (UseSSE<=1);
match(Set dst (SqrtD src));
format %{ "DSQRT $dst,$src" %}
opcode(0xFA, 0xD9);
! ins_encode( Push_Reg_DPR(src),
! OpcS, OpcP, Pop_Reg_DPR(dst) );
ins_pipe( pipe_slow );
%}
! instruct powD_reg(regD X, regDPR1 Y, eAXRegI rax, eBXRegI rbx, eCXRegI rcx) %{
! instruct powDPR_reg(regDPR X, regDPR1 Y, eAXRegI rax, eBXRegI rbx, eCXRegI rcx) %{
predicate (UseSSE<=1);
match(Set Y (PowD X Y)); // Raise X to the Yth power
effect(KILL rax, KILL rbx, KILL rcx);
format %{ "SUB ESP,8\t\t# Fast-path POW encoding\n\t"
"FLD_D $X\n\t"
*** 10373,10390 ****
--- 10198,10215 ----
"FMUL ST(0),[ESP+0]\t# Scale\n\t"
"ADD ESP,8"
%}
ins_encode( push_stack_temp_qword,
! Push_Reg_DPR(X),
Opcode(0xD9), Opcode(0xF1), // fyl2x
pow_exp_core_encoding,
pop_stack_temp_qword);
ins_pipe( pipe_slow );
%}
! instruct powXD_reg(regXD dst, regXD src0, regXD src1, regDPR1 tmp1, eAXRegI rax, eBXRegI rbx, eCXRegI rcx ) %{
! instruct powD_reg(regD dst, regD src0, regD src1, regDPR1 tmp1, eAXRegI rax, eBXRegI rbx, eCXRegI rcx ) %{
predicate (UseSSE>=2);
match(Set dst (PowD src0 src1)); // Raise src0 to the src1'th power
effect(KILL tmp1, KILL rax, KILL rbx, KILL rcx );
format %{ "SUB ESP,8\t\t# Fast-path POW encoding\n\t"
"MOVSD [ESP],$src1\n\t"
*** 10418,10433 ****
--- 10243,10258 ----
ins_encode( push_stack_temp_qword,
push_xmm_to_fpr1(src1),
push_xmm_to_fpr1(src0),
Opcode(0xD9), Opcode(0xF1), // fyl2x
pow_exp_core_encoding,
! Push_ResultXD(dst) );
! Push_ResultD(dst) );
ins_pipe( pipe_slow );
%}
! instruct expD_reg(regDPR1 dpr1, eAXRegI rax, eBXRegI rbx, eCXRegI rcx) %{
! instruct expDPR_reg(regDPR1 dpr1, eAXRegI rax, eBXRegI rbx, eCXRegI rcx) %{
predicate (UseSSE<=1);
match(Set dpr1 (ExpD dpr1));
effect(KILL rax, KILL rbx, KILL rcx);
format %{ "SUB ESP,8\t\t# Fast-path EXP encoding"
"FLDL2E \t\t\t# Ld log2(e) X\n\t"
*** 10459,10469 ****
--- 10284,10294 ----
pow_exp_core_encoding,
pop_stack_temp_qword);
ins_pipe( pipe_slow );
%}
! instruct expXD_reg(regXD dst, regXD src, regDPR1 tmp1, eAXRegI rax, eBXRegI rbx, eCXRegI rcx) %{
! instruct expD_reg(regD dst, regD src, regDPR1 tmp1, eAXRegI rax, eBXRegI rbx, eCXRegI rcx) %{
predicate (UseSSE>=2);
match(Set dst (ExpD src));
effect(KILL tmp1, KILL rax, KILL rbx, KILL rcx);
format %{ "SUB ESP,8\t\t# Fast-path EXP encoding\n\t"
"MOVSD [ESP],$src\n\t"
*** 10490,10510 ****
--- 10315,10335 ----
"FST_D [ESP]\n\t"
"MOVSD $dst,[ESP]\n\t"
"ADD ESP,8"
%}
! ins_encode( Push_SrcXD(src),
! ins_encode( Push_SrcD(src),
Opcode(0xD9), Opcode(0xEA), // fldl2e
Opcode(0xDE), Opcode(0xC9), // fmulp
pow_exp_core_encoding,
! Push_ResultXD(dst) );
! Push_ResultD(dst) );
ins_pipe( pipe_slow );
%}
! instruct log10D_reg(regDPR1 dst, regDPR1 src) %{
! instruct log10DPR_reg(regDPR1 dst, regDPR1 src) %{
predicate (UseSSE<=1);
// The source Double operand on FPU stack
match(Set dst (Log10D src));
// fldlg2 ; push log_10(2) on the FPU stack; full 80-bit number
// fxch ; swap ST(0) with ST(1)
*** 10518,10545 ****
--- 10343,10370 ----
Opcode(0xD9), Opcode(0xF1)); // fyl2x
ins_pipe( pipe_slow );
%}
! instruct log10XD_reg(regXD dst, regXD src, eFlagsReg cr) %{
! instruct log10D_reg(regD dst, regD src, eFlagsReg cr) %{
predicate (UseSSE>=2);
effect(KILL cr);
match(Set dst (Log10D src));
// fldlg2 ; push log_10(2) on the FPU stack; full 80-bit number
// fyl2x ; compute log_10(2) * log_2(x)
format %{ "FLDLG2 \t\t\t#Log10\n\t"
"FYL2X \t\t\t# Q=Log10*Log_2(x)"
%}
ins_encode( Opcode(0xD9), Opcode(0xEC), // fldlg2
! Push_SrcXD(src),
! Push_SrcD(src),
Opcode(0xD9), Opcode(0xF1), // fyl2x
! Push_ResultXD(dst));
! Push_ResultD(dst));
ins_pipe( pipe_slow );
%}
! instruct logD_reg(regDPR1 dst, regDPR1 src) %{
! instruct logDPR_reg(regDPR1 dst, regDPR1 src) %{
predicate (UseSSE<=1);
// The source Double operand on FPU stack
match(Set dst (LogD src));
// fldln2 ; push log_e(2) on the FPU stack; full 80-bit number
// fxch ; swap ST(0) with ST(1)
*** 10553,10563 ****
--- 10378,10388 ----
Opcode(0xD9), Opcode(0xF1)); // fyl2x
ins_pipe( pipe_slow );
%}
! instruct logXD_reg(regXD dst, regXD src, eFlagsReg cr) %{
! instruct logD_reg(regD dst, regD src, eFlagsReg cr) %{
predicate (UseSSE>=2);
effect(KILL cr);
// The source and result Double operands in XMM registers
match(Set dst (LogD src));
// fldln2 ; push log_e(2) on the FPU stack; full 80-bit number
*** 10564,10576 ****
--- 10389,10401 ----
// fyl2x ; compute log_e(2) * log_2(x)
format %{ "FLDLN2 \t\t\t#Log_e\n\t"
"FYL2X \t\t\t# Q=Log_e*Log_2(x)"
%}
ins_encode( Opcode(0xD9), Opcode(0xED), // fldln2
! Push_SrcXD(src),
! Push_SrcD(src),
Opcode(0xD9), Opcode(0xF1), // fyl2x
! Push_ResultXD(dst));
! Push_ResultD(dst));
ins_pipe( pipe_slow );
%}
//-------------Float Instructions-------------------------------
// Float Math
*** 10587,10597 ****
--- 10412,10422 ----
// jcc(Assembler::equal, exit);
// movl(dst, greater_result);
// exit:
// P6 version of float compare, sets condition codes in EFLAGS
! instruct cmpF_cc_P6(eFlagsRegU cr, regF src1, regF src2, eAXRegI rax) %{
! instruct cmpFPR_cc_P6(eFlagsRegU cr, regFPR src1, regFPR src2, eAXRegI rax) %{
predicate(VM_Version::supports_cmov() && UseSSE == 0);
match(Set cr (CmpF src1 src2));
effect(KILL rax);
ins_cost(150);
format %{ "FLD $src1\n\t"
*** 10599,10629 ****
--- 10424,10454 ----
"JNP exit\n\t"
"MOV ah,1 // saw a NaN, set CF (treat as LT)\n\t"
"SAHF\n"
"exit:\tNOP // avoid branch to branch" %}
opcode(0xDF, 0x05); /* DF E8+i or DF /5 */
! ins_encode( Push_Reg_DPR(src1),
OpcP, RegOpc(src2),
cmpF_P6_fixup );
ins_pipe( pipe_slow );
%}
! instruct cmpF_cc_P6CF(eFlagsRegUCF cr, regF src1, regF src2) %{
! instruct cmpFPR_cc_P6CF(eFlagsRegUCF cr, regFPR src1, regFPR src2) %{
predicate(VM_Version::supports_cmov() && UseSSE == 0);
match(Set cr (CmpF src1 src2));
ins_cost(100);
format %{ "FLD $src1\n\t"
"FUCOMIP ST,$src2 // P6 instruction" %}
opcode(0xDF, 0x05); /* DF E8+i or DF /5 */
! ins_encode( Push_Reg_DPR(src1),
OpcP, RegOpc(src2));
ins_pipe( pipe_slow );
%}
// Compare & branch
! instruct cmpF_cc(eFlagsRegU cr, regF src1, regF src2, eAXRegI rax) %{
! instruct cmpFPR_cc(eFlagsRegU cr, regFPR src1, regFPR src2, eAXRegI rax) %{
predicate(UseSSE == 0);
match(Set cr (CmpF src1 src2));
effect(KILL rax);
ins_cost(200);
format %{ "FLD $src1\n\t"
*** 10632,10677 ****
--- 10457,10502 ----
"TEST AX,0x400\n\t"
"JZ,s flags\n\t"
"MOV AH,1\t# unordered treat as LT\n"
"flags:\tSAHF" %}
opcode(0xD8, 0x3); /* D8 D8+i or D8 /3 */
! ins_encode( Push_Reg_DPR(src1),
OpcP, RegOpc(src2),
fpu_flags);
ins_pipe( pipe_slow );
%}
// Compare vs zero into -1,0,1
! instruct cmpF_0(eRegI dst, regF src1, immF0 zero, eAXRegI rax, eFlagsReg cr) %{
! instruct cmpFPR_0(eRegI dst, regFPR src1, immFPR0 zero, eAXRegI rax, eFlagsReg cr) %{
predicate(UseSSE == 0);
match(Set dst (CmpF3 src1 zero));
effect(KILL cr, KILL rax);
ins_cost(280);
format %{ "FTSTF $dst,$src1" %}
opcode(0xE4, 0xD9);
! ins_encode( Push_Reg_DPR(src1),
OpcS, OpcP, PopFPU,
CmpF_Result(dst));
ins_pipe( pipe_slow );
%}
// Compare into -1,0,1
! instruct cmpF_reg(eRegI dst, regF src1, regF src2, eAXRegI rax, eFlagsReg cr) %{
! instruct cmpFPR_reg(eRegI dst, regFPR src1, regFPR src2, eAXRegI rax, eFlagsReg cr) %{
predicate(UseSSE == 0);
match(Set dst (CmpF3 src1 src2));
effect(KILL cr, KILL rax);
ins_cost(300);
format %{ "FCMPF $dst,$src1,$src2" %}
opcode(0xD8, 0x3); /* D8 D8+i or D8 /3 */
! ins_encode( Push_Reg_DPR(src1),
OpcP, RegOpc(src2),
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) %{
! instruct cmpF_cc(eFlagsRegU cr, regF src1, regF src2) %{
predicate(UseSSE>=1);
match(Set cr (CmpF src1 src2));
ins_cost(145);
format %{ "UCOMISS $src1,$src2\n\t"
"JNP,s exit\n\t"
*** 10684,10694 ****
--- 10509,10519 ----
emit_cmpfp_fixup(_masm);
%}
ins_pipe( pipe_slow );
%}
! instruct cmpX_ccCF(eFlagsRegUCF cr, regX src1, regX src2) %{
! instruct cmpF_ccCF(eFlagsRegUCF cr, regF src1, regF src2) %{
predicate(UseSSE>=1);
match(Set cr (CmpF src1 src2));
ins_cost(100);
format %{ "UCOMISS $src1,$src2" %}
ins_encode %{
*** 10696,10706 ****
--- 10521,10531 ----
%}
ins_pipe( pipe_slow );
%}
// float compare and set condition codes in EFLAGS by XMM regs
! instruct cmpX_ccmem(eFlagsRegU cr, regX src1, memory src2) %{
! instruct cmpF_ccmem(eFlagsRegU cr, regF 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"
*** 10713,10723 ****
--- 10538,10548 ----
emit_cmpfp_fixup(_masm);
%}
ins_pipe( pipe_slow );
%}
! instruct cmpX_ccmemCF(eFlagsRegUCF cr, regX src1, memory src2) %{
! instruct cmpF_ccmemCF(eFlagsRegUCF cr, regF src1, memory src2) %{
predicate(UseSSE>=1);
match(Set cr (CmpF src1 (LoadF src2)));
ins_cost(100);
format %{ "UCOMISS $src1,$src2" %}
ins_encode %{
*** 10725,10735 ****
--- 10550,10560 ----
%}
ins_pipe( pipe_slow );
%}
// Compare into -1,0,1 in XMM
! instruct cmpX_reg(xRegI dst, regX src1, regX src2, eFlagsReg cr) %{
! instruct cmpF_reg(xRegI dst, regF src1, regF src2, eFlagsReg cr) %{
predicate(UseSSE>=1);
match(Set dst (CmpF3 src1 src2));
effect(KILL cr);
ins_cost(255);
format %{ "UCOMISS $src1, $src2\n\t"
*** 10745,10755 ****
--- 10570,10580 ----
%}
ins_pipe( pipe_slow );
%}
// Compare into -1,0,1 in XMM and memory
! instruct cmpX_regmem(xRegI dst, regX src1, memory src2, eFlagsReg cr) %{
! instruct cmpF_regmem(xRegI dst, regF 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"
*** 10765,11060 ****
--- 10590,10688 ----
%}
ins_pipe( pipe_slow );
%}
// Spill to obtain 24-bit precision
! instruct subF24_reg(stackSlotF dst, regF src1, regF src2) %{
! instruct subFPR24_reg(stackSlotF dst, regFPR src1, regFPR src2) %{
predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
match(Set dst (SubF src1 src2));
format %{ "FSUB $dst,$src1 - $src2" %}
opcode(0xD8, 0x4); /* D8 E0+i or D8 /4 mod==0x3 ;; result in TOS */
! ins_encode( Push_Reg_FPR(src1),
! OpcReg_FPR(src2),
! Pop_Mem_FPR(dst) );
ins_pipe( fpu_mem_reg_reg );
%}
//
// This instruction does not round to 24-bits
! instruct subF_reg(regF dst, regF src) %{
! instruct subFPR_reg(regFPR dst, regFPR src) %{
predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr());
match(Set dst (SubF dst src));
format %{ "FSUB $dst,$src" %}
opcode(0xDE, 0x5); /* DE E8+i or DE /5 */
! ins_encode( Push_Reg_FPR(src),
OpcP, RegOpc(dst) );
ins_pipe( fpu_reg_reg );
%}
// Spill to obtain 24-bit precision
! instruct addF24_reg(stackSlotF dst, regF src1, regF src2) %{
! instruct addFPR24_reg(stackSlotF dst, regFPR src1, regFPR src2) %{
predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
match(Set dst (AddF src1 src2));
format %{ "FADD $dst,$src1,$src2" %}
opcode(0xD8, 0x0); /* D8 C0+i */
! ins_encode( Push_Reg_FPR(src2),
! OpcReg_FPR(src1),
! Pop_Mem_FPR(dst) );
ins_pipe( fpu_mem_reg_reg );
%}
//
// This instruction does not round to 24-bits
! instruct addF_reg(regF dst, regF src) %{
! instruct addFPR_reg(regFPR dst, regFPR src) %{
predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr());
match(Set dst (AddF dst src));
format %{ "FLD $src\n\t"
"FADDp $dst,ST" %}
opcode(0xDE, 0x0); /* DE C0+i or DE /0*/
! ins_encode( Push_Reg_FPR(src),
OpcP, RegOpc(dst) );
ins_pipe( fpu_reg_reg );
%}
// 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);
match(Set dst (AddF dst con));
format %{ "ADDSS $dst,[$constantaddress]\t# load from constant table: float=$con" %}
ins_encode %{
__ addss($dst$$XMMRegister, $constantaddress($con));
%}
ins_pipe(pipe_slow);
%}
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);
%}
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);
match(Set dst (MulF dst con));
format %{ "MULSS $dst,[$constantaddress]\t# load from constant table: float=$con" %}
ins_encode %{
__ mulss($dst$$XMMRegister, $constantaddress($con));
%}
ins_pipe(pipe_slow);
%}
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);
match(Set dst (DivF dst con));
format %{ "DIVSS $dst,[$constantaddress]\t# load from constant table: float=$con" %}
ins_encode %{
__ divss($dst$$XMMRegister, $constantaddress($con));
%}
ins_pipe(pipe_slow);
%}
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) %{
+ instruct absFPR_reg(regFPR1 dst, regFPR1 src) %{
predicate(UseSSE==0);
match(Set dst (AbsF src));
ins_cost(100);
format %{ "FABS" %}
opcode(0xE1, 0xD9);
ins_encode( OpcS, OpcP );
ins_pipe( fpu_reg_reg );
%}
! 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) %{
! instruct negFPR_reg(regFPR1 dst, regFPR1 src) %{
predicate(UseSSE==0);
match(Set dst (NegF src));
ins_cost(100);
format %{ "FCHS" %}
opcode(0xE0, 0xD9);
ins_encode( OpcS, OpcP );
ins_pipe( fpu_reg_reg );
%}
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
+ // Cisc-alternate to addFPR_reg
// Spill to obtain 24-bit precision
! instruct addF24_reg_mem(stackSlotF dst, regF src1, memory src2) %{
! instruct addFPR24_reg_mem(stackSlotF dst, regFPR src1, memory src2) %{
predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
match(Set dst (AddF src1 (LoadF src2)));
format %{ "FLD $src2\n\t"
"FADD ST,$src1\n\t"
"FSTP_S $dst" %}
opcode(0xD8, 0x0, 0xD9); /* D8 C0+i */ /* LoadF D9 /0 */
ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src2),
! OpcReg_FPR(src1),
! Pop_Mem_FPR(dst) );
ins_pipe( fpu_mem_reg_mem );
%}
//
! // Cisc-alternate to addF_reg
! // Cisc-alternate to addFPR_reg
// This instruction does not round to 24-bits
! instruct addF_reg_mem(regF dst, memory src) %{
! instruct addFPR_reg_mem(regFPR dst, memory src) %{
predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr());
match(Set dst (AddF dst (LoadF src)));
format %{ "FADD $dst,$src" %}
opcode(0xDE, 0x0, 0xD9); /* DE C0+i or DE /0*/ /* LoadF D9 /0 */
*** 11063,11116 ****
--- 10691,10744 ----
ins_pipe( fpu_reg_mem );
%}
// // Following two instructions for _222_mpegaudio
// Spill to obtain 24-bit precision
! instruct addF24_mem_reg(stackSlotF dst, regF src2, memory src1 ) %{
! instruct addFPR24_mem_reg(stackSlotF dst, regFPR src2, memory src1 ) %{
predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
match(Set dst (AddF src1 src2));
format %{ "FADD $dst,$src1,$src2" %}
opcode(0xD8, 0x0, 0xD9); /* D8 C0+i */ /* LoadF D9 /0 */
ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src1),
! OpcReg_FPR(src2),
! Pop_Mem_FPR(dst) );
ins_pipe( fpu_mem_reg_mem );
%}
// Cisc-spill variant
// Spill to obtain 24-bit precision
! instruct addF24_mem_cisc(stackSlotF dst, memory src1, memory src2) %{
! instruct addFPR24_mem_cisc(stackSlotF dst, memory src1, memory src2) %{
predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
match(Set dst (AddF src1 (LoadF src2)));
format %{ "FADD $dst,$src1,$src2 cisc" %}
opcode(0xD8, 0x0, 0xD9); /* D8 C0+i */ /* LoadF D9 /0 */
ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src2),
set_instruction_start,
OpcP, RMopc_Mem(secondary,src1),
! Pop_Mem_FPR(dst) );
ins_pipe( fpu_mem_mem_mem );
%}
// Spill to obtain 24-bit precision
! instruct addF24_mem_mem(stackSlotF dst, memory src1, memory src2) %{
! instruct addFPR24_mem_mem(stackSlotF dst, memory src1, memory src2) %{
predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
match(Set dst (AddF src1 src2));
format %{ "FADD $dst,$src1,$src2" %}
opcode(0xD8, 0x0, 0xD9); /* D8 /0 */ /* LoadF D9 /0 */
ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src2),
set_instruction_start,
OpcP, RMopc_Mem(secondary,src1),
! Pop_Mem_FPR(dst) );
ins_pipe( fpu_mem_mem_mem );
%}
// Spill to obtain 24-bit precision
! instruct addF24_reg_imm(stackSlotF dst, regF src, immF con) %{
! instruct addFPR24_reg_imm(stackSlotF dst, regFPR src, immFPR con) %{
predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
match(Set dst (AddF src con));
format %{ "FLD $src\n\t"
"FADD_S [$constantaddress]\t# load from constant table: float=$con\n\t"
"FSTP_S $dst" %}
*** 11121,11131 ****
--- 10749,10759 ----
%}
ins_pipe(fpu_mem_reg_con);
%}
//
// This instruction does not round to 24-bits
! instruct addF_reg_imm(regF dst, regF src, immF con) %{
! instruct addFPR_reg_imm(regFPR dst, regFPR src, immFPR con) %{
predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr());
match(Set dst (AddF src con));
format %{ "FLD $src\n\t"
"FADD_S [$constantaddress]\t# load from constant table: float=$con\n\t"
"FSTP $dst" %}
*** 11136,11221 ****
--- 10764,10849 ----
%}
ins_pipe(fpu_reg_reg_con);
%}
// Spill to obtain 24-bit precision
! instruct mulF24_reg(stackSlotF dst, regF src1, regF src2) %{
! instruct mulFPR24_reg(stackSlotF dst, regFPR src1, regFPR src2) %{
predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
match(Set dst (MulF src1 src2));
format %{ "FLD $src1\n\t"
"FMUL $src2\n\t"
"FSTP_S $dst" %}
opcode(0xD8, 0x1); /* D8 C8+i or D8 /1 ;; result in TOS */
! ins_encode( Push_Reg_FPR(src1),
! OpcReg_FPR(src2),
! Pop_Mem_FPR(dst) );
ins_pipe( fpu_mem_reg_reg );
%}
//
// This instruction does not round to 24-bits
! instruct mulF_reg(regF dst, regF src1, regF src2) %{
! instruct mulFPR_reg(regFPR dst, regFPR src1, regFPR src2) %{
predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr());
match(Set dst (MulF src1 src2));
format %{ "FLD $src1\n\t"
"FMUL $src2\n\t"
"FSTP_S $dst" %}
opcode(0xD8, 0x1); /* D8 C8+i */
! ins_encode( Push_Reg_FPR(src2),
! OpcReg_FPR(src1),
! Pop_Reg_FPR(dst) );
ins_pipe( fpu_reg_reg_reg );
%}
// Spill to obtain 24-bit precision
// Cisc-alternate to reg-reg multiply
! instruct mulF24_reg_mem(stackSlotF dst, regF src1, memory src2) %{
! instruct mulFPR24_reg_mem(stackSlotF dst, regFPR src1, memory src2) %{
predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
match(Set dst (MulF src1 (LoadF src2)));
format %{ "FLD_S $src2\n\t"
"FMUL $src1\n\t"
"FSTP_S $dst" %}
opcode(0xD8, 0x1, 0xD9); /* D8 C8+i or DE /1*/ /* LoadF D9 /0 */
ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src2),
! OpcReg_FPR(src1),
! Pop_Mem_FPR(dst) );
ins_pipe( fpu_mem_reg_mem );
%}
//
// This instruction does not round to 24-bits
// Cisc-alternate to reg-reg multiply
! instruct mulF_reg_mem(regF dst, regF src1, memory src2) %{
! instruct mulFPR_reg_mem(regFPR dst, regFPR src1, memory src2) %{
predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr());
match(Set dst (MulF src1 (LoadF src2)));
format %{ "FMUL $dst,$src1,$src2" %}
opcode(0xD8, 0x1, 0xD9); /* D8 C8+i */ /* LoadF D9 /0 */
ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src2),
! OpcReg_FPR(src1),
! Pop_Reg_FPR(dst) );
ins_pipe( fpu_reg_reg_mem );
%}
// Spill to obtain 24-bit precision
! instruct mulF24_mem_mem(stackSlotF dst, memory src1, memory src2) %{
! instruct mulFPR24_mem_mem(stackSlotF dst, memory src1, memory src2) %{
predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
match(Set dst (MulF src1 src2));
format %{ "FMUL $dst,$src1,$src2" %}
opcode(0xD8, 0x1, 0xD9); /* D8 /1 */ /* LoadF D9 /0 */
ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src2),
set_instruction_start,
OpcP, RMopc_Mem(secondary,src1),
! Pop_Mem_FPR(dst) );
ins_pipe( fpu_mem_mem_mem );
%}
// Spill to obtain 24-bit precision
! instruct mulF24_reg_imm(stackSlotF dst, regF src, immF con) %{
! instruct mulFPR24_reg_imm(stackSlotF dst, regFPR src, immFPR con) %{
predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
match(Set dst (MulF src con));
format %{ "FLD $src\n\t"
"FMUL_S [$constantaddress]\t# load from constant table: float=$con\n\t"
*** 11227,11237 ****
--- 10855,10865 ----
%}
ins_pipe(fpu_mem_reg_con);
%}
//
// This instruction does not round to 24-bits
! instruct mulF_reg_imm(regF dst, regF src, immF con) %{
! instruct mulFPR_reg_imm(regFPR dst, regFPR src, immFPR con) %{
predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr());
match(Set dst (MulF src con));
format %{ "FLD $src\n\t"
"FMUL_S [$constantaddress]\t# load from constant table: float=$con\n\t"
*** 11244,11379 ****
--- 10872,11007 ----
ins_pipe(fpu_reg_reg_con);
%}
//
! // MACRO1 -- subsume unshared load into mulFPR
// This instruction does not round to 24-bits
! instruct mulF_reg_load1(regF dst, regF src, memory mem1 ) %{
! instruct mulFPR_reg_load1(regFPR dst, regFPR src, memory mem1 ) %{
predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr());
match(Set dst (MulF (LoadF mem1) src));
format %{ "FLD $mem1 ===MACRO1===\n\t"
"FMUL ST,$src\n\t"
"FSTP $dst" %}
opcode(0xD8, 0x1, 0xD9); /* D8 C8+i or D8 /1 */ /* LoadF D9 /0 */
ins_encode( Opcode(tertiary), RMopc_Mem(0x00,mem1),
! OpcReg_FPR(src),
! Pop_Reg_FPR(dst) );
ins_pipe( fpu_reg_reg_mem );
%}
//
! // MACRO2 -- addFPR a mulFPR which subsumed an unshared load
// This instruction does not round to 24-bits
! instruct addF_mulF_reg_load1(regF dst, memory mem1, regF src1, regF src2) %{
! instruct addFPR_mulFPR_reg_load1(regFPR dst, memory mem1, regFPR src1, regFPR src2) %{
predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr());
match(Set dst (AddF (MulF (LoadF mem1) src1) src2));
ins_cost(95);
format %{ "FLD $mem1 ===MACRO2===\n\t"
! "FMUL ST,$src1 subsume mulFPR left load\n\t"
"FADD ST,$src2\n\t"
"FSTP $dst" %}
opcode(0xD9); /* LoadF D9 /0 */
ins_encode( OpcP, RMopc_Mem(0x00,mem1),
FMul_ST_reg(src1),
FAdd_ST_reg(src2),
! Pop_Reg_FPR(dst) );
ins_pipe( fpu_reg_mem_reg_reg );
%}
! // MACRO3 -- addFPR a mulFPR
// This instruction does not round to 24-bits. It is a '2-address'
// instruction in that the result goes back to src2. This eliminates
// a move from the macro; possibly the register allocator will have
// to add it back (and maybe not).
! instruct addF_mulF_reg(regF src2, regF src1, regF src0) %{
! instruct addFPR_mulFPR_reg(regFPR src2, regFPR src1, regFPR src0) %{
predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr());
match(Set src2 (AddF (MulF src0 src1) src2));
format %{ "FLD $src0 ===MACRO3===\n\t"
"FMUL ST,$src1\n\t"
"FADDP $src2,ST" %}
opcode(0xD9); /* LoadF D9 /0 */
! ins_encode( Push_Reg_FPR(src0),
FMul_ST_reg(src1),
FAddP_reg_ST(src2) );
ins_pipe( fpu_reg_reg_reg );
%}
! // MACRO4 -- divFPR subFPR
// This instruction does not round to 24-bits
! instruct subF_divF_reg(regF dst, regF src1, regF src2, regF src3) %{
! instruct subFPR_divFPR_reg(regFPR dst, regFPR src1, regFPR src2, regFPR src3) %{
predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr());
match(Set dst (DivF (SubF src2 src1) src3));
format %{ "FLD $src2 ===MACRO4===\n\t"
"FSUB ST,$src1\n\t"
"FDIV ST,$src3\n\t"
"FSTP $dst" %}
opcode(0xDE, 0x7); /* DE F8+i or DE /7*/
! ins_encode( Push_Reg_FPR(src2),
! subF_divF_encode(src1,src3),
! Pop_Reg_F(dst) );
! subFPR_divFPR_encode(src1,src3),
! Pop_Reg_FPR(dst) );
ins_pipe( fpu_reg_reg_reg_reg );
%}
// Spill to obtain 24-bit precision
! instruct divF24_reg(stackSlotF dst, regF src1, regF src2) %{
! instruct divFPR24_reg(stackSlotF dst, regFPR src1, regFPR src2) %{
predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
match(Set dst (DivF src1 src2));
format %{ "FDIV $dst,$src1,$src2" %}
opcode(0xD8, 0x6); /* D8 F0+i or DE /6*/
! ins_encode( Push_Reg_FPR(src1),
! OpcReg_FPR(src2),
! Pop_Mem_FPR(dst) );
ins_pipe( fpu_mem_reg_reg );
%}
//
// This instruction does not round to 24-bits
! instruct divF_reg(regF dst, regF src) %{
! instruct divFPR_reg(regFPR dst, regFPR src) %{
predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr());
match(Set dst (DivF dst src));
format %{ "FDIV $dst,$src" %}
opcode(0xDE, 0x7); /* DE F8+i or DE /7*/
! ins_encode( Push_Reg_FPR(src),
OpcP, RegOpc(dst) );
ins_pipe( fpu_reg_reg );
%}
// Spill to obtain 24-bit precision
! instruct modF24_reg(stackSlotF dst, regF src1, regF src2, eAXRegI rax, eFlagsReg cr) %{
! instruct modFPR24_reg(stackSlotF dst, regFPR src1, regFPR src2, eAXRegI rax, eFlagsReg cr) %{
predicate( UseSSE==0 && Compile::current()->select_24_bit_instr());
match(Set dst (ModF src1 src2));
! effect(KILL rax, KILL cr); // emitModDPR() uses EAX and EFLAGS
format %{ "FMOD $dst,$src1,$src2" %}
! ins_encode( Push_Reg_Mod_DPR(src1, src2),
! emitModDPR(),
! Push_Result_Mod_DPR(src2),
! Pop_Mem_FPR(dst));
ins_pipe( pipe_slow );
%}
//
// This instruction does not round to 24-bits
! instruct modF_reg(regF dst, regF src, eAXRegI rax, eFlagsReg cr) %{
! instruct modFPR_reg(regFPR dst, regFPR src, eAXRegI rax, eFlagsReg cr) %{
predicate( UseSSE==0 && !Compile::current()->select_24_bit_instr());
match(Set dst (ModF dst src));
! effect(KILL rax, KILL cr); // emitModDPR() uses EAX and EFLAGS
format %{ "FMOD $dst,$src" %}
! ins_encode(Push_Reg_Mod_DPR(dst, src),
! emitModDPR(),
! Push_Result_Mod_DPR(src),
! Pop_Reg_FPR(dst));
ins_pipe( pipe_slow );
%}
! instruct modX_reg(regX dst, regX src0, regX src1, eAXRegI rax, eFlagsReg cr) %{
! instruct modF_reg(regF dst, regF src0, regF src1, eAXRegI rax, eFlagsReg cr) %{
predicate(UseSSE>=1);
match(Set dst (ModF src0 src1));
effect(KILL rax, KILL cr);
format %{ "SUB ESP,4\t # FMOD\n"
"\tMOVSS [ESP+0],$src1\n"
*** 11389,11436 ****
--- 11017,11064 ----
"\tMOVSS $dst,[ESP+0]\n"
"\tADD ESP,4\n"
"\tFSTP ST0\t # Restore FPU Stack"
%}
ins_cost(250);
! ins_encode( Push_ModX_encoding(src0, src1), emitModD(), Push_ResultX(dst,0x4), PopFPU);
! ins_encode( Push_ModF_encoding(src0, src1), emitModDPR(), Push_ResultF(dst,0x4), PopFPU);
ins_pipe( pipe_slow );
%}
//----------Arithmetic Conversion Instructions---------------------------------
// The conversions operations are all Alpha sorted. Please keep it that way!
! instruct roundFloat_mem_reg(stackSlotF dst, regFPR src) %{
predicate(UseSSE==0);
match(Set dst (RoundFloat src));
ins_cost(125);
format %{ "FST_S $dst,$src\t# F-round" %}
! ins_encode( Pop_Mem_Reg_FPR(dst, src) );
ins_pipe( fpu_mem_reg );
%}
! instruct roundDouble_mem_reg(stackSlotD dst, regDPR src) %{
predicate(UseSSE<=1);
match(Set dst (RoundDouble src));
ins_cost(125);
format %{ "FST_D $dst,$src\t# D-round" %}
! ins_encode( Pop_Mem_Reg_DPR(dst, src) );
ins_pipe( fpu_mem_reg );
%}
// Force rounding to 24-bit precision and 6-bit exponent
! instruct convD2F_reg(stackSlotF dst, regD src) %{
! instruct convDPR2FPR_reg(stackSlotF dst, regDPR src) %{
predicate(UseSSE==0);
match(Set dst (ConvD2F src));
format %{ "FST_S $dst,$src\t# F-round" %}
expand %{
roundFloat_mem_reg(dst,src);
%}
%}
// Force rounding to 24-bit precision and 6-bit exponent
! instruct convD2X_reg(regX dst, regD src, eFlagsReg cr) %{
! instruct convDPR2F_reg(regF dst, regDPR src, eFlagsReg cr) %{
predicate(UseSSE==1);
match(Set dst (ConvD2F src));
effect( KILL cr );
format %{ "SUB ESP,4\n\t"
"FST_S [ESP],$src\t# F-round\n\t"
*** 11449,11486 ****
--- 11077,11114 ----
%}
ins_pipe( pipe_slow );
%}
// Force rounding double precision to single precision
! instruct convXD2X_reg(regX dst, regXD src) %{
! instruct convD2F_reg(regF dst, regD 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) %{
! instruct convFPR2DPR_reg_reg(regDPR dst, regFPR src) %{
predicate(UseSSE==0);
match(Set dst (ConvF2D src));
format %{ "FST_S $dst,$src\t# D-round" %}
! ins_encode( Pop_Reg_Reg_DPR(dst, src));
ins_pipe( fpu_reg_reg );
%}
! instruct convF2D_reg(stackSlotD dst, regF src) %{
! instruct convFPR2D_reg(stackSlotD dst, regFPR src) %{
predicate(UseSSE==1);
match(Set dst (ConvF2D src));
format %{ "FST_D $dst,$src\t# D-round" %}
expand %{
roundDouble_mem_reg(dst,src);
%}
%}
! instruct convX2D_reg(regD dst, regX src, eFlagsReg cr) %{
! instruct convF2DPR_reg(regDPR dst, regF src, eFlagsReg cr) %{
predicate(UseSSE==1);
match(Set dst (ConvF2D src));
effect( KILL cr );
format %{ "SUB ESP,4\n\t"
"MOVSS [ESP] $src\n\t"
*** 11495,11505 ****
--- 11123,11133 ----
__ fstp_d($dst$$reg);
%}
ins_pipe( pipe_slow );
%}
! instruct convX2XD_reg(regXD dst, regX src) %{
! instruct convF2D_reg(regD dst, regF src) %{
predicate(UseSSE>=2);
match(Set dst (ConvF2D src));
format %{ "CVTSS2SD $dst,$src\t# D-round" %}
ins_encode %{
__ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister);
*** 11506,11516 ****
--- 11134,11144 ----
%}
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 ) %{
! instruct convDPR2I_reg_reg( eAXRegI dst, eDXRegI tmp, regDPR src, eFlagsReg cr ) %{
predicate(UseSSE<=1);
match(Set dst (ConvD2I src));
effect( KILL tmp, KILL cr );
format %{ "FLD $src\t# Convert double to int \n\t"
"FLDCW trunc mode\n\t"
*** 11521,11536 ****
--- 11149,11164 ----
"CMP EAX,0x80000000\n\t"
"JNE,s fast\n\t"
"FLD_D $src\n\t"
"CALL d2i_wrapper\n"
"fast:" %}
! ins_encode( Push_Reg_D(src), D2I_encoding(src) );
! ins_encode( Push_Reg_DPR(src), DPR2I_encoding(src) );
ins_pipe( pipe_slow );
%}
// Convert a double to an int. If the double is a NAN, stuff a zero in instead.
! instruct convXD2I_reg_reg( eAXRegI dst, eDXRegI tmp, regXD src, eFlagsReg cr ) %{
! instruct convD2I_reg_reg( eAXRegI dst, eDXRegI tmp, regD src, eFlagsReg cr ) %{
predicate(UseSSE>=2);
match(Set dst (ConvD2I src));
effect( KILL tmp, KILL cr );
format %{ "CVTTSD2SI $dst, $src\n\t"
"CMP $dst,0x80000000\n\t"
*** 11554,11564 ****
--- 11182,11192 ----
__ bind(fast);
%}
ins_pipe( pipe_slow );
%}
! instruct convD2L_reg_reg( eADXRegL dst, regD src, eFlagsReg cr ) %{
! instruct convDPR2L_reg_reg( eADXRegL dst, regDPR src, eFlagsReg cr ) %{
predicate(UseSSE<=1);
match(Set dst (ConvD2L src));
effect( KILL cr );
format %{ "FLD $src\t# Convert double to long\n\t"
"FLDCW trunc mode\n\t"
*** 11572,11587 ****
--- 11200,11215 ----
"TEST EAX,EAX\n\t"
"JNE,s fast\n\t"
"FLD $src\n\t"
"CALL d2l_wrapper\n"
"fast:" %}
! ins_encode( Push_Reg_D(src), D2L_encoding(src) );
! ins_encode( Push_Reg_DPR(src), DPR2L_encoding(src) );
ins_pipe( pipe_slow );
%}
// XMM lacks a float/double->long conversion, so use the old FPU stack.
! instruct convXD2L_reg_reg( eADXRegL dst, regXD src, eFlagsReg cr ) %{
! instruct convD2L_reg_reg( eADXRegL dst, regD src, eFlagsReg cr ) %{
predicate (UseSSE>=2);
match(Set dst (ConvD2L src));
effect( KILL cr );
format %{ "SUB ESP,8\t# Convert double to long\n\t"
"MOVSD [ESP],$src\n\t"
*** 11635,11645 ****
--- 11263,11273 ----
// manglations in the corner cases. So we set the rounding mode to
// 'zero', store the darned double down as an int, and reset the
// rounding mode to 'nearest'. The hardware stores a flag value down
// if we would overflow or converted a NAN; we check for this and
// and go the slow path if needed.
! instruct convF2I_reg_reg(eAXRegI dst, eDXRegI tmp, regF src, eFlagsReg cr ) %{
! instruct convFPR2I_reg_reg(eAXRegI dst, eDXRegI tmp, regFPR src, eFlagsReg cr ) %{
predicate(UseSSE==0);
match(Set dst (ConvF2I src));
effect( KILL tmp, KILL cr );
format %{ "FLD $src\t# Convert float to int \n\t"
"FLDCW trunc mode\n\t"
*** 11650,11666 ****
--- 11278,11294 ----
"CMP EAX,0x80000000\n\t"
"JNE,s fast\n\t"
"FLD $src\n\t"
"CALL d2i_wrapper\n"
"fast:" %}
! // D2I_encoding works for F2I
! ins_encode( Push_Reg_F(src), D2I_encoding(src) );
! // DPR2I_encoding works for FPR2I
! ins_encode( Push_Reg_FPR(src), DPR2I_encoding(src) );
ins_pipe( pipe_slow );
%}
// Convert a float in xmm to an int reg.
! instruct convX2I_reg(eAXRegI dst, eDXRegI tmp, regX src, eFlagsReg cr ) %{
! instruct convF2I_reg(eAXRegI dst, eDXRegI tmp, regF src, eFlagsReg cr ) %{
predicate(UseSSE>=1);
match(Set dst (ConvF2I src));
effect( KILL tmp, KILL cr );
format %{ "CVTTSS2SI $dst, $src\n\t"
"CMP $dst,0x80000000\n\t"
*** 11684,11694 ****
--- 11312,11322 ----
__ bind(fast);
%}
ins_pipe( pipe_slow );
%}
! instruct convF2L_reg_reg( eADXRegL dst, regF src, eFlagsReg cr ) %{
! instruct convFPR2L_reg_reg( eADXRegL dst, regFPR src, eFlagsReg cr ) %{
predicate(UseSSE==0);
match(Set dst (ConvF2L src));
effect( KILL cr );
format %{ "FLD $src\t# Convert float to long\n\t"
"FLDCW trunc mode\n\t"
*** 11702,11718 ****
--- 11330,11346 ----
"TEST EAX,EAX\n\t"
"JNE,s fast\n\t"
"FLD $src\n\t"
"CALL d2l_wrapper\n"
"fast:" %}
! // D2L_encoding works for F2L
! ins_encode( Push_Reg_F(src), D2L_encoding(src) );
! // DPR2L_encoding works for FPR2L
! ins_encode( Push_Reg_FPR(src), DPR2L_encoding(src) );
ins_pipe( pipe_slow );
%}
// XMM lacks a float/double->long conversion, so use the old FPU stack.
! instruct convX2L_reg_reg( eADXRegL dst, regX src, eFlagsReg cr ) %{
! instruct convF2L_reg_reg( eADXRegL dst, regF src, eFlagsReg cr ) %{
predicate (UseSSE>=1);
match(Set dst (ConvF2L src));
effect( KILL cr );
format %{ "SUB ESP,8\t# Convert float to long\n\t"
"MOVSS [ESP],$src\n\t"
*** 11760,11800 ****
--- 11388,11428 ----
__ bind(fast);
%}
ins_pipe( pipe_slow );
%}
! instruct convI2D_reg(regD dst, stackSlotI src) %{
! instruct convI2DPR_reg(regDPR dst, stackSlotI src) %{
predicate( UseSSE<=1 );
match(Set dst (ConvI2D src));
format %{ "FILD $src\n\t"
"FSTP $dst" %}
opcode(0xDB, 0x0); /* DB /0 */
! ins_encode(Push_Mem_I(src), Pop_Reg_DPR(dst));
ins_pipe( fpu_reg_mem );
%}
! instruct convI2XD_reg(regXD dst, eRegI src) %{
! instruct convI2D_reg(regD 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) %{
! instruct convI2D_mem(regD 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)
! instruct convXI2D_reg(regD dst, eRegI src)
%{
predicate( UseSSE>=2 && UseXmmI2D );
match(Set dst (ConvI2D src));
format %{ "MOVD $dst,$src\n\t"
*** 11804,11898 ****
--- 11432,11526 ----
__ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister);
%}
ins_pipe(pipe_slow); // XXX
%}
! instruct convI2D_mem(regD dst, memory mem) %{
! instruct convI2DPR_mem(regDPR dst, memory mem) %{
predicate( UseSSE<=1 && !Compile::current()->select_24_bit_instr());
match(Set dst (ConvI2D (LoadI mem)));
format %{ "FILD $mem\n\t"
"FSTP $dst" %}
opcode(0xDB); /* DB /0 */
ins_encode( OpcP, RMopc_Mem(0x00,mem),
! Pop_Reg_DPR(dst));
ins_pipe( fpu_reg_mem );
%}
// Convert a byte to a float; no rounding step needed.
! instruct conv24I2F_reg(regF dst, stackSlotI src) %{
! instruct conv24I2FPR_reg(regFPR dst, stackSlotI src) %{
predicate( UseSSE==0 && n->in(1)->Opcode() == Op_AndI && n->in(1)->in(2)->is_Con() && n->in(1)->in(2)->get_int() == 255 );
match(Set dst (ConvI2F src));
format %{ "FILD $src\n\t"
"FSTP $dst" %}
opcode(0xDB, 0x0); /* DB /0 */
! ins_encode(Push_Mem_I(src), Pop_Reg_FPR(dst));
ins_pipe( fpu_reg_mem );
%}
// In 24-bit mode, force exponent rounding by storing back out
! instruct convI2F_SSF(stackSlotF dst, stackSlotI src) %{
! instruct convI2FPR_SSF(stackSlotF dst, stackSlotI src) %{
predicate( UseSSE==0 && Compile::current()->select_24_bit_instr());
match(Set dst (ConvI2F src));
ins_cost(200);
format %{ "FILD $src\n\t"
"FSTP_S $dst" %}
opcode(0xDB, 0x0); /* DB /0 */
ins_encode( Push_Mem_I(src),
! Pop_Mem_FPR(dst));
ins_pipe( fpu_mem_mem );
%}
// In 24-bit mode, force exponent rounding by storing back out
! instruct convI2F_SSF_mem(stackSlotF dst, memory mem) %{
! instruct convI2FPR_SSF_mem(stackSlotF dst, memory mem) %{
predicate( UseSSE==0 && Compile::current()->select_24_bit_instr());
match(Set dst (ConvI2F (LoadI mem)));
ins_cost(200);
format %{ "FILD $mem\n\t"
"FSTP_S $dst" %}
opcode(0xDB); /* DB /0 */
ins_encode( OpcP, RMopc_Mem(0x00,mem),
! Pop_Mem_FPR(dst));
ins_pipe( fpu_mem_mem );
%}
// This instruction does not round to 24-bits
! instruct convI2F_reg(regF dst, stackSlotI src) %{
! instruct convI2FPR_reg(regFPR dst, stackSlotI src) %{
predicate( UseSSE==0 && !Compile::current()->select_24_bit_instr());
match(Set dst (ConvI2F src));
format %{ "FILD $src\n\t"
"FSTP $dst" %}
opcode(0xDB, 0x0); /* DB /0 */
ins_encode( Push_Mem_I(src),
! Pop_Reg_FPR(dst));
ins_pipe( fpu_reg_mem );
%}
// This instruction does not round to 24-bits
! instruct convI2F_mem(regF dst, memory mem) %{
! instruct convI2FPR_mem(regFPR dst, memory mem) %{
predicate( UseSSE==0 && !Compile::current()->select_24_bit_instr());
match(Set dst (ConvI2F (LoadI mem)));
format %{ "FILD $mem\n\t"
"FSTP $dst" %}
opcode(0xDB); /* DB /0 */
ins_encode( OpcP, RMopc_Mem(0x00,mem),
! Pop_Reg_FPR(dst));
ins_pipe( fpu_reg_mem );
%}
// Convert an int to a float in xmm; no rounding step needed.
! instruct convI2X_reg(regX dst, eRegI src) %{
! instruct convI2F_reg(regF 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)
! instruct convXI2F_reg(regF dst, eRegI src)
%{
predicate( UseSSE>=2 && UseXmmI2F );
match(Set dst (ConvI2F src));
format %{ "MOVD $dst,$src\n\t"
*** 11937,11961 ****
--- 11565,11589 ----
opcode(0x33); // XOR
ins_encode(enc_Copy(dst,src), OpcP, RegReg_Hi2(dst,dst) );
ins_pipe( ialu_reg_reg_long );
%}
! instruct convL2D_reg( stackSlotD dst, eRegL src, eFlagsReg cr) %{
! instruct convL2DPR_reg( stackSlotD dst, eRegL src, eFlagsReg cr) %{
predicate (UseSSE<=1);
match(Set dst (ConvL2D src));
effect( KILL cr );
format %{ "PUSH $src.hi\t# Convert long to double\n\t"
"PUSH $src.lo\n\t"
"FILD ST,[ESP + #0]\n\t"
"ADD ESP,8\n\t"
"FSTP_D $dst\t# D-round" %}
opcode(0xDF, 0x5); /* DF /5 */
! ins_encode(convert_long_double(src), Pop_Mem_DPR(dst));
ins_pipe( pipe_slow );
%}
! instruct convL2XD_reg( regXD dst, eRegL src, eFlagsReg cr) %{
! instruct convL2D_reg( regD dst, eRegL src, eFlagsReg cr) %{
predicate (UseSSE>=2);
match(Set dst (ConvL2D src));
effect( KILL cr );
format %{ "PUSH $src.hi\t# Convert long to double\n\t"
"PUSH $src.lo\n\t"
*** 11962,11976 ****
--- 11590,11604 ----
"FILD_D [ESP]\n\t"
"FSTP_D [ESP]\n\t"
"MOVSD $dst,[ESP]\n\t"
"ADD ESP,8" %}
opcode(0xDF, 0x5); /* DF /5 */
! ins_encode(convert_long_double2(src), Push_ResultXD(dst));
! ins_encode(convert_long_double2(src), Push_ResultD(dst));
ins_pipe( pipe_slow );
%}
! instruct convL2X_reg( regX dst, eRegL src, eFlagsReg cr) %{
! instruct convL2F_reg( regF dst, eRegL src, eFlagsReg cr) %{
predicate (UseSSE>=1);
match(Set dst (ConvL2F src));
effect( KILL cr );
format %{ "PUSH $src.hi\t# Convert long to single float\n\t"
"PUSH $src.lo\n\t"
*** 11977,12000 ****
--- 11605,11628 ----
"FILD_D [ESP]\n\t"
"FSTP_S [ESP]\n\t"
"MOVSS $dst,[ESP]\n\t"
"ADD ESP,8" %}
opcode(0xDF, 0x5); /* DF /5 */
! ins_encode(convert_long_double2(src), Push_ResultX(dst,0x8));
! ins_encode(convert_long_double2(src), Push_ResultF(dst,0x8));
ins_pipe( pipe_slow );
%}
! instruct convL2F_reg( stackSlotF dst, eRegL src, eFlagsReg cr) %{
! instruct convL2FPR_reg( stackSlotF dst, eRegL src, eFlagsReg cr) %{
match(Set dst (ConvL2F src));
effect( KILL cr );
format %{ "PUSH $src.hi\t# Convert long to single float\n\t"
"PUSH $src.lo\n\t"
"FILD ST,[ESP + #0]\n\t"
"ADD ESP,8\n\t"
"FSTP_S $dst\t# F-round" %}
opcode(0xDF, 0x5); /* DF /5 */
! ins_encode(convert_long_double(src), Pop_Mem_FPR(dst));
ins_pipe( pipe_slow );
%}
instruct convL2I_reg( eRegI dst, eRegL src ) %{
match(Set dst (ConvL2I src));
*** 12014,12035 ****
--- 11642,11663 ----
__ movl($dst$$Register, Address(rsp, $src$$disp));
%}
ins_pipe( ialu_reg_mem );
%}
! instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{
! instruct MoveFPR2I_reg_stack(stackSlotI dst, regFPR src) %{
predicate(UseSSE==0);
match(Set dst (MoveF2I src));
effect( DEF dst, USE src );
ins_cost(125);
format %{ "FST_S $dst,$src\t# MoveF2I_reg_stack" %}
! ins_encode( Pop_Mem_Reg_FPR(dst, src) );
ins_pipe( fpu_mem_reg );
%}
! instruct MoveF2I_reg_stack_sse(stackSlotI dst, regX src) %{
! instruct MoveF2I_reg_stack_sse(stackSlotI dst, regF src) %{
predicate(UseSSE>=1);
match(Set dst (MoveF2I src));
effect( DEF dst, USE src );
ins_cost(95);
*** 12038,12048 ****
--- 11666,11676 ----
__ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister);
%}
ins_pipe( pipe_slow );
%}
! instruct MoveF2I_reg_reg_sse(eRegI dst, regX src) %{
! instruct MoveF2I_reg_reg_sse(eRegI dst, regF 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" %}
*** 12063,12087 ****
--- 11691,11715 ----
%}
ins_pipe( ialu_mem_reg );
%}
! instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{
! instruct MoveI2FPR_stack_reg(regFPR dst, stackSlotI src) %{
predicate(UseSSE==0);
match(Set dst (MoveI2F src));
effect(DEF dst, USE src);
ins_cost(125);
format %{ "FLD_S $src\n\t"
"FSTP $dst\t# MoveI2F_stack_reg" %}
opcode(0xD9); /* D9 /0, FLD m32real */
ins_encode( OpcP, RMopc_Mem_no_oop(0x00,src),
! Pop_Reg_FPR(dst) );
ins_pipe( fpu_reg_mem );
%}
! instruct MoveI2F_stack_reg_sse(regX dst, stackSlotI src) %{
! instruct MoveI2F_stack_reg_sse(regF dst, stackSlotI src) %{
predicate(UseSSE>=1);
match(Set dst (MoveI2F src));
effect( DEF dst, USE src );
ins_cost(95);
*** 12090,12100 ****
--- 11718,11728 ----
__ movflt($dst$$XMMRegister, Address(rsp, $src$$disp));
%}
ins_pipe( pipe_slow );
%}
! instruct MoveI2F_reg_reg_sse(regX dst, eRegI src) %{
! instruct MoveI2F_reg_reg_sse(regF dst, eRegI src) %{
predicate(UseSSE>=2);
match(Set dst (MoveI2F src));
effect( DEF dst, USE src );
ins_cost(85);
*** 12115,12136 ****
--- 11743,11764 ----
opcode(0x8B, 0x8B);
ins_encode( OpcP, RegMem(dst,src), OpcS, RegMem_Hi(dst,src));
ins_pipe( ialu_mem_long_reg );
%}
! instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{
! instruct MoveDPR2L_reg_stack(stackSlotL dst, regDPR src) %{
predicate(UseSSE<=1);
match(Set dst (MoveD2L src));
effect(DEF dst, USE src);
ins_cost(125);
format %{ "FST_D $dst,$src\t# MoveD2L_reg_stack" %}
! ins_encode( Pop_Mem_Reg_DPR(dst, src) );
ins_pipe( fpu_mem_reg );
%}
! instruct MoveD2L_reg_stack_sse(stackSlotL dst, regXD src) %{
! instruct MoveD2L_reg_stack_sse(stackSlotL dst, regD 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" %}
*** 12138,12148 ****
--- 11766,11776 ----
__ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister);
%}
ins_pipe( pipe_slow );
%}
! instruct MoveD2L_reg_reg_sse(eRegL dst, regXD src, regXD tmp) %{
! instruct MoveD2L_reg_reg_sse(eRegL dst, regD src, regD tmp) %{
predicate(UseSSE>=2);
match(Set dst (MoveD2L src));
effect(DEF dst, USE src, TEMP tmp);
ins_cost(85);
format %{ "MOVD $dst.lo,$src\n\t"
*** 12167,12192 ****
--- 11795,11820 ----
ins_encode( OpcP, RegMem( src, dst ), OpcS, RegMem_Hi( src, dst ) );
ins_pipe( ialu_mem_long_reg );
%}
! instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{
! instruct MoveL2DPR_stack_reg(regDPR dst, stackSlotL src) %{
predicate(UseSSE<=1);
match(Set dst (MoveL2D src));
effect(DEF dst, USE src);
ins_cost(125);
format %{ "FLD_D $src\n\t"
"FSTP $dst\t# MoveL2D_stack_reg" %}
opcode(0xDD); /* DD /0, FLD m64real */
ins_encode( OpcP, RMopc_Mem_no_oop(0x00,src),
! Pop_Reg_DPR(dst) );
ins_pipe( fpu_reg_mem );
%}
! instruct MoveL2D_stack_reg_sse(regXD dst, stackSlotL src) %{
! instruct MoveL2D_stack_reg_sse(regD dst, stackSlotL src) %{
predicate(UseSSE>=2 && UseXmmLoadAndClearUpper);
match(Set dst (MoveL2D src));
effect(DEF dst, USE src);
ins_cost(95);
*** 12195,12205 ****
--- 11823,11833 ----
__ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp));
%}
ins_pipe( pipe_slow );
%}
! instruct MoveL2D_stack_reg_sse_partial(regXD dst, stackSlotL src) %{
! instruct MoveL2D_stack_reg_sse_partial(regD dst, stackSlotL src) %{
predicate(UseSSE>=2 && !UseXmmLoadAndClearUpper);
match(Set dst (MoveL2D src));
effect(DEF dst, USE src);
ins_cost(95);
*** 12208,12218 ****
--- 11836,11846 ----
__ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp));
%}
ins_pipe( pipe_slow );
%}
! instruct MoveL2D_reg_reg_sse(regXD dst, eRegL src, regXD tmp) %{
! instruct MoveL2D_reg_reg_sse(regD dst, eRegL src, regD tmp) %{
predicate(UseSSE>=2);
match(Set dst (MoveL2D src));
effect(TEMP dst, USE src, TEMP tmp);
ins_cost(85);
format %{ "MOVD $dst,$src.lo\n\t"
*** 12225,12235 ****
--- 11853,11863 ----
%}
ins_pipe( pipe_slow );
%}
// Replicate scalar to packed byte (1 byte) values in xmm
! instruct Repl8B_reg(regXD dst, regXD src) %{
! instruct Repl8B_reg(regD dst, regD src) %{
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" %}
*** 12242,12252 ****
--- 11870,11880 ----
%}
ins_pipe( pipe_slow );
%}
// Replicate scalar to packed byte (1 byte) values in xmm
! instruct Repl8B_eRegI(regXD dst, eRegI src) %{
! instruct Repl8B_eRegI(regD dst, eRegI src) %{
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" %}
*** 12257,12267 ****
--- 11885,11895 ----
%}
ins_pipe( pipe_slow );
%}
// Replicate scalar zero to packed byte (1 byte) values in xmm
! instruct Repl8B_immI0(regXD dst, immI0 zero) %{
! instruct Repl8B_immI0(regD dst, immI0 zero) %{
predicate(UseSSE>=2);
match(Set dst (Replicate8B zero));
format %{ "PXOR $dst,$dst\t! replicate8B" %}
ins_encode %{
__ pxor($dst$$XMMRegister, $dst$$XMMRegister);
*** 12268,12278 ****
--- 11896,11906 ----
%}
ins_pipe( fpu_reg_reg );
%}
// Replicate scalar to packed shore (2 byte) values in xmm
! instruct Repl4S_reg(regXD dst, regXD src) %{
! instruct Repl4S_reg(regD dst, regD src) %{
predicate(UseSSE>=2);
match(Set dst (Replicate4S src));
format %{ "PSHUFLW $dst,$src,0x00\t! replicate4S" %}
ins_encode %{
__ pshuflw($dst$$XMMRegister, $src$$XMMRegister, 0x00);
*** 12279,12289 ****
--- 11907,11917 ----
%}
ins_pipe( fpu_reg_reg );
%}
// Replicate scalar to packed shore (2 byte) values in xmm
! instruct Repl4S_eRegI(regXD dst, eRegI src) %{
! instruct Repl4S_eRegI(regD 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 %{
*** 12292,12302 ****
--- 11920,11930 ----
%}
ins_pipe( fpu_reg_reg );
%}
// Replicate scalar zero to packed short (2 byte) values in xmm
! instruct Repl4S_immI0(regXD dst, immI0 zero) %{
! instruct Repl4S_immI0(regD dst, immI0 zero) %{
predicate(UseSSE>=2);
match(Set dst (Replicate4S zero));
format %{ "PXOR $dst,$dst\t! replicate4S" %}
ins_encode %{
__ pxor($dst$$XMMRegister, $dst$$XMMRegister);
*** 12303,12313 ****
--- 11931,11941 ----
%}
ins_pipe( fpu_reg_reg );
%}
// Replicate scalar to packed char (2 byte) values in xmm
! instruct Repl4C_reg(regXD dst, regXD src) %{
! instruct Repl4C_reg(regD dst, regD src) %{
predicate(UseSSE>=2);
match(Set dst (Replicate4C src));
format %{ "PSHUFLW $dst,$src,0x00\t! replicate4C" %}
ins_encode %{
__ pshuflw($dst$$XMMRegister, $src$$XMMRegister, 0x00);
*** 12314,12324 ****
--- 11942,11952 ----
%}
ins_pipe( fpu_reg_reg );
%}
// Replicate scalar to packed char (2 byte) values in xmm
! instruct Repl4C_eRegI(regXD dst, eRegI src) %{
! instruct Repl4C_eRegI(regD 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 %{
*** 12327,12337 ****
--- 11955,11965 ----
%}
ins_pipe( fpu_reg_reg );
%}
// Replicate scalar zero to packed char (2 byte) values in xmm
! instruct Repl4C_immI0(regXD dst, immI0 zero) %{
! instruct Repl4C_immI0(regD dst, immI0 zero) %{
predicate(UseSSE>=2);
match(Set dst (Replicate4C zero));
format %{ "PXOR $dst,$dst\t! replicate4C" %}
ins_encode %{
__ pxor($dst$$XMMRegister, $dst$$XMMRegister);
*** 12338,12348 ****
--- 11966,11976 ----
%}
ins_pipe( fpu_reg_reg );
%}
// Replicate scalar to packed integer (4 byte) values in xmm
! instruct Repl2I_reg(regXD dst, regXD src) %{
! instruct Repl2I_reg(regD dst, regD src) %{
predicate(UseSSE>=2);
match(Set dst (Replicate2I src));
format %{ "PSHUFD $dst,$src,0x00\t! replicate2I" %}
ins_encode %{
__ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0x00);
*** 12349,12359 ****
--- 11977,11987 ----
%}
ins_pipe( fpu_reg_reg );
%}
// Replicate scalar to packed integer (4 byte) values in xmm
! instruct Repl2I_eRegI(regXD dst, eRegI src) %{
! instruct Repl2I_eRegI(regD 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 %{
*** 12362,12372 ****
--- 11990,12000 ----
%}
ins_pipe( fpu_reg_reg );
%}
// Replicate scalar zero to packed integer (2 byte) values in xmm
! instruct Repl2I_immI0(regXD dst, immI0 zero) %{
! instruct Repl2I_immI0(regD dst, immI0 zero) %{
predicate(UseSSE>=2);
match(Set dst (Replicate2I zero));
format %{ "PXOR $dst,$dst\t! replicate2I" %}
ins_encode %{
__ pxor($dst$$XMMRegister, $dst$$XMMRegister);
*** 12373,12383 ****
--- 12001,12011 ----
%}
ins_pipe( fpu_reg_reg );
%}
// Replicate scalar to packed single precision floating point values in xmm
! instruct Repl2F_reg(regXD dst, regXD src) %{
! instruct Repl2F_reg(regD dst, regD src) %{
predicate(UseSSE>=2);
match(Set dst (Replicate2F src));
format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %}
ins_encode %{
__ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0xe0);
*** 12384,12394 ****
--- 12012,12022 ----
%}
ins_pipe( fpu_reg_reg );
%}
// Replicate scalar to packed single precision floating point values in xmm
! instruct Repl2F_regX(regXD dst, regX src) %{
! instruct Repl2F_regF(regD dst, regF src) %{
predicate(UseSSE>=2);
match(Set dst (Replicate2F src));
format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %}
ins_encode %{
__ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0xe0);
*** 12395,12405 ****
--- 12023,12033 ----
%}
ins_pipe( fpu_reg_reg );
%}
// Replicate scalar to packed single precision floating point values in xmm
! instruct Repl2F_immXF0(regXD dst, immXF0 zero) %{
! instruct Repl2F_immF0(regD dst, immF0 zero) %{
predicate(UseSSE>=2);
match(Set dst (Replicate2F zero));
format %{ "PXOR $dst,$dst\t! replicate2F" %}
ins_encode %{
__ pxor($dst$$XMMRegister, $dst$$XMMRegister);
*** 12421,12431 ****
--- 12049,12059 ----
Opcode(0xF3), Opcode(0xAB) );
ins_pipe( pipe_slow );
%}
instruct string_compare(eDIRegP str1, eCXRegI cnt1, eSIRegP str2, eDXRegI cnt2,
! eAXRegI result, regXD tmp1, eFlagsReg cr) %{
! eAXRegI result, regD tmp1, eFlagsReg cr) %{
match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %}
ins_encode %{
*** 12436,12446 ****
--- 12064,12074 ----
ins_pipe( pipe_slow );
%}
// fast string equals
instruct string_equals(eDIRegP str1, eSIRegP str2, eCXRegI cnt, eAXRegI result,
! regXD tmp1, regXD tmp2, eBXRegI tmp3, eFlagsReg cr) %{
! regD tmp1, regD tmp2, eBXRegI tmp3, eFlagsReg cr) %{
match(Set result (StrEquals (Binary str1 str2) cnt));
effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr);
format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %}
ins_encode %{
*** 12451,12461 ****
--- 12079,12089 ----
ins_pipe( pipe_slow );
%}
// fast search of substring with known size.
instruct string_indexof_con(eDIRegP str1, eDXRegI cnt1, eSIRegP str2, immI int_cnt2,
! eBXRegI result, regXD vec, eAXRegI cnt2, eCXRegI tmp, eFlagsReg cr) %{
! eBXRegI result, regD vec, eAXRegI cnt2, eCXRegI tmp, eFlagsReg cr) %{
predicate(UseSSE42Intrinsics);
match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr);
format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %}
*** 12478,12488 ****
--- 12106,12116 ----
%}
ins_pipe( pipe_slow );
%}
instruct string_indexof(eDIRegP str1, eDXRegI cnt1, eSIRegP str2, eAXRegI cnt2,
! eBXRegI result, regXD vec, eCXRegI tmp, eFlagsReg cr) %{
! eBXRegI result, regD vec, eCXRegI tmp, eFlagsReg cr) %{
predicate(UseSSE42Intrinsics);
match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr);
format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %}
*** 12495,12505 ****
--- 12123,12133 ----
ins_pipe( pipe_slow );
%}
// fast array equals
instruct array_equals(eDIRegP ary1, eSIRegP ary2, eAXRegI result,
! regXD tmp1, regXD tmp2, eCXRegI tmp3, eBXRegI tmp4, eFlagsReg cr)
! regD tmp1, regD tmp2, eCXRegI tmp3, eBXRegI tmp4, eFlagsReg cr)
%{
match(Set result (AryEq ary1 ary2));
effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr);
//ins_cost(300);
*** 13321,13364 ****
--- 12949,12992 ----
ins_encode( enc_cmov(cmp), RegReg( dst, src ) );
ins_pipe( pipe_cmov_reg );
%}
// Compare 2 longs and CMOVE doubles
! instruct cmovDD_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, regD dst, regD src) %{
! instruct cmovDDPR_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, regDPR dst, regDPR src) %{
predicate( UseSSE<=1 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
match(Set dst (CMoveD (Binary cmp flags) (Binary dst src)));
ins_cost(200);
expand %{
! fcmovD_regS(cmp,flags,dst,src);
! fcmovDPR_regS(cmp,flags,dst,src);
%}
%}
// Compare 2 longs and CMOVE doubles
! instruct cmovXDD_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, regXD dst, regXD src) %{
! instruct cmovDD_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, regD dst, regD src) %{
predicate( UseSSE>=2 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
match(Set dst (CMoveD (Binary cmp flags) (Binary dst src)));
ins_cost(200);
expand %{
! fcmovXD_regS(cmp,flags,dst,src);
! fcmovD_regS(cmp,flags,dst,src);
%}
%}
! instruct cmovFF_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, regF dst, regF src) %{
! instruct cmovFFPR_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, regFPR dst, regFPR src) %{
predicate( UseSSE==0 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
match(Set dst (CMoveF (Binary cmp flags) (Binary dst src)));
ins_cost(200);
expand %{
! fcmovF_regS(cmp,flags,dst,src);
! fcmovFPR_regS(cmp,flags,dst,src);
%}
%}
! instruct cmovXX_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, regX dst, regX src) %{
! instruct cmovFF_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, regF dst, regF src) %{
predicate( UseSSE>=1 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
match(Set dst (CMoveF (Binary cmp flags) (Binary dst src)));
ins_cost(200);
expand %{
! fcmovX_regS(cmp,flags,dst,src);
! fcmovF_regS(cmp,flags,dst,src);
%}
%}
//======
// Manifest a CmpL result in the normal flags. Only good for EQ/NE compares.
*** 13449,13492 ****
--- 13077,13120 ----
ins_encode( enc_cmov(cmp), RegReg( dst, src ) );
ins_pipe( pipe_cmov_reg );
%}
// Compare 2 longs and CMOVE doubles
! instruct cmovDD_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, regD dst, regD src) %{
! instruct cmovDDPR_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, regDPR dst, regDPR src) %{
predicate( UseSSE<=1 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
match(Set dst (CMoveD (Binary cmp flags) (Binary dst src)));
ins_cost(200);
expand %{
! fcmovD_regS(cmp,flags,dst,src);
! fcmovDPR_regS(cmp,flags,dst,src);
%}
%}
// Compare 2 longs and CMOVE doubles
! instruct cmovXDD_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, regXD dst, regXD src) %{
! instruct cmovDD_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, regD dst, regD src) %{
predicate( UseSSE>=2 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
match(Set dst (CMoveD (Binary cmp flags) (Binary dst src)));
ins_cost(200);
expand %{
! fcmovXD_regS(cmp,flags,dst,src);
! fcmovD_regS(cmp,flags,dst,src);
%}
%}
! instruct cmovFF_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, regF dst, regF src) %{
! instruct cmovFFPR_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, regFPR dst, regFPR src) %{
predicate( UseSSE==0 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
match(Set dst (CMoveF (Binary cmp flags) (Binary dst src)));
ins_cost(200);
expand %{
! fcmovF_regS(cmp,flags,dst,src);
! fcmovFPR_regS(cmp,flags,dst,src);
%}
%}
! instruct cmovXX_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, regX dst, regX src) %{
! instruct cmovFF_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, regF dst, regF src) %{
predicate( UseSSE>=1 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
match(Set dst (CMoveF (Binary cmp flags) (Binary dst src)));
ins_cost(200);
expand %{
! fcmovX_regS(cmp,flags,dst,src);
! fcmovF_regS(cmp,flags,dst,src);
%}
%}
//======
// Manifest a CmpL result in the normal flags. Only good for LE or GT compares.
*** 13582,13626 ****
--- 13210,13254 ----
ins_encode( enc_cmov(cmp), RegReg( dst, src ) );
ins_pipe( pipe_cmov_reg );
%}
// Compare 2 longs and CMOVE doubles
! instruct cmovDD_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, regD dst, regD src) %{
! instruct cmovDDPR_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, regDPR dst, regDPR src) %{
predicate( UseSSE<=1 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
match(Set dst (CMoveD (Binary cmp flags) (Binary dst src)));
ins_cost(200);
expand %{
! fcmovD_regS(cmp,flags,dst,src);
! fcmovDPR_regS(cmp,flags,dst,src);
%}
%}
// Compare 2 longs and CMOVE doubles
! instruct cmovXDD_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, regXD dst, regXD src) %{
! instruct cmovDD_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, regD dst, regD src) %{
predicate( UseSSE>=2 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
match(Set dst (CMoveD (Binary cmp flags) (Binary dst src)));
ins_cost(200);
expand %{
! fcmovXD_regS(cmp,flags,dst,src);
! fcmovD_regS(cmp,flags,dst,src);
%}
%}
! instruct cmovFF_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, regF dst, regF src) %{
! instruct cmovFFPR_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, regFPR dst, regFPR src) %{
predicate( UseSSE==0 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
match(Set dst (CMoveF (Binary cmp flags) (Binary dst src)));
ins_cost(200);
expand %{
! fcmovF_regS(cmp,flags,dst,src);
! fcmovFPR_regS(cmp,flags,dst,src);
%}
%}
! instruct cmovXX_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, regX dst, regX src) %{
! instruct cmovFF_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, regF dst, regF src) %{
predicate( UseSSE>=1 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
match(Set dst (CMoveF (Binary cmp flags) (Binary dst src)));
ins_cost(200);
expand %{
! fcmovX_regS(cmp,flags,dst,src);
! fcmovF_regS(cmp,flags,dst,src);
%}
%}
// ============================================================================
src/cpu/x86/vm/x86_32.ad
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File