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:
Vladimir Kozlov 2011-12-20 00:55:02 -08:00
parent 2928feab6a
commit dc542c9909
10 changed files with 1709 additions and 1311 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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);

View 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

View File

@ -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));

View File

@ -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()) {