7121648: Use 3-operands SIMD instructions on x86 with AVX
Use 3-operands SIMD instructions in C2 generated code for machines with AVX. Reviewed-by: never
This commit is contained in:
parent
2928feab6a
commit
dc542c9909
@ -39,9 +39,16 @@ OS = $(Platform_os_family)
|
||||
|
||||
SOURCE.AD = $(OUTDIR)/$(OS)_$(Platform_arch_model).ad
|
||||
|
||||
SOURCES.AD = \
|
||||
ifeq ("${Platform_arch_model}", "${Platform_arch}")
|
||||
SOURCES.AD = \
|
||||
$(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch_model).ad) \
|
||||
$(call altsrc-replace,$(HS_COMMON_SRC)/os_cpu/$(OS)_$(ARCH)/vm/$(OS)_$(Platform_arch_model).ad)
|
||||
else
|
||||
SOURCES.AD = \
|
||||
$(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch_model).ad) \
|
||||
$(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch).ad) \
|
||||
$(call altsrc-replace,$(HS_COMMON_SRC)/os_cpu/$(OS)_$(ARCH)/vm/$(OS)_$(Platform_arch_model).ad)
|
||||
endif
|
||||
|
||||
EXEC = $(OUTDIR)/adlc
|
||||
|
||||
|
@ -39,9 +39,16 @@ OS = $(Platform_os_family)
|
||||
|
||||
SOURCE.AD = $(OUTDIR)/$(OS)_$(Platform_arch_model).ad
|
||||
|
||||
SOURCES.AD = \
|
||||
ifeq ("${Platform_arch_model}", "${Platform_arch}")
|
||||
SOURCES.AD = \
|
||||
$(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch_model).ad) \
|
||||
$(call altsrc-replace,$(HS_COMMON_SRC)/os_cpu/$(OS)_$(ARCH)/vm/$(OS)_$(Platform_arch_model).ad)
|
||||
else
|
||||
SOURCES.AD = \
|
||||
$(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch_model).ad) \
|
||||
$(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch).ad) \
|
||||
$(call altsrc-replace,$(HS_COMMON_SRC)/os_cpu/$(OS)_$(ARCH)/vm/$(OS)_$(Platform_arch_model).ad)
|
||||
endif
|
||||
|
||||
EXEC = $(OUTDIR)/adlc
|
||||
|
||||
|
@ -40,9 +40,16 @@ OS = $(Platform_os_family)
|
||||
|
||||
SOURCE.AD = $(OUTDIR)/$(OS)_$(Platform_arch_model).ad
|
||||
|
||||
SOURCES.AD = \
|
||||
ifeq ("${Platform_arch_model}", "${Platform_arch}")
|
||||
SOURCES.AD = \
|
||||
$(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch_model).ad) \
|
||||
$(call altsrc-replace,$(HS_COMMON_SRC)/os_cpu/$(OS)_$(ARCH)/vm/$(OS)_$(Platform_arch_model).ad)
|
||||
else
|
||||
SOURCES.AD = \
|
||||
$(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch_model).ad) \
|
||||
$(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch).ad) \
|
||||
$(call altsrc-replace,$(HS_COMMON_SRC)/os_cpu/$(OS)_$(ARCH)/vm/$(OS)_$(Platform_arch_model).ad)
|
||||
endif
|
||||
|
||||
EXEC = $(OUTDIR)/adlc
|
||||
|
||||
|
@ -53,6 +53,17 @@ CPP_INCLUDE_DIRS=\
|
||||
/I "$(WorkSpace)\src\os\windows\vm" \
|
||||
/I "$(WorkSpace)\src\cpu\$(Platform_arch)\vm"
|
||||
|
||||
!if "$(Platform_arch_model)" == "$(Platform_arch)"
|
||||
SOURCES_AD=\
|
||||
$(WorkSpace)/src/cpu/$(Platform_arch)/vm/$(Platform_arch_model).ad \
|
||||
$(WorkSpace)/src/os_cpu/windows_$(Platform_arch)/vm/windows_$(Platform_arch_model).ad
|
||||
!else
|
||||
SOURCES_AD=\
|
||||
$(WorkSpace)/src/cpu/$(Platform_arch)/vm/$(Platform_arch_model).ad \
|
||||
$(WorkSpace)/src/cpu/$(Platform_arch)/vm/$(Platform_arch).ad \
|
||||
$(WorkSpace)/src/os_cpu/windows_$(Platform_arch)/vm/windows_$(Platform_arch_model).ad
|
||||
!endif
|
||||
|
||||
# NOTE! If you add any files here, you must also update GENERATED_NAMES_IN_DIR
|
||||
# and ProjectCreatorIDEOptions in projectcreator.make.
|
||||
GENERATED_NAMES=\
|
||||
@ -105,7 +116,6 @@ $(GENERATED_NAMES_IN_DIR): $(Platform_arch_model).ad adlc.exe
|
||||
$(ADLC) $(ADLCFLAGS) $(Platform_arch_model).ad
|
||||
mv $(GENERATED_NAMES) $(AdlcOutDir)/
|
||||
|
||||
$(Platform_arch_model).ad: $(WorkSpace)/src/cpu/$(Platform_arch)/vm/$(Platform_arch_model).ad $(WorkSpace)/src/os_cpu/windows_$(Platform_arch)/vm/windows_$(Platform_arch_model).ad
|
||||
$(Platform_arch_model).ad: $(SOURCES_AD)
|
||||
rm -f $(Platform_arch_model).ad
|
||||
cat $(WorkSpace)/src/cpu/$(Platform_arch)/vm/$(Platform_arch_model).ad \
|
||||
$(WorkSpace)/src/os_cpu/windows_$(Platform_arch)/vm/windows_$(Platform_arch_model).ad >$(Platform_arch_model).ad
|
||||
cat $(SOURCES_AD) >$(Platform_arch_model).ad
|
||||
|
@ -2932,6 +2932,161 @@ void Assembler::xorps(XMMRegister dst, Address src) {
|
||||
emit_operand(dst, src);
|
||||
}
|
||||
|
||||
// AVX 3-operands non destructive source instructions (encoded with VEX prefix)
|
||||
|
||||
void Assembler::vaddsd(XMMRegister dst, XMMRegister nds, Address src) {
|
||||
assert(VM_Version::supports_avx(), "");
|
||||
InstructionMark im(this);
|
||||
vex_prefix(dst, nds, src, VEX_SIMD_F2);
|
||||
emit_byte(0x58);
|
||||
emit_operand(dst, src);
|
||||
}
|
||||
|
||||
void Assembler::vaddsd(XMMRegister dst, XMMRegister nds, XMMRegister src) {
|
||||
assert(VM_Version::supports_avx(), "");
|
||||
int encode = vex_prefix_and_encode(dst, nds, src, VEX_SIMD_F2);
|
||||
emit_byte(0x58);
|
||||
emit_byte(0xC0 | encode);
|
||||
}
|
||||
|
||||
void Assembler::vaddss(XMMRegister dst, XMMRegister nds, Address src) {
|
||||
assert(VM_Version::supports_avx(), "");
|
||||
InstructionMark im(this);
|
||||
vex_prefix(dst, nds, src, VEX_SIMD_F3);
|
||||
emit_byte(0x58);
|
||||
emit_operand(dst, src);
|
||||
}
|
||||
|
||||
void Assembler::vaddss(XMMRegister dst, XMMRegister nds, XMMRegister src) {
|
||||
assert(VM_Version::supports_avx(), "");
|
||||
int encode = vex_prefix_and_encode(dst, nds, src, VEX_SIMD_F3);
|
||||
emit_byte(0x58);
|
||||
emit_byte(0xC0 | encode);
|
||||
}
|
||||
|
||||
void Assembler::vandpd(XMMRegister dst, XMMRegister nds, Address src) {
|
||||
assert(VM_Version::supports_avx(), "");
|
||||
InstructionMark im(this);
|
||||
vex_prefix(dst, nds, src, VEX_SIMD_66); // 128-bit vector
|
||||
emit_byte(0x54);
|
||||
emit_operand(dst, src);
|
||||
}
|
||||
|
||||
void Assembler::vandps(XMMRegister dst, XMMRegister nds, Address src) {
|
||||
assert(VM_Version::supports_avx(), "");
|
||||
InstructionMark im(this);
|
||||
vex_prefix(dst, nds, src, VEX_SIMD_NONE); // 128-bit vector
|
||||
emit_byte(0x54);
|
||||
emit_operand(dst, src);
|
||||
}
|
||||
|
||||
void Assembler::vdivsd(XMMRegister dst, XMMRegister nds, Address src) {
|
||||
assert(VM_Version::supports_avx(), "");
|
||||
InstructionMark im(this);
|
||||
vex_prefix(dst, nds, src, VEX_SIMD_F2);
|
||||
emit_byte(0x5E);
|
||||
emit_operand(dst, src);
|
||||
}
|
||||
|
||||
void Assembler::vdivsd(XMMRegister dst, XMMRegister nds, XMMRegister src) {
|
||||
assert(VM_Version::supports_avx(), "");
|
||||
int encode = vex_prefix_and_encode(dst, nds, src, VEX_SIMD_F2);
|
||||
emit_byte(0x5E);
|
||||
emit_byte(0xC0 | encode);
|
||||
}
|
||||
|
||||
void Assembler::vdivss(XMMRegister dst, XMMRegister nds, Address src) {
|
||||
assert(VM_Version::supports_avx(), "");
|
||||
InstructionMark im(this);
|
||||
vex_prefix(dst, nds, src, VEX_SIMD_F3);
|
||||
emit_byte(0x5E);
|
||||
emit_operand(dst, src);
|
||||
}
|
||||
|
||||
void Assembler::vdivss(XMMRegister dst, XMMRegister nds, XMMRegister src) {
|
||||
assert(VM_Version::supports_avx(), "");
|
||||
int encode = vex_prefix_and_encode(dst, nds, src, VEX_SIMD_F3);
|
||||
emit_byte(0x5E);
|
||||
emit_byte(0xC0 | encode);
|
||||
}
|
||||
|
||||
void Assembler::vmulsd(XMMRegister dst, XMMRegister nds, Address src) {
|
||||
assert(VM_Version::supports_avx(), "");
|
||||
InstructionMark im(this);
|
||||
vex_prefix(dst, nds, src, VEX_SIMD_F2);
|
||||
emit_byte(0x59);
|
||||
emit_operand(dst, src);
|
||||
}
|
||||
|
||||
void Assembler::vmulsd(XMMRegister dst, XMMRegister nds, XMMRegister src) {
|
||||
assert(VM_Version::supports_avx(), "");
|
||||
int encode = vex_prefix_and_encode(dst, nds, src, VEX_SIMD_F2);
|
||||
emit_byte(0x59);
|
||||
emit_byte(0xC0 | encode);
|
||||
}
|
||||
|
||||
void Assembler::vmulss(XMMRegister dst, XMMRegister nds, Address src) {
|
||||
InstructionMark im(this);
|
||||
vex_prefix(dst, nds, src, VEX_SIMD_F3);
|
||||
emit_byte(0x59);
|
||||
emit_operand(dst, src);
|
||||
}
|
||||
|
||||
void Assembler::vmulss(XMMRegister dst, XMMRegister nds, XMMRegister src) {
|
||||
assert(VM_Version::supports_avx(), "");
|
||||
int encode = vex_prefix_and_encode(dst, nds, src, VEX_SIMD_F3);
|
||||
emit_byte(0x59);
|
||||
emit_byte(0xC0 | encode);
|
||||
}
|
||||
|
||||
|
||||
void Assembler::vsubsd(XMMRegister dst, XMMRegister nds, Address src) {
|
||||
assert(VM_Version::supports_avx(), "");
|
||||
InstructionMark im(this);
|
||||
vex_prefix(dst, nds, src, VEX_SIMD_F2);
|
||||
emit_byte(0x5C);
|
||||
emit_operand(dst, src);
|
||||
}
|
||||
|
||||
void Assembler::vsubsd(XMMRegister dst, XMMRegister nds, XMMRegister src) {
|
||||
assert(VM_Version::supports_avx(), "");
|
||||
int encode = vex_prefix_and_encode(dst, nds, src, VEX_SIMD_F2);
|
||||
emit_byte(0x5C);
|
||||
emit_byte(0xC0 | encode);
|
||||
}
|
||||
|
||||
void Assembler::vsubss(XMMRegister dst, XMMRegister nds, Address src) {
|
||||
assert(VM_Version::supports_avx(), "");
|
||||
InstructionMark im(this);
|
||||
vex_prefix(dst, nds, src, VEX_SIMD_F3);
|
||||
emit_byte(0x5C);
|
||||
emit_operand(dst, src);
|
||||
}
|
||||
|
||||
void Assembler::vsubss(XMMRegister dst, XMMRegister nds, XMMRegister src) {
|
||||
assert(VM_Version::supports_avx(), "");
|
||||
int encode = vex_prefix_and_encode(dst, nds, src, VEX_SIMD_F3);
|
||||
emit_byte(0x5C);
|
||||
emit_byte(0xC0 | encode);
|
||||
}
|
||||
|
||||
void Assembler::vxorpd(XMMRegister dst, XMMRegister nds, Address src) {
|
||||
assert(VM_Version::supports_avx(), "");
|
||||
InstructionMark im(this);
|
||||
vex_prefix(dst, nds, src, VEX_SIMD_66); // 128-bit vector
|
||||
emit_byte(0x57);
|
||||
emit_operand(dst, src);
|
||||
}
|
||||
|
||||
void Assembler::vxorps(XMMRegister dst, XMMRegister nds, Address src) {
|
||||
assert(VM_Version::supports_avx(), "");
|
||||
InstructionMark im(this);
|
||||
vex_prefix(dst, nds, src, VEX_SIMD_NONE); // 128-bit vector
|
||||
emit_byte(0x57);
|
||||
emit_operand(dst, src);
|
||||
}
|
||||
|
||||
|
||||
#ifndef _LP64
|
||||
// 32bit only pieces of the assembler
|
||||
|
||||
@ -7235,6 +7390,157 @@ void MacroAssembler::subss(XMMRegister dst, AddressLiteral src) {
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::ucomisd(XMMRegister dst, AddressLiteral src) {
|
||||
if (reachable(src)) {
|
||||
Assembler::ucomisd(dst, as_Address(src));
|
||||
} else {
|
||||
lea(rscratch1, src);
|
||||
Assembler::ucomisd(dst, Address(rscratch1, 0));
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::ucomiss(XMMRegister dst, AddressLiteral src) {
|
||||
if (reachable(src)) {
|
||||
Assembler::ucomiss(dst, as_Address(src));
|
||||
} else {
|
||||
lea(rscratch1, src);
|
||||
Assembler::ucomiss(dst, Address(rscratch1, 0));
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::xorpd(XMMRegister dst, AddressLiteral src) {
|
||||
// Used in sign-bit flipping with aligned address.
|
||||
assert((UseAVX > 0) || (((intptr_t)src.target() & 15) == 0), "SSE mode requires address alignment 16 bytes");
|
||||
if (reachable(src)) {
|
||||
Assembler::xorpd(dst, as_Address(src));
|
||||
} else {
|
||||
lea(rscratch1, src);
|
||||
Assembler::xorpd(dst, Address(rscratch1, 0));
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::xorps(XMMRegister dst, AddressLiteral src) {
|
||||
// Used in sign-bit flipping with aligned address.
|
||||
assert((UseAVX > 0) || (((intptr_t)src.target() & 15) == 0), "SSE mode requires address alignment 16 bytes");
|
||||
if (reachable(src)) {
|
||||
Assembler::xorps(dst, as_Address(src));
|
||||
} else {
|
||||
lea(rscratch1, src);
|
||||
Assembler::xorps(dst, Address(rscratch1, 0));
|
||||
}
|
||||
}
|
||||
|
||||
// AVX 3-operands instructions
|
||||
|
||||
void MacroAssembler::vaddsd(XMMRegister dst, XMMRegister nds, AddressLiteral src) {
|
||||
if (reachable(src)) {
|
||||
vaddsd(dst, nds, as_Address(src));
|
||||
} else {
|
||||
lea(rscratch1, src);
|
||||
vaddsd(dst, nds, Address(rscratch1, 0));
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::vaddss(XMMRegister dst, XMMRegister nds, AddressLiteral src) {
|
||||
if (reachable(src)) {
|
||||
vaddss(dst, nds, as_Address(src));
|
||||
} else {
|
||||
lea(rscratch1, src);
|
||||
vaddss(dst, nds, Address(rscratch1, 0));
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::vandpd(XMMRegister dst, XMMRegister nds, AddressLiteral src) {
|
||||
if (reachable(src)) {
|
||||
vandpd(dst, nds, as_Address(src));
|
||||
} else {
|
||||
lea(rscratch1, src);
|
||||
vandpd(dst, nds, Address(rscratch1, 0));
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::vandps(XMMRegister dst, XMMRegister nds, AddressLiteral src) {
|
||||
if (reachable(src)) {
|
||||
vandps(dst, nds, as_Address(src));
|
||||
} else {
|
||||
lea(rscratch1, src);
|
||||
vandps(dst, nds, Address(rscratch1, 0));
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::vdivsd(XMMRegister dst, XMMRegister nds, AddressLiteral src) {
|
||||
if (reachable(src)) {
|
||||
vdivsd(dst, nds, as_Address(src));
|
||||
} else {
|
||||
lea(rscratch1, src);
|
||||
vdivsd(dst, nds, Address(rscratch1, 0));
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::vdivss(XMMRegister dst, XMMRegister nds, AddressLiteral src) {
|
||||
if (reachable(src)) {
|
||||
vdivss(dst, nds, as_Address(src));
|
||||
} else {
|
||||
lea(rscratch1, src);
|
||||
vdivss(dst, nds, Address(rscratch1, 0));
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::vmulsd(XMMRegister dst, XMMRegister nds, AddressLiteral src) {
|
||||
if (reachable(src)) {
|
||||
vmulsd(dst, nds, as_Address(src));
|
||||
} else {
|
||||
lea(rscratch1, src);
|
||||
vmulsd(dst, nds, Address(rscratch1, 0));
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::vmulss(XMMRegister dst, XMMRegister nds, AddressLiteral src) {
|
||||
if (reachable(src)) {
|
||||
vmulss(dst, nds, as_Address(src));
|
||||
} else {
|
||||
lea(rscratch1, src);
|
||||
vmulss(dst, nds, Address(rscratch1, 0));
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::vsubsd(XMMRegister dst, XMMRegister nds, AddressLiteral src) {
|
||||
if (reachable(src)) {
|
||||
vsubsd(dst, nds, as_Address(src));
|
||||
} else {
|
||||
lea(rscratch1, src);
|
||||
vsubsd(dst, nds, Address(rscratch1, 0));
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::vsubss(XMMRegister dst, XMMRegister nds, AddressLiteral src) {
|
||||
if (reachable(src)) {
|
||||
vsubss(dst, nds, as_Address(src));
|
||||
} else {
|
||||
lea(rscratch1, src);
|
||||
vsubss(dst, nds, Address(rscratch1, 0));
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::vxorpd(XMMRegister dst, XMMRegister nds, AddressLiteral src) {
|
||||
if (reachable(src)) {
|
||||
vxorpd(dst, nds, as_Address(src));
|
||||
} else {
|
||||
lea(rscratch1, src);
|
||||
vxorpd(dst, nds, Address(rscratch1, 0));
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::vxorps(XMMRegister dst, XMMRegister nds, AddressLiteral src) {
|
||||
if (reachable(src)) {
|
||||
vxorps(dst, nds, as_Address(src));
|
||||
} else {
|
||||
lea(rscratch1, src);
|
||||
vxorps(dst, nds, Address(rscratch1, 0));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef SERIALGC
|
||||
|
||||
@ -8119,46 +8425,6 @@ void MacroAssembler::check_klass_subtype_slow_path(Register sub_klass,
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::ucomisd(XMMRegister dst, AddressLiteral src) {
|
||||
if (reachable(src)) {
|
||||
Assembler::ucomisd(dst, as_Address(src));
|
||||
} else {
|
||||
lea(rscratch1, src);
|
||||
Assembler::ucomisd(dst, Address(rscratch1, 0));
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::ucomiss(XMMRegister dst, AddressLiteral src) {
|
||||
if (reachable(src)) {
|
||||
Assembler::ucomiss(dst, as_Address(src));
|
||||
} else {
|
||||
lea(rscratch1, src);
|
||||
Assembler::ucomiss(dst, Address(rscratch1, 0));
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::xorpd(XMMRegister dst, AddressLiteral src) {
|
||||
// Used in sign-bit flipping with aligned address.
|
||||
assert((UseAVX > 0) || (((intptr_t)src.target() & 15) == 0), "SSE mode requires address alignment 16 bytes");
|
||||
if (reachable(src)) {
|
||||
Assembler::xorpd(dst, as_Address(src));
|
||||
} else {
|
||||
lea(rscratch1, src);
|
||||
Assembler::xorpd(dst, Address(rscratch1, 0));
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::xorps(XMMRegister dst, AddressLiteral src) {
|
||||
// Used in sign-bit flipping with aligned address.
|
||||
assert((UseAVX > 0) || (((intptr_t)src.target() & 15) == 0), "SSE mode requires address alignment 16 bytes");
|
||||
if (reachable(src)) {
|
||||
Assembler::xorps(dst, as_Address(src));
|
||||
} else {
|
||||
lea(rscratch1, src);
|
||||
Assembler::xorps(dst, Address(rscratch1, 0));
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::cmov32(Condition cc, Register dst, Address src) {
|
||||
if (VM_Version::supports_cmov()) {
|
||||
cmovl(cc, dst, src);
|
||||
|
@ -589,10 +589,21 @@ private:
|
||||
VexSimdPrefix pre, VexOpcode opc,
|
||||
bool vex_w, bool vector256);
|
||||
|
||||
void vex_prefix(XMMRegister dst, XMMRegister nds, Address src,
|
||||
VexSimdPrefix pre, bool vector256 = false) {
|
||||
vex_prefix(src, nds->encoding(), dst->encoding(),
|
||||
pre, VEX_OPCODE_0F, false, vector256);
|
||||
}
|
||||
|
||||
int vex_prefix_and_encode(int dst_enc, int nds_enc, int src_enc,
|
||||
VexSimdPrefix pre, VexOpcode opc,
|
||||
bool vex_w, bool vector256);
|
||||
|
||||
int vex_prefix_and_encode(XMMRegister dst, XMMRegister nds, XMMRegister src,
|
||||
VexSimdPrefix pre, bool vector256 = false) {
|
||||
return vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(),
|
||||
pre, VEX_OPCODE_0F, false, vector256);
|
||||
}
|
||||
|
||||
void simd_prefix(XMMRegister xreg, XMMRegister nds, Address adr,
|
||||
VexSimdPrefix pre, VexOpcode opc = VEX_OPCODE_0F,
|
||||
@ -1574,6 +1585,29 @@ private:
|
||||
|
||||
void set_byte_if_not_zero(Register dst); // sets reg to 1 if not zero, otherwise 0
|
||||
|
||||
// AVX 3-operands instructions (encoded with VEX prefix)
|
||||
void vaddsd(XMMRegister dst, XMMRegister nds, Address src);
|
||||
void vaddsd(XMMRegister dst, XMMRegister nds, XMMRegister src);
|
||||
void vaddss(XMMRegister dst, XMMRegister nds, Address src);
|
||||
void vaddss(XMMRegister dst, XMMRegister nds, XMMRegister src);
|
||||
void vandpd(XMMRegister dst, XMMRegister nds, Address src);
|
||||
void vandps(XMMRegister dst, XMMRegister nds, Address src);
|
||||
void vdivsd(XMMRegister dst, XMMRegister nds, Address src);
|
||||
void vdivsd(XMMRegister dst, XMMRegister nds, XMMRegister src);
|
||||
void vdivss(XMMRegister dst, XMMRegister nds, Address src);
|
||||
void vdivss(XMMRegister dst, XMMRegister nds, XMMRegister src);
|
||||
void vmulsd(XMMRegister dst, XMMRegister nds, Address src);
|
||||
void vmulsd(XMMRegister dst, XMMRegister nds, XMMRegister src);
|
||||
void vmulss(XMMRegister dst, XMMRegister nds, Address src);
|
||||
void vmulss(XMMRegister dst, XMMRegister nds, XMMRegister src);
|
||||
void vsubsd(XMMRegister dst, XMMRegister nds, Address src);
|
||||
void vsubsd(XMMRegister dst, XMMRegister nds, XMMRegister src);
|
||||
void vsubss(XMMRegister dst, XMMRegister nds, Address src);
|
||||
void vsubss(XMMRegister dst, XMMRegister nds, XMMRegister src);
|
||||
void vxorpd(XMMRegister dst, XMMRegister nds, Address src);
|
||||
void vxorps(XMMRegister dst, XMMRegister nds, Address src);
|
||||
|
||||
|
||||
protected:
|
||||
// Next instructions require address alignment 16 bytes SSE mode.
|
||||
// They should be called only from corresponding MacroAssembler instructions.
|
||||
@ -2422,6 +2456,53 @@ public:
|
||||
void xorps(XMMRegister dst, Address src) { Assembler::xorps(dst, src); }
|
||||
void xorps(XMMRegister dst, AddressLiteral src);
|
||||
|
||||
// AVX 3-operands instructions
|
||||
|
||||
void vaddsd(XMMRegister dst, XMMRegister nds, XMMRegister src) { Assembler::vaddsd(dst, nds, src); }
|
||||
void vaddsd(XMMRegister dst, XMMRegister nds, Address src) { Assembler::vaddsd(dst, nds, src); }
|
||||
void vaddsd(XMMRegister dst, XMMRegister nds, AddressLiteral src);
|
||||
|
||||
void vaddss(XMMRegister dst, XMMRegister nds, XMMRegister src) { Assembler::vaddss(dst, nds, src); }
|
||||
void vaddss(XMMRegister dst, XMMRegister nds, Address src) { Assembler::vaddss(dst, nds, src); }
|
||||
void vaddss(XMMRegister dst, XMMRegister nds, AddressLiteral src);
|
||||
|
||||
void vandpd(XMMRegister dst, XMMRegister nds, Address src) { Assembler::vandpd(dst, nds, src); }
|
||||
void vandpd(XMMRegister dst, XMMRegister nds, AddressLiteral src);
|
||||
|
||||
void vandps(XMMRegister dst, XMMRegister nds, Address src) { Assembler::vandps(dst, nds, src); }
|
||||
void vandps(XMMRegister dst, XMMRegister nds, AddressLiteral src);
|
||||
|
||||
void vdivsd(XMMRegister dst, XMMRegister nds, XMMRegister src) { Assembler::vdivsd(dst, nds, src); }
|
||||
void vdivsd(XMMRegister dst, XMMRegister nds, Address src) { Assembler::vdivsd(dst, nds, src); }
|
||||
void vdivsd(XMMRegister dst, XMMRegister nds, AddressLiteral src);
|
||||
|
||||
void vdivss(XMMRegister dst, XMMRegister nds, XMMRegister src) { Assembler::vdivss(dst, nds, src); }
|
||||
void vdivss(XMMRegister dst, XMMRegister nds, Address src) { Assembler::vdivss(dst, nds, src); }
|
||||
void vdivss(XMMRegister dst, XMMRegister nds, AddressLiteral src);
|
||||
|
||||
void vmulsd(XMMRegister dst, XMMRegister nds, XMMRegister src) { Assembler::vmulsd(dst, nds, src); }
|
||||
void vmulsd(XMMRegister dst, XMMRegister nds, Address src) { Assembler::vmulsd(dst, nds, src); }
|
||||
void vmulsd(XMMRegister dst, XMMRegister nds, AddressLiteral src);
|
||||
|
||||
void vmulss(XMMRegister dst, XMMRegister nds, XMMRegister src) { Assembler::vmulss(dst, nds, src); }
|
||||
void vmulss(XMMRegister dst, XMMRegister nds, Address src) { Assembler::vmulss(dst, nds, src); }
|
||||
void vmulss(XMMRegister dst, XMMRegister nds, AddressLiteral src);
|
||||
|
||||
void vsubsd(XMMRegister dst, XMMRegister nds, XMMRegister src) { Assembler::vsubsd(dst, nds, src); }
|
||||
void vsubsd(XMMRegister dst, XMMRegister nds, Address src) { Assembler::vsubsd(dst, nds, src); }
|
||||
void vsubsd(XMMRegister dst, XMMRegister nds, AddressLiteral src);
|
||||
|
||||
void vsubss(XMMRegister dst, XMMRegister nds, XMMRegister src) { Assembler::vsubss(dst, nds, src); }
|
||||
void vsubss(XMMRegister dst, XMMRegister nds, Address src) { Assembler::vsubss(dst, nds, src); }
|
||||
void vsubss(XMMRegister dst, XMMRegister nds, AddressLiteral src);
|
||||
|
||||
void vxorpd(XMMRegister dst, XMMRegister nds, Address src) { Assembler::vxorpd(dst, nds, src); }
|
||||
void vxorpd(XMMRegister dst, XMMRegister nds, AddressLiteral src);
|
||||
|
||||
void vxorps(XMMRegister dst, XMMRegister nds, Address src) { Assembler::vxorps(dst, nds, src); }
|
||||
void vxorps(XMMRegister dst, XMMRegister nds, AddressLiteral src);
|
||||
|
||||
|
||||
// Data
|
||||
|
||||
void cmov32( Condition cc, Register dst, Address src);
|
||||
|
777
hotspot/src/cpu/x86/vm/x86.ad
Normal file
777
hotspot/src/cpu/x86/vm/x86.ad
Normal file
@ -0,0 +1,777 @@
|
||||
//
|
||||
// Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
//
|
||||
// This code is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License version 2 only, as
|
||||
// published by the Free Software Foundation.
|
||||
//
|
||||
// This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
// version 2 for more details (a copy is included in the LICENSE file that
|
||||
// accompanied this code).
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License version
|
||||
// 2 along with this work; if not, write to the Free Software Foundation,
|
||||
// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
// or visit www.oracle.com if you need additional information or have any
|
||||
// questions.
|
||||
//
|
||||
//
|
||||
|
||||
// X86 Common Architecture Description File
|
||||
|
||||
source %{
|
||||
// Float masks come from different places depending on platform.
|
||||
#ifdef _LP64
|
||||
static address float_signmask() { return StubRoutines::x86::float_sign_mask(); }
|
||||
static address float_signflip() { return StubRoutines::x86::float_sign_flip(); }
|
||||
static address double_signmask() { return StubRoutines::x86::double_sign_mask(); }
|
||||
static address double_signflip() { return StubRoutines::x86::double_sign_flip(); }
|
||||
#else
|
||||
static address float_signmask() { return (address)float_signmask_pool; }
|
||||
static address float_signflip() { return (address)float_signflip_pool; }
|
||||
static address double_signmask() { return (address)double_signmask_pool; }
|
||||
static address double_signflip() { return (address)double_signflip_pool; }
|
||||
#endif
|
||||
%}
|
||||
|
||||
// INSTRUCTIONS -- Platform independent definitions (same for 32- and 64-bit)
|
||||
|
||||
instruct addF_reg(regF dst, regF src) %{
|
||||
predicate((UseSSE>=1) && (UseAVX == 0));
|
||||
match(Set dst (AddF dst src));
|
||||
|
||||
format %{ "addss $dst, $src" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ addss($dst$$XMMRegister, $src$$XMMRegister);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct addF_mem(regF dst, memory src) %{
|
||||
predicate((UseSSE>=1) && (UseAVX == 0));
|
||||
match(Set dst (AddF dst (LoadF src)));
|
||||
|
||||
format %{ "addss $dst, $src" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ addss($dst$$XMMRegister, $src$$Address);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct addF_imm(regF dst, immF con) %{
|
||||
predicate((UseSSE>=1) && (UseAVX == 0));
|
||||
match(Set dst (AddF dst con));
|
||||
format %{ "addss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ addss($dst$$XMMRegister, $constantaddress($con));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vaddF_reg(regF dst, regF src1, regF src2) %{
|
||||
predicate(UseAVX > 0);
|
||||
match(Set dst (AddF src1 src2));
|
||||
|
||||
format %{ "vaddss $dst, $src1, $src2" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ vaddss($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vaddF_mem(regF dst, regF src1, memory src2) %{
|
||||
predicate(UseAVX > 0);
|
||||
match(Set dst (AddF src1 (LoadF src2)));
|
||||
|
||||
format %{ "vaddss $dst, $src1, $src2" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ vaddss($dst$$XMMRegister, $src1$$XMMRegister, $src2$$Address);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vaddF_imm(regF dst, regF src, immF con) %{
|
||||
predicate(UseAVX > 0);
|
||||
match(Set dst (AddF src con));
|
||||
|
||||
format %{ "vaddss $dst, $src, [$constantaddress]\t# load from constant table: float=$con" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ vaddss($dst$$XMMRegister, $src$$XMMRegister, $constantaddress($con));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct addD_reg(regD dst, regD src) %{
|
||||
predicate((UseSSE>=2) && (UseAVX == 0));
|
||||
match(Set dst (AddD dst src));
|
||||
|
||||
format %{ "addsd $dst, $src" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ addsd($dst$$XMMRegister, $src$$XMMRegister);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct addD_mem(regD dst, memory src) %{
|
||||
predicate((UseSSE>=2) && (UseAVX == 0));
|
||||
match(Set dst (AddD dst (LoadD src)));
|
||||
|
||||
format %{ "addsd $dst, $src" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ addsd($dst$$XMMRegister, $src$$Address);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct addD_imm(regD dst, immD con) %{
|
||||
predicate((UseSSE>=2) && (UseAVX == 0));
|
||||
match(Set dst (AddD dst con));
|
||||
format %{ "addsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ addsd($dst$$XMMRegister, $constantaddress($con));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vaddD_reg(regD dst, regD src1, regD src2) %{
|
||||
predicate(UseAVX > 0);
|
||||
match(Set dst (AddD src1 src2));
|
||||
|
||||
format %{ "vaddsd $dst, $src1, $src2" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ vaddsd($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vaddD_mem(regD dst, regD src1, memory src2) %{
|
||||
predicate(UseAVX > 0);
|
||||
match(Set dst (AddD src1 (LoadD src2)));
|
||||
|
||||
format %{ "vaddsd $dst, $src1, $src2" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ vaddsd($dst$$XMMRegister, $src1$$XMMRegister, $src2$$Address);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vaddD_imm(regD dst, regD src, immD con) %{
|
||||
predicate(UseAVX > 0);
|
||||
match(Set dst (AddD src con));
|
||||
|
||||
format %{ "vaddsd $dst, $src, [$constantaddress]\t# load from constant table: double=$con" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ vaddsd($dst$$XMMRegister, $src$$XMMRegister, $constantaddress($con));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct subF_reg(regF dst, regF src) %{
|
||||
predicate((UseSSE>=1) && (UseAVX == 0));
|
||||
match(Set dst (SubF dst src));
|
||||
|
||||
format %{ "subss $dst, $src" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ subss($dst$$XMMRegister, $src$$XMMRegister);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct subF_mem(regF dst, memory src) %{
|
||||
predicate((UseSSE>=1) && (UseAVX == 0));
|
||||
match(Set dst (SubF dst (LoadF src)));
|
||||
|
||||
format %{ "subss $dst, $src" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ subss($dst$$XMMRegister, $src$$Address);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct subF_imm(regF dst, immF con) %{
|
||||
predicate((UseSSE>=1) && (UseAVX == 0));
|
||||
match(Set dst (SubF dst con));
|
||||
format %{ "subss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ subss($dst$$XMMRegister, $constantaddress($con));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vsubF_reg(regF dst, regF src1, regF src2) %{
|
||||
predicate(UseAVX > 0);
|
||||
match(Set dst (SubF src1 src2));
|
||||
|
||||
format %{ "vsubss $dst, $src1, $src2" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ vsubss($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vsubF_mem(regF dst, regF src1, memory src2) %{
|
||||
predicate(UseAVX > 0);
|
||||
match(Set dst (SubF src1 (LoadF src2)));
|
||||
|
||||
format %{ "vsubss $dst, $src1, $src2" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ vsubss($dst$$XMMRegister, $src1$$XMMRegister, $src2$$Address);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vsubF_imm(regF dst, regF src, immF con) %{
|
||||
predicate(UseAVX > 0);
|
||||
match(Set dst (SubF src con));
|
||||
|
||||
format %{ "vsubss $dst, $src, [$constantaddress]\t# load from constant table: float=$con" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ vsubss($dst$$XMMRegister, $src$$XMMRegister, $constantaddress($con));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct subD_reg(regD dst, regD src) %{
|
||||
predicate((UseSSE>=2) && (UseAVX == 0));
|
||||
match(Set dst (SubD dst src));
|
||||
|
||||
format %{ "subsd $dst, $src" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ subsd($dst$$XMMRegister, $src$$XMMRegister);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct subD_mem(regD dst, memory src) %{
|
||||
predicate((UseSSE>=2) && (UseAVX == 0));
|
||||
match(Set dst (SubD dst (LoadD src)));
|
||||
|
||||
format %{ "subsd $dst, $src" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ subsd($dst$$XMMRegister, $src$$Address);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct subD_imm(regD dst, immD con) %{
|
||||
predicate((UseSSE>=2) && (UseAVX == 0));
|
||||
match(Set dst (SubD dst con));
|
||||
format %{ "subsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ subsd($dst$$XMMRegister, $constantaddress($con));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vsubD_reg(regD dst, regD src1, regD src2) %{
|
||||
predicate(UseAVX > 0);
|
||||
match(Set dst (SubD src1 src2));
|
||||
|
||||
format %{ "vsubsd $dst, $src1, $src2" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ vsubsd($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vsubD_mem(regD dst, regD src1, memory src2) %{
|
||||
predicate(UseAVX > 0);
|
||||
match(Set dst (SubD src1 (LoadD src2)));
|
||||
|
||||
format %{ "vsubsd $dst, $src1, $src2" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ vsubsd($dst$$XMMRegister, $src1$$XMMRegister, $src2$$Address);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vsubD_imm(regD dst, regD src, immD con) %{
|
||||
predicate(UseAVX > 0);
|
||||
match(Set dst (SubD src con));
|
||||
|
||||
format %{ "vsubsd $dst, $src, [$constantaddress]\t# load from constant table: double=$con" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ vsubsd($dst$$XMMRegister, $src$$XMMRegister, $constantaddress($con));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct mulF_reg(regF dst, regF src) %{
|
||||
predicate((UseSSE>=1) && (UseAVX == 0));
|
||||
match(Set dst (MulF dst src));
|
||||
|
||||
format %{ "mulss $dst, $src" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ mulss($dst$$XMMRegister, $src$$XMMRegister);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct mulF_mem(regF dst, memory src) %{
|
||||
predicate((UseSSE>=1) && (UseAVX == 0));
|
||||
match(Set dst (MulF dst (LoadF src)));
|
||||
|
||||
format %{ "mulss $dst, $src" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ mulss($dst$$XMMRegister, $src$$Address);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct mulF_imm(regF dst, immF con) %{
|
||||
predicate((UseSSE>=1) && (UseAVX == 0));
|
||||
match(Set dst (MulF dst con));
|
||||
format %{ "mulss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ mulss($dst$$XMMRegister, $constantaddress($con));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vmulF_reg(regF dst, regF src1, regF src2) %{
|
||||
predicate(UseAVX > 0);
|
||||
match(Set dst (MulF src1 src2));
|
||||
|
||||
format %{ "vmulss $dst, $src1, $src2" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ vmulss($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vmulF_mem(regF dst, regF src1, memory src2) %{
|
||||
predicate(UseAVX > 0);
|
||||
match(Set dst (MulF src1 (LoadF src2)));
|
||||
|
||||
format %{ "vmulss $dst, $src1, $src2" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ vmulss($dst$$XMMRegister, $src1$$XMMRegister, $src2$$Address);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vmulF_imm(regF dst, regF src, immF con) %{
|
||||
predicate(UseAVX > 0);
|
||||
match(Set dst (MulF src con));
|
||||
|
||||
format %{ "vmulss $dst, $src, [$constantaddress]\t# load from constant table: float=$con" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ vmulss($dst$$XMMRegister, $src$$XMMRegister, $constantaddress($con));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct mulD_reg(regD dst, regD src) %{
|
||||
predicate((UseSSE>=2) && (UseAVX == 0));
|
||||
match(Set dst (MulD dst src));
|
||||
|
||||
format %{ "mulsd $dst, $src" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ mulsd($dst$$XMMRegister, $src$$XMMRegister);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct mulD_mem(regD dst, memory src) %{
|
||||
predicate((UseSSE>=2) && (UseAVX == 0));
|
||||
match(Set dst (MulD dst (LoadD src)));
|
||||
|
||||
format %{ "mulsd $dst, $src" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ mulsd($dst$$XMMRegister, $src$$Address);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct mulD_imm(regD dst, immD con) %{
|
||||
predicate((UseSSE>=2) && (UseAVX == 0));
|
||||
match(Set dst (MulD dst con));
|
||||
format %{ "mulsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ mulsd($dst$$XMMRegister, $constantaddress($con));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vmulD_reg(regD dst, regD src1, regD src2) %{
|
||||
predicate(UseAVX > 0);
|
||||
match(Set dst (MulD src1 src2));
|
||||
|
||||
format %{ "vmulsd $dst, $src1, $src2" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ vmulsd($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vmulD_mem(regD dst, regD src1, memory src2) %{
|
||||
predicate(UseAVX > 0);
|
||||
match(Set dst (MulD src1 (LoadD src2)));
|
||||
|
||||
format %{ "vmulsd $dst, $src1, $src2" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ vmulsd($dst$$XMMRegister, $src1$$XMMRegister, $src2$$Address);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vmulD_imm(regD dst, regD src, immD con) %{
|
||||
predicate(UseAVX > 0);
|
||||
match(Set dst (MulD src con));
|
||||
|
||||
format %{ "vmulsd $dst, $src, [$constantaddress]\t# load from constant table: double=$con" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ vmulsd($dst$$XMMRegister, $src$$XMMRegister, $constantaddress($con));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct divF_reg(regF dst, regF src) %{
|
||||
predicate((UseSSE>=1) && (UseAVX == 0));
|
||||
match(Set dst (DivF dst src));
|
||||
|
||||
format %{ "divss $dst, $src" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ divss($dst$$XMMRegister, $src$$XMMRegister);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct divF_mem(regF dst, memory src) %{
|
||||
predicate((UseSSE>=1) && (UseAVX == 0));
|
||||
match(Set dst (DivF dst (LoadF src)));
|
||||
|
||||
format %{ "divss $dst, $src" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ divss($dst$$XMMRegister, $src$$Address);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct divF_imm(regF dst, immF con) %{
|
||||
predicate((UseSSE>=1) && (UseAVX == 0));
|
||||
match(Set dst (DivF dst con));
|
||||
format %{ "divss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ divss($dst$$XMMRegister, $constantaddress($con));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vdivF_reg(regF dst, regF src1, regF src2) %{
|
||||
predicate(UseAVX > 0);
|
||||
match(Set dst (DivF src1 src2));
|
||||
|
||||
format %{ "vdivss $dst, $src1, $src2" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ vdivss($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vdivF_mem(regF dst, regF src1, memory src2) %{
|
||||
predicate(UseAVX > 0);
|
||||
match(Set dst (DivF src1 (LoadF src2)));
|
||||
|
||||
format %{ "vdivss $dst, $src1, $src2" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ vdivss($dst$$XMMRegister, $src1$$XMMRegister, $src2$$Address);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vdivF_imm(regF dst, regF src, immF con) %{
|
||||
predicate(UseAVX > 0);
|
||||
match(Set dst (DivF src con));
|
||||
|
||||
format %{ "vdivss $dst, $src, [$constantaddress]\t# load from constant table: float=$con" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ vdivss($dst$$XMMRegister, $src$$XMMRegister, $constantaddress($con));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct divD_reg(regD dst, regD src) %{
|
||||
predicate((UseSSE>=2) && (UseAVX == 0));
|
||||
match(Set dst (DivD dst src));
|
||||
|
||||
format %{ "divsd $dst, $src" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ divsd($dst$$XMMRegister, $src$$XMMRegister);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct divD_mem(regD dst, memory src) %{
|
||||
predicate((UseSSE>=2) && (UseAVX == 0));
|
||||
match(Set dst (DivD dst (LoadD src)));
|
||||
|
||||
format %{ "divsd $dst, $src" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ divsd($dst$$XMMRegister, $src$$Address);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct divD_imm(regD dst, immD con) %{
|
||||
predicate((UseSSE>=2) && (UseAVX == 0));
|
||||
match(Set dst (DivD dst con));
|
||||
format %{ "divsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ divsd($dst$$XMMRegister, $constantaddress($con));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vdivD_reg(regD dst, regD src1, regD src2) %{
|
||||
predicate(UseAVX > 0);
|
||||
match(Set dst (DivD src1 src2));
|
||||
|
||||
format %{ "vdivsd $dst, $src1, $src2" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ vdivsd($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vdivD_mem(regD dst, regD src1, memory src2) %{
|
||||
predicate(UseAVX > 0);
|
||||
match(Set dst (DivD src1 (LoadD src2)));
|
||||
|
||||
format %{ "vdivsd $dst, $src1, $src2" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ vdivsd($dst$$XMMRegister, $src1$$XMMRegister, $src2$$Address);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vdivD_imm(regD dst, regD src, immD con) %{
|
||||
predicate(UseAVX > 0);
|
||||
match(Set dst (DivD src con));
|
||||
|
||||
format %{ "vdivsd $dst, $src, [$constantaddress]\t# load from constant table: double=$con" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ vdivsd($dst$$XMMRegister, $src$$XMMRegister, $constantaddress($con));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct absF_reg(regF dst) %{
|
||||
predicate((UseSSE>=1) && (UseAVX == 0));
|
||||
match(Set dst (AbsF dst));
|
||||
ins_cost(150);
|
||||
format %{ "andps $dst, [0x7fffffff]\t# abs float by sign masking" %}
|
||||
ins_encode %{
|
||||
__ andps($dst$$XMMRegister, ExternalAddress(float_signmask()));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vabsF_reg(regF dst, regF src) %{
|
||||
predicate(UseAVX > 0);
|
||||
match(Set dst (AbsF src));
|
||||
ins_cost(150);
|
||||
format %{ "vandps $dst, $src, [0x7fffffff]\t# abs float by sign masking" %}
|
||||
ins_encode %{
|
||||
__ vandps($dst$$XMMRegister, $src$$XMMRegister,
|
||||
ExternalAddress(float_signmask()));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct absD_reg(regD dst) %{
|
||||
predicate((UseSSE>=2) && (UseAVX == 0));
|
||||
match(Set dst (AbsD dst));
|
||||
ins_cost(150);
|
||||
format %{ "andpd $dst, [0x7fffffffffffffff]\t"
|
||||
"# abs double by sign masking" %}
|
||||
ins_encode %{
|
||||
__ andpd($dst$$XMMRegister, ExternalAddress(double_signmask()));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vabsD_reg(regD dst, regD src) %{
|
||||
predicate(UseAVX > 0);
|
||||
match(Set dst (AbsD src));
|
||||
ins_cost(150);
|
||||
format %{ "vandpd $dst, $src, [0x7fffffffffffffff]\t"
|
||||
"# abs double by sign masking" %}
|
||||
ins_encode %{
|
||||
__ vandpd($dst$$XMMRegister, $src$$XMMRegister,
|
||||
ExternalAddress(double_signmask()));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct negF_reg(regF dst) %{
|
||||
predicate((UseSSE>=1) && (UseAVX == 0));
|
||||
match(Set dst (NegF dst));
|
||||
ins_cost(150);
|
||||
format %{ "xorps $dst, [0x80000000]\t# neg float by sign flipping" %}
|
||||
ins_encode %{
|
||||
__ xorps($dst$$XMMRegister, ExternalAddress(float_signflip()));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vnegF_reg(regF dst, regF src) %{
|
||||
predicate(UseAVX > 0);
|
||||
match(Set dst (NegF src));
|
||||
ins_cost(150);
|
||||
format %{ "vxorps $dst, $src, [0x80000000]\t# neg float by sign flipping" %}
|
||||
ins_encode %{
|
||||
__ vxorps($dst$$XMMRegister, $src$$XMMRegister,
|
||||
ExternalAddress(float_signflip()));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct negD_reg(regD dst) %{
|
||||
predicate((UseSSE>=2) && (UseAVX == 0));
|
||||
match(Set dst (NegD dst));
|
||||
ins_cost(150);
|
||||
format %{ "xorpd $dst, [0x8000000000000000]\t"
|
||||
"# neg double by sign flipping" %}
|
||||
ins_encode %{
|
||||
__ xorpd($dst$$XMMRegister, ExternalAddress(double_signflip()));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vnegD_reg(regD dst, regD src) %{
|
||||
predicate(UseAVX > 0);
|
||||
match(Set dst (NegD src));
|
||||
ins_cost(150);
|
||||
format %{ "vxorpd $dst, $src, [0x8000000000000000]\t"
|
||||
"# neg double by sign flipping" %}
|
||||
ins_encode %{
|
||||
__ vxorpd($dst$$XMMRegister, $src$$XMMRegister,
|
||||
ExternalAddress(double_signflip()));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct sqrtF_reg(regF dst, regF src) %{
|
||||
predicate(UseSSE>=1);
|
||||
match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
|
||||
|
||||
format %{ "sqrtss $dst, $src" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ sqrtss($dst$$XMMRegister, $src$$XMMRegister);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct sqrtF_mem(regF dst, memory src) %{
|
||||
predicate(UseSSE>=1);
|
||||
match(Set dst (ConvD2F (SqrtD (ConvF2D (LoadF src)))));
|
||||
|
||||
format %{ "sqrtss $dst, $src" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ sqrtss($dst$$XMMRegister, $src$$Address);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct sqrtF_imm(regF dst, immF con) %{
|
||||
predicate(UseSSE>=1);
|
||||
match(Set dst (ConvD2F (SqrtD (ConvF2D con))));
|
||||
format %{ "sqrtss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ sqrtss($dst$$XMMRegister, $constantaddress($con));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct sqrtD_reg(regD dst, regD src) %{
|
||||
predicate(UseSSE>=2);
|
||||
match(Set dst (SqrtD src));
|
||||
|
||||
format %{ "sqrtsd $dst, $src" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ sqrtsd($dst$$XMMRegister, $src$$XMMRegister);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct sqrtD_mem(regD dst, memory src) %{
|
||||
predicate(UseSSE>=2);
|
||||
match(Set dst (SqrtD (LoadD src)));
|
||||
|
||||
format %{ "sqrtsd $dst, $src" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ sqrtsd($dst$$XMMRegister, $src$$Address);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct sqrtD_imm(regD dst, immD con) %{
|
||||
predicate(UseSSE>=2);
|
||||
match(Set dst (SqrtD con));
|
||||
format %{ "sqrtsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
|
||||
ins_cost(150);
|
||||
ins_encode %{
|
||||
__ sqrtsd($dst$$XMMRegister, $constantaddress($con));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -9873,396 +9873,6 @@ instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct addF_reg(regF dst, regF src)
|
||||
%{
|
||||
match(Set dst (AddF dst src));
|
||||
|
||||
format %{ "addss $dst, $src" %}
|
||||
ins_cost(150); // XXX
|
||||
ins_encode %{
|
||||
__ addss($dst$$XMMRegister, $src$$XMMRegister);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct addF_mem(regF dst, memory src)
|
||||
%{
|
||||
match(Set dst (AddF dst (LoadF src)));
|
||||
|
||||
format %{ "addss $dst, $src" %}
|
||||
ins_cost(150); // XXX
|
||||
ins_encode %{
|
||||
__ addss($dst$$XMMRegister, $src$$Address);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct addF_imm(regF dst, immF con) %{
|
||||
match(Set dst (AddF dst con));
|
||||
format %{ "addss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
|
||||
ins_cost(150); // XXX
|
||||
ins_encode %{
|
||||
__ addss($dst$$XMMRegister, $constantaddress($con));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct addD_reg(regD dst, regD src)
|
||||
%{
|
||||
match(Set dst (AddD dst src));
|
||||
|
||||
format %{ "addsd $dst, $src" %}
|
||||
ins_cost(150); // XXX
|
||||
ins_encode %{
|
||||
__ addsd($dst$$XMMRegister, $src$$XMMRegister);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct addD_mem(regD dst, memory src)
|
||||
%{
|
||||
match(Set dst (AddD dst (LoadD src)));
|
||||
|
||||
format %{ "addsd $dst, $src" %}
|
||||
ins_cost(150); // XXX
|
||||
ins_encode %{
|
||||
__ addsd($dst$$XMMRegister, $src$$Address);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct addD_imm(regD dst, immD con) %{
|
||||
match(Set dst (AddD dst con));
|
||||
format %{ "addsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
|
||||
ins_cost(150); // XXX
|
||||
ins_encode %{
|
||||
__ addsd($dst$$XMMRegister, $constantaddress($con));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct subF_reg(regF dst, regF src)
|
||||
%{
|
||||
match(Set dst (SubF dst src));
|
||||
|
||||
format %{ "subss $dst, $src" %}
|
||||
ins_cost(150); // XXX
|
||||
ins_encode %{
|
||||
__ subss($dst$$XMMRegister, $src$$XMMRegister);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct subF_mem(regF dst, memory src)
|
||||
%{
|
||||
match(Set dst (SubF dst (LoadF src)));
|
||||
|
||||
format %{ "subss $dst, $src" %}
|
||||
ins_cost(150); // XXX
|
||||
ins_encode %{
|
||||
__ subss($dst$$XMMRegister, $src$$Address);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct subF_imm(regF dst, immF con) %{
|
||||
match(Set dst (SubF dst con));
|
||||
format %{ "subss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
|
||||
ins_cost(150); // XXX
|
||||
ins_encode %{
|
||||
__ subss($dst$$XMMRegister, $constantaddress($con));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct subD_reg(regD dst, regD src)
|
||||
%{
|
||||
match(Set dst (SubD dst src));
|
||||
|
||||
format %{ "subsd $dst, $src" %}
|
||||
ins_cost(150); // XXX
|
||||
ins_encode %{
|
||||
__ subsd($dst$$XMMRegister, $src$$XMMRegister);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct subD_mem(regD dst, memory src)
|
||||
%{
|
||||
match(Set dst (SubD dst (LoadD src)));
|
||||
|
||||
format %{ "subsd $dst, $src" %}
|
||||
ins_cost(150); // XXX
|
||||
ins_encode %{
|
||||
__ subsd($dst$$XMMRegister, $src$$Address);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct subD_imm(regD dst, immD con) %{
|
||||
match(Set dst (SubD dst con));
|
||||
format %{ "subsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
|
||||
ins_cost(150); // XXX
|
||||
ins_encode %{
|
||||
__ subsd($dst$$XMMRegister, $constantaddress($con));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct mulF_reg(regF dst, regF src)
|
||||
%{
|
||||
match(Set dst (MulF dst src));
|
||||
|
||||
format %{ "mulss $dst, $src" %}
|
||||
ins_cost(150); // XXX
|
||||
ins_encode %{
|
||||
__ mulss($dst$$XMMRegister, $src$$XMMRegister);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct mulF_mem(regF dst, memory src)
|
||||
%{
|
||||
match(Set dst (MulF dst (LoadF src)));
|
||||
|
||||
format %{ "mulss $dst, $src" %}
|
||||
ins_cost(150); // XXX
|
||||
ins_encode %{
|
||||
__ mulss($dst$$XMMRegister, $src$$Address);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct mulF_imm(regF dst, immF con) %{
|
||||
match(Set dst (MulF dst con));
|
||||
format %{ "mulss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
|
||||
ins_cost(150); // XXX
|
||||
ins_encode %{
|
||||
__ mulss($dst$$XMMRegister, $constantaddress($con));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct mulD_reg(regD dst, regD src)
|
||||
%{
|
||||
match(Set dst (MulD dst src));
|
||||
|
||||
format %{ "mulsd $dst, $src" %}
|
||||
ins_cost(150); // XXX
|
||||
ins_encode %{
|
||||
__ mulsd($dst$$XMMRegister, $src$$XMMRegister);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct mulD_mem(regD dst, memory src)
|
||||
%{
|
||||
match(Set dst (MulD dst (LoadD src)));
|
||||
|
||||
format %{ "mulsd $dst, $src" %}
|
||||
ins_cost(150); // XXX
|
||||
ins_encode %{
|
||||
__ mulsd($dst$$XMMRegister, $src$$Address);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct mulD_imm(regD dst, immD con) %{
|
||||
match(Set dst (MulD dst con));
|
||||
format %{ "mulsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
|
||||
ins_cost(150); // XXX
|
||||
ins_encode %{
|
||||
__ mulsd($dst$$XMMRegister, $constantaddress($con));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct divF_reg(regF dst, regF src)
|
||||
%{
|
||||
match(Set dst (DivF dst src));
|
||||
|
||||
format %{ "divss $dst, $src" %}
|
||||
ins_cost(150); // XXX
|
||||
ins_encode %{
|
||||
__ divss($dst$$XMMRegister, $src$$XMMRegister);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct divF_mem(regF dst, memory src)
|
||||
%{
|
||||
match(Set dst (DivF dst (LoadF src)));
|
||||
|
||||
format %{ "divss $dst, $src" %}
|
||||
ins_cost(150); // XXX
|
||||
ins_encode %{
|
||||
__ divss($dst$$XMMRegister, $src$$Address);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct divF_imm(regF dst, immF con) %{
|
||||
match(Set dst (DivF dst con));
|
||||
format %{ "divss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
|
||||
ins_cost(150); // XXX
|
||||
ins_encode %{
|
||||
__ divss($dst$$XMMRegister, $constantaddress($con));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct divD_reg(regD dst, regD src)
|
||||
%{
|
||||
match(Set dst (DivD dst src));
|
||||
|
||||
format %{ "divsd $dst, $src" %}
|
||||
ins_cost(150); // XXX
|
||||
ins_encode %{
|
||||
__ divsd($dst$$XMMRegister, $src$$XMMRegister);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct divD_mem(regD dst, memory src)
|
||||
%{
|
||||
match(Set dst (DivD dst (LoadD src)));
|
||||
|
||||
format %{ "divsd $dst, $src" %}
|
||||
ins_cost(150); // XXX
|
||||
ins_encode %{
|
||||
__ divsd($dst$$XMMRegister, $src$$Address);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct divD_imm(regD dst, immD con) %{
|
||||
match(Set dst (DivD dst con));
|
||||
format %{ "divsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
|
||||
ins_cost(150); // XXX
|
||||
ins_encode %{
|
||||
__ divsd($dst$$XMMRegister, $constantaddress($con));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct sqrtF_reg(regF dst, regF src)
|
||||
%{
|
||||
match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
|
||||
|
||||
format %{ "sqrtss $dst, $src" %}
|
||||
ins_cost(150); // XXX
|
||||
ins_encode %{
|
||||
__ sqrtss($dst$$XMMRegister, $src$$XMMRegister);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct sqrtF_mem(regF dst, memory src)
|
||||
%{
|
||||
match(Set dst (ConvD2F (SqrtD (ConvF2D (LoadF src)))));
|
||||
|
||||
format %{ "sqrtss $dst, $src" %}
|
||||
ins_cost(150); // XXX
|
||||
ins_encode %{
|
||||
__ sqrtss($dst$$XMMRegister, $src$$Address);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct sqrtF_imm(regF dst, immF con) %{
|
||||
match(Set dst (ConvD2F (SqrtD (ConvF2D con))));
|
||||
format %{ "sqrtss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
|
||||
ins_cost(150); // XXX
|
||||
ins_encode %{
|
||||
__ sqrtss($dst$$XMMRegister, $constantaddress($con));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct sqrtD_reg(regD dst, regD src)
|
||||
%{
|
||||
match(Set dst (SqrtD src));
|
||||
|
||||
format %{ "sqrtsd $dst, $src" %}
|
||||
ins_cost(150); // XXX
|
||||
ins_encode %{
|
||||
__ sqrtsd($dst$$XMMRegister, $src$$XMMRegister);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct sqrtD_mem(regD dst, memory src)
|
||||
%{
|
||||
match(Set dst (SqrtD (LoadD src)));
|
||||
|
||||
format %{ "sqrtsd $dst, $src" %}
|
||||
ins_cost(150); // XXX
|
||||
ins_encode %{
|
||||
__ sqrtsd($dst$$XMMRegister, $src$$Address);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct sqrtD_imm(regD dst, immD con) %{
|
||||
match(Set dst (SqrtD con));
|
||||
format %{ "sqrtsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
|
||||
ins_cost(150); // XXX
|
||||
ins_encode %{
|
||||
__ sqrtsd($dst$$XMMRegister, $constantaddress($con));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct absF_reg(regF dst)
|
||||
%{
|
||||
match(Set dst (AbsF dst));
|
||||
ins_cost(150); // XXX
|
||||
format %{ "andps $dst, [0x7fffffff]\t# abs float by sign masking" %}
|
||||
ins_encode %{
|
||||
__ andps($dst$$XMMRegister,
|
||||
ExternalAddress((address) StubRoutines::x86::float_sign_mask()));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct absD_reg(regD dst)
|
||||
%{
|
||||
match(Set dst (AbsD dst));
|
||||
ins_cost(150); // XXX
|
||||
format %{ "andpd $dst, [0x7fffffffffffffff]\t"
|
||||
"# abs double by sign masking" %}
|
||||
ins_encode %{
|
||||
__ andpd($dst$$XMMRegister,
|
||||
ExternalAddress((address) StubRoutines::x86::double_sign_mask()));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct negF_reg(regF dst)
|
||||
%{
|
||||
match(Set dst (NegF dst));
|
||||
ins_cost(150); // XXX
|
||||
format %{ "xorps $dst, [0x80000000]\t# neg float by sign flipping" %}
|
||||
ins_encode %{
|
||||
__ xorps($dst$$XMMRegister,
|
||||
ExternalAddress((address) StubRoutines::x86::float_sign_flip()));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct negD_reg(regD dst)
|
||||
%{
|
||||
match(Set dst (NegD dst));
|
||||
ins_cost(150); // XXX
|
||||
format %{ "xorpd $dst, [0x8000000000000000]\t"
|
||||
"# neg double by sign flipping" %}
|
||||
ins_encode %{
|
||||
__ xorpd($dst$$XMMRegister,
|
||||
ExternalAddress((address) StubRoutines::x86::double_sign_flip()));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
// -----------Trig and Trancendental Instructions------------------------------
|
||||
instruct cosD_reg(regD dst) %{
|
||||
match(Set dst (CosD dst));
|
||||
|
@ -1365,31 +1365,36 @@ static bool match_into_reg( const Node *n, Node *m, Node *control, int i, bool s
|
||||
|
||||
const Type *t = m->bottom_type();
|
||||
|
||||
if( t->singleton() ) {
|
||||
if (t->singleton()) {
|
||||
// Never force constants into registers. Allow them to match as
|
||||
// constants or registers. Copies of the same value will share
|
||||
// the same register. See find_shared_node.
|
||||
return false;
|
||||
} else { // Not a constant
|
||||
// Stop recursion if they have different Controls.
|
||||
// Slot 0 of constants is not really a Control.
|
||||
if( control && m->in(0) && control != m->in(0) ) {
|
||||
Node* m_control = m->in(0);
|
||||
// Control of load's memory can post-dominates load's control.
|
||||
// So use it since load can't float above its memory.
|
||||
Node* mem_control = (m->is_Load()) ? m->in(MemNode::Memory)->in(0) : NULL;
|
||||
if (control && m_control && control != m_control && control != mem_control) {
|
||||
|
||||
// Actually, we can live with the most conservative control we
|
||||
// find, if it post-dominates the others. This allows us to
|
||||
// pick up load/op/store trees where the load can float a little
|
||||
// above the store.
|
||||
Node *x = control;
|
||||
const uint max_scan = 6; // Arbitrary scan cutoff
|
||||
const uint max_scan = 6; // Arbitrary scan cutoff
|
||||
uint j;
|
||||
for( j=0; j<max_scan; j++ ) {
|
||||
if( x->is_Region() ) // Bail out at merge points
|
||||
for (j=0; j<max_scan; j++) {
|
||||
if (x->is_Region()) // Bail out at merge points
|
||||
return true;
|
||||
x = x->in(0);
|
||||
if( x == m->in(0) ) // Does 'control' post-dominate
|
||||
if (x == m_control) // Does 'control' post-dominate
|
||||
break; // m->in(0)? If so, we can use it
|
||||
if (x == mem_control) // Does 'control' post-dominate
|
||||
break; // mem_control? If so, we can use it
|
||||
}
|
||||
if( j == max_scan ) // No post-domination before scan end?
|
||||
if (j == max_scan) // No post-domination before scan end?
|
||||
return true; // Then break the match tree up
|
||||
}
|
||||
if (m->is_DecodeN() && Matcher::narrow_oop_use_complex_address()) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user