Commit b973a777 authored by weiliang.lin's avatar weiliang.lin Committed by Commit bot

[x64] add Absps/d and Negps/d macro

BUG=

Review-Url: https://codereview.chromium.org/2161513002
Cr-Commit-Position: refs/heads/master@{#37937}
parent f6f8062f
......@@ -126,6 +126,32 @@ double uint32_bias;
static DoubleConstant double_constants;
static struct V8_ALIGNED(16) {
uint32_t a;
uint32_t b;
uint32_t c;
uint32_t d;
} float_absolute_constant = {0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF};
static struct V8_ALIGNED(16) {
uint32_t a;
uint32_t b;
uint32_t c;
uint32_t d;
} float_negate_constant = {0x80000000, 0x80000000, 0x80000000, 0x80000000};
static struct V8_ALIGNED(16) {
uint64_t a;
uint64_t b;
} double_absolute_constant = {V8_UINT64_C(0x7FFFFFFFFFFFFFFF),
V8_UINT64_C(0x7FFFFFFFFFFFFFFF)};
static struct V8_ALIGNED(16) {
uint64_t a;
uint64_t b;
} double_negate_constant = {V8_UINT64_C(0x8000000000000000),
V8_UINT64_C(0x8000000000000000)};
const char* const RelocInfo::kFillerCommentString = "DEOPTIMIZATION PADDING";
// -----------------------------------------------------------------------------
......@@ -1317,6 +1343,26 @@ ExternalReference ExternalReference::address_of_uint32_bias() {
}
ExternalReference ExternalReference::address_of_float_abs_constant() {
return ExternalReference(reinterpret_cast<void*>(&float_absolute_constant));
}
ExternalReference ExternalReference::address_of_float_neg_constant() {
return ExternalReference(reinterpret_cast<void*>(&float_negate_constant));
}
ExternalReference ExternalReference::address_of_double_abs_constant() {
return ExternalReference(reinterpret_cast<void*>(&double_absolute_constant));
}
ExternalReference ExternalReference::address_of_double_neg_constant() {
return ExternalReference(reinterpret_cast<void*>(&double_negate_constant));
}
ExternalReference ExternalReference::is_profiling_address(Isolate* isolate) {
return ExternalReference(isolate->is_profiling_address());
}
......
......@@ -991,6 +991,12 @@ class ExternalReference BASE_EMBEDDED {
static ExternalReference address_of_the_hole_nan();
static ExternalReference address_of_uint32_bias();
// Static variables containing simd constants.
static ExternalReference address_of_float_abs_constant();
static ExternalReference address_of_float_neg_constant();
static ExternalReference address_of_double_abs_constant();
static ExternalReference address_of_double_neg_constant();
// IEEE 754 functions.
static ExternalReference ieee754_acos_function(Isolate* isolate);
static ExternalReference ieee754_acosh_function(Isolate* isolate);
......
......@@ -224,6 +224,14 @@ void ExternalReferenceTable::AddReferences(Isolate* isolate) {
Add(ExternalReference::is_tail_call_elimination_enabled_address(isolate)
.address(),
"Isolate::is_tail_call_elimination_enabled_address()");
Add(ExternalReference::address_of_float_abs_constant().address(),
"float_absolute_constant");
Add(ExternalReference::address_of_float_neg_constant().address(),
"float_negate_constant");
Add(ExternalReference::address_of_double_abs_constant().address(),
"double_absolute_constant");
Add(ExternalReference::address_of_double_neg_constant().address(),
"double_negate_constant");
// Debug addresses
Add(ExternalReference::debug_after_break_target_address(isolate).address(),
......
......@@ -2963,6 +2963,24 @@ void Assembler::movapd(XMMRegister dst, XMMRegister src) {
}
void Assembler::movupd(XMMRegister dst, const Operand& src) {
EnsureSpace ensure_space(this);
emit(0x66);
emit_optional_rex_32(dst, src);
emit(0x0F);
emit(0x10);
emit_sse_operand(dst, src);
}
void Assembler::movupd(const Operand& dst, XMMRegister src) {
EnsureSpace ensure_space(this);
emit(0x66);
emit_optional_rex_32(src, dst);
emit(0x0F);
emit(0x11);
emit_sse_operand(src, dst);
}
void Assembler::addss(XMMRegister dst, XMMRegister src) {
EnsureSpace ensure_space(this);
emit(0xF3);
......@@ -3605,6 +3623,16 @@ void Assembler::andpd(XMMRegister dst, XMMRegister src) {
}
void Assembler::andpd(XMMRegister dst, const Operand& src) {
EnsureSpace ensure_space(this);
emit(0x66);
emit_optional_rex_32(dst, src);
emit(0x0F);
emit(0x54);
emit_sse_operand(dst, src);
}
void Assembler::orpd(XMMRegister dst, XMMRegister src) {
EnsureSpace ensure_space(this);
emit(0x66);
......@@ -3615,6 +3643,16 @@ void Assembler::orpd(XMMRegister dst, XMMRegister src) {
}
void Assembler::orpd(XMMRegister dst, const Operand& src) {
EnsureSpace ensure_space(this);
emit(0x66);
emit_optional_rex_32(dst, src);
emit(0x0F);
emit(0x56);
emit_sse_operand(dst, src);
}
void Assembler::xorpd(XMMRegister dst, XMMRegister src) {
DCHECK(!IsEnabled(AVX));
EnsureSpace ensure_space(this);
......@@ -3626,6 +3664,17 @@ void Assembler::xorpd(XMMRegister dst, XMMRegister src) {
}
void Assembler::xorpd(XMMRegister dst, const Operand& src) {
DCHECK(!IsEnabled(AVX));
EnsureSpace ensure_space(this);
emit(0x66);
emit_optional_rex_32(dst, src);
emit(0x0F);
emit(0x57);
emit_sse_operand(dst, src);
}
void Assembler::sqrtsd(XMMRegister dst, XMMRegister src) {
DCHECK(!IsEnabled(AVX));
EnsureSpace ensure_space(this);
......
......@@ -1094,6 +1094,8 @@ class Assembler : public AssemblerBase {
void movdqu(XMMRegister dst, const Operand& src);
void movapd(XMMRegister dst, XMMRegister src);
void movupd(XMMRegister dst, const Operand& src);
void movupd(const Operand& dst, XMMRegister src);
void psllq(XMMRegister reg, byte imm8);
void psrlq(XMMRegister reg, byte imm8);
......@@ -1140,8 +1142,11 @@ class Assembler : public AssemblerBase {
void minsd(XMMRegister dst, const Operand& src);
void andpd(XMMRegister dst, XMMRegister src);
void andpd(XMMRegister dst, const Operand& src);
void orpd(XMMRegister dst, XMMRegister src);
void orpd(XMMRegister dst, const Operand& src);
void xorpd(XMMRegister dst, XMMRegister src);
void xorpd(XMMRegister dst, const Operand& src);
void sqrtsd(XMMRegister dst, XMMRegister src);
void sqrtsd(XMMRegister dst, const Operand& src);
......@@ -1539,6 +1544,12 @@ class Assembler : public AssemblerBase {
vps(0x11, src, xmm0, dst);
}
void vmovapd(XMMRegister dst, XMMRegister src) { vpd(0x28, dst, xmm0, src); }
void vmovupd(XMMRegister dst, const Operand& src) {
vpd(0x10, dst, xmm0, src);
}
void vmovupd(const Operand& dst, XMMRegister src) {
vpd(0x11, src, xmm0, dst);
}
void vmovmskpd(Register dst, XMMRegister src) {
XMMRegister idst = {dst.code()};
vpd(0x50, idst, xmm0, src);
......
......@@ -1266,6 +1266,15 @@ int DisassemblerX64::AVXInstruction(byte* data) {
int mod, regop, rm, vvvv = vex_vreg();
get_modrm(*current, &mod, &regop, &rm);
switch (opcode) {
case 0x10:
AppendToBuffer("vmovupd %s,", NameOfXMMRegister(regop));
current += PrintRightXMMOperand(current);
break;
case 0x11:
AppendToBuffer("vmovupd ");
current += PrintRightXMMOperand(current);
AppendToBuffer(",%s", NameOfXMMRegister(regop));
break;
case 0x28:
AppendToBuffer("vmovapd %s,", NameOfXMMRegister(regop));
current += PrintRightXMMOperand(current);
......@@ -1589,6 +1598,13 @@ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) {
current += 4;
} // else no immediate displacement.
AppendToBuffer("nop");
} else if (opcode == 0x10) {
AppendToBuffer("movupd %s,", NameOfXMMRegister(regop));
current += PrintRightXMMOperand(current);
} else if (opcode == 0x11) {
AppendToBuffer("movupd ");
current += PrintRightXMMOperand(current);
AppendToBuffer(",%s", NameOfXMMRegister(regop));
} else if (opcode == 0x28) {
AppendToBuffer("movapd %s,", NameOfXMMRegister(regop));
current += PrintRightXMMOperand(current);
......
......@@ -2755,6 +2755,23 @@ void MacroAssembler::Movapd(XMMRegister dst, XMMRegister src) {
}
}
void MacroAssembler::Movupd(XMMRegister dst, const Operand& src) {
if (CpuFeatures::IsSupported(AVX)) {
CpuFeatureScope scope(this, AVX);
vmovupd(dst, src);
} else {
movupd(dst, src);
}
}
void MacroAssembler::Movupd(const Operand& dst, XMMRegister src) {
if (CpuFeatures::IsSupported(AVX)) {
CpuFeatureScope scope(this, AVX);
vmovupd(dst, src);
} else {
movupd(dst, src);
}
}
void MacroAssembler::Movsd(XMMRegister dst, XMMRegister src) {
if (CpuFeatures::IsSupported(AVX)) {
......@@ -2974,6 +2991,27 @@ void MacroAssembler::Ucomisd(XMMRegister src1, const Operand& src2) {
}
}
// ----------------------------------------------------------------------------
void MacroAssembler::Absps(XMMRegister dst) {
Andps(dst,
ExternalOperand(ExternalReference::address_of_float_abs_constant()));
}
void MacroAssembler::Negps(XMMRegister dst) {
Xorps(dst,
ExternalOperand(ExternalReference::address_of_float_neg_constant()));
}
void MacroAssembler::Abspd(XMMRegister dst) {
Andps(dst,
ExternalOperand(ExternalReference::address_of_double_abs_constant()));
}
void MacroAssembler::Negpd(XMMRegister dst) {
Xorps(dst,
ExternalOperand(ExternalReference::address_of_double_neg_constant()));
}
void MacroAssembler::Cmp(Register dst, Handle<Object> source) {
AllowDeferredHandleDereference smi_check;
......
......@@ -957,9 +957,10 @@ class MacroAssembler: public Assembler {
AVX_OP2_XO(Subsd, subsd)
AVX_OP2_XO(Mulsd, mulsd)
AVX_OP2_XO(Divsd, divsd)
AVX_OP2_X(Andpd, andpd)
AVX_OP2_X(Orpd, orpd)
AVX_OP2_X(Xorpd, xorpd)
AVX_OP2_XO(Andps, andps)
AVX_OP2_XO(Andpd, andpd)
AVX_OP2_XO(Orpd, orpd)
AVX_OP2_XO(Xorpd, xorpd)
AVX_OP2_X(Pcmpeqd, pcmpeqd)
AVX_OP2_WITH_TYPE(Psllq, psllq, byte)
AVX_OP2_WITH_TYPE(Psrlq, psrlq, byte)
......@@ -987,6 +988,8 @@ class MacroAssembler: public Assembler {
void Movups(XMMRegister dst, const Operand& src);
void Movups(const Operand& dst, XMMRegister src);
void Movapd(XMMRegister dst, XMMRegister src);
void Movupd(XMMRegister dst, const Operand& src);
void Movupd(const Operand& dst, XMMRegister src);
void Movmskpd(Register dst, XMMRegister src);
void Xorps(XMMRegister dst, XMMRegister src);
......@@ -1002,6 +1005,13 @@ class MacroAssembler: public Assembler {
void Ucomisd(XMMRegister src1, XMMRegister src2);
void Ucomisd(XMMRegister src1, const Operand& src2);
// ---------------------------------------------------------------------------
// SIMD macros.
void Absps(XMMRegister dst);
void Negps(XMMRegister dst);
void Abspd(XMMRegister dst);
void Negpd(XMMRegister dst);
// Control Flow
void Jump(Address destination, RelocInfo::Mode rmode);
void Jump(ExternalReference ext);
......
......@@ -431,6 +431,8 @@ TEST(DisasmX64) {
__ movsd(xmm1, Operand(rbx, rcx, times_4, 10000));
__ movsd(Operand(rbx, rcx, times_4, 10000), xmm1);
// 128 bit move instructions.
__ movupd(xmm0, Operand(rbx, rcx, times_4, 10000));
__ movupd(Operand(rbx, rcx, times_4, 10000), xmm0);
__ movdqa(xmm0, Operand(rbx, rcx, times_4, 10000));
__ movdqa(Operand(rbx, rcx, times_4, 10000), xmm0);
......@@ -449,6 +451,11 @@ TEST(DisasmX64) {
__ ucomisd(xmm0, xmm1);
__ andpd(xmm0, xmm1);
__ andpd(xmm0, Operand(rbx, rcx, times_4, 10000));
__ orpd(xmm0, xmm1);
__ orpd(xmm0, Operand(rbx, rcx, times_4, 10000));
__ xorpd(xmm0, xmm1);
__ xorpd(xmm0, Operand(rbx, rcx, times_4, 10000));
__ pslld(xmm0, 6);
__ psrld(xmm0, 6);
......@@ -597,6 +604,8 @@ TEST(DisasmX64) {
__ vmovaps(xmm10, xmm11);
__ vmovapd(xmm7, xmm0);
__ vmovupd(xmm0, Operand(rbx, rcx, times_4, 10000));
__ vmovupd(Operand(rbx, rcx, times_4, 10000), xmm0);
__ vmovmskpd(r9, xmm4);
__ vmovups(xmm5, xmm1);
......
......@@ -55,7 +55,10 @@ using i::carry;
using i::greater;
using i::greater_equal;
using i::kIntSize;
using i::kFloatSize;
using i::kDoubleSize;
using i::kPointerSize;
using i::kSimd128Size;
using i::kSmiTagMask;
using i::kSmiValueSize;
using i::less_equal;
......@@ -79,6 +82,22 @@ using i::rdi;
using i::rdx;
using i::rsi;
using i::rsp;
using i::xmm0;
using i::xmm1;
using i::xmm2;
using i::xmm3;
using i::xmm4;
using i::xmm5;
using i::xmm6;
using i::xmm7;
using i::xmm8;
using i::xmm9;
using i::xmm10;
using i::xmm11;
using i::xmm12;
using i::xmm13;
using i::xmm14;
using i::xmm15;
using i::times_pointer_size;
// Test the x64 assembler by compiling some simple functions into
......@@ -2728,5 +2747,159 @@ TEST(LoadAndStoreWithRepresentation) {
CHECK_EQ(0, result);
}
void TestFloat32x4Abs(MacroAssembler* masm, Label* exit, float x, float y,
float z, float w) {
__ subq(rsp, Immediate(kSimd128Size));
__ Move(xmm1, x);
__ Movss(Operand(rsp, 0 * kFloatSize), xmm1);
__ Move(xmm2, y);
__ Movss(Operand(rsp, 1 * kFloatSize), xmm2);
__ Move(xmm3, z);
__ Movss(Operand(rsp, 2 * kFloatSize), xmm3);
__ Move(xmm4, w);
__ Movss(Operand(rsp, 3 * kFloatSize), xmm4);
__ Movups(xmm0, Operand(rsp, 0));
__ Absps(xmm0);
__ Movups(Operand(rsp, 0), xmm0);
__ incq(rax);
__ Move(xmm1, fabsf(x));
__ Ucomiss(xmm1, Operand(rsp, 0 * kFloatSize));
__ j(not_equal, exit);
__ incq(rax);
__ Move(xmm2, fabsf(y));
__ Ucomiss(xmm2, Operand(rsp, 1 * kFloatSize));
__ j(not_equal, exit);
__ incq(rax);
__ Move(xmm3, fabsf(z));
__ Ucomiss(xmm3, Operand(rsp, 2 * kFloatSize));
__ j(not_equal, exit);
__ incq(rax);
__ Move(xmm4, fabsf(w));
__ Ucomiss(xmm4, Operand(rsp, 3 * kFloatSize));
__ j(not_equal, exit);
__ addq(rsp, Immediate(kSimd128Size));
}
void TestFloat32x4Neg(MacroAssembler* masm, Label* exit, float x, float y,
float z, float w) {
__ subq(rsp, Immediate(kSimd128Size));
__ Move(xmm1, x);
__ Movss(Operand(rsp, 0 * kFloatSize), xmm1);
__ Move(xmm2, y);
__ Movss(Operand(rsp, 1 * kFloatSize), xmm2);
__ Move(xmm3, z);
__ Movss(Operand(rsp, 2 * kFloatSize), xmm3);
__ Move(xmm4, w);
__ Movss(Operand(rsp, 3 * kFloatSize), xmm4);
__ Movups(xmm0, Operand(rsp, 0));
__ Negps(xmm0);
__ Movups(Operand(rsp, 0), xmm0);
__ incq(rax);
__ Move(xmm1, -x);
__ Ucomiss(xmm1, Operand(rsp, 0 * kFloatSize));
__ j(not_equal, exit);
__ incq(rax);
__ Move(xmm2, -y);
__ Ucomiss(xmm2, Operand(rsp, 1 * kFloatSize));
__ j(not_equal, exit);
__ incq(rax);
__ Move(xmm3, -z);
__ Ucomiss(xmm3, Operand(rsp, 2 * kFloatSize));
__ j(not_equal, exit);
__ incq(rax);
__ Move(xmm4, -w);
__ Ucomiss(xmm4, Operand(rsp, 3 * kFloatSize));
__ j(not_equal, exit);
__ addq(rsp, Immediate(kSimd128Size));
}
void TestFloat64x2Abs(MacroAssembler* masm, Label* exit, double x, double y) {
__ subq(rsp, Immediate(kSimd128Size));
__ Move(xmm1, x);
__ Movsd(Operand(rsp, 0 * kDoubleSize), xmm1);
__ Move(xmm2, y);
__ Movsd(Operand(rsp, 1 * kDoubleSize), xmm2);
__ Movupd(xmm0, Operand(rsp, 0));
__ Abspd(xmm0);
__ Movupd(Operand(rsp, 0), xmm0);
__ incq(rax);
__ Move(xmm1, fabs(x));
__ Ucomisd(xmm1, Operand(rsp, 0 * kDoubleSize));
__ j(not_equal, exit);
__ incq(rax);
__ Move(xmm2, fabs(y));
__ Ucomisd(xmm2, Operand(rsp, 1 * kDoubleSize));
__ j(not_equal, exit);
__ addq(rsp, Immediate(kSimd128Size));
}
void TestFloat64x2Neg(MacroAssembler* masm, Label* exit, double x, double y) {
__ subq(rsp, Immediate(kSimd128Size));
__ Move(xmm1, x);
__ Movsd(Operand(rsp, 0 * kDoubleSize), xmm1);
__ Move(xmm2, y);
__ Movsd(Operand(rsp, 1 * kDoubleSize), xmm2);
__ Movupd(xmm0, Operand(rsp, 0));
__ Negpd(xmm0);
__ Movupd(Operand(rsp, 0), xmm0);
__ incq(rax);
__ Move(xmm1, -x);
__ Ucomisd(xmm1, Operand(rsp, 0 * kDoubleSize));
__ j(not_equal, exit);
__ incq(rax);
__ Move(xmm2, -y);
__ Ucomisd(xmm2, Operand(rsp, 1 * kDoubleSize));
__ j(not_equal, exit);
__ addq(rsp, Immediate(kSimd128Size));
}
TEST(SIMDMacros) {
// Allocate an executable page of memory.
size_t actual_size;
byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
Assembler::kMinimalBufferSize * 2, &actual_size, true));
CHECK(buffer);
Isolate* isolate = CcTest::i_isolate();
HandleScope handles(isolate);
MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size),
v8::internal::CodeObjectRequired::kYes);
MacroAssembler* masm = &assembler;
EntryCode(masm);
Label exit;
__ xorq(rax, rax);
TestFloat32x4Abs(masm, &exit, 1.5, -1.5, 0.5, -0.5);
TestFloat32x4Neg(masm, &exit, 1.5, -1.5, 0.5, -0.5);
TestFloat64x2Abs(masm, &exit, 1.75, -1.75);
TestFloat64x2Neg(masm, &exit, 1.75, -1.75);
__ xorq(rax, rax); // Success.
__ bind(&exit);
ExitCode(masm);
__ ret(0);
CodeDesc desc;
masm->GetCode(&desc);
// Call the function from C++.
int result = FUNCTION_CAST<F0>(buffer)();
CHECK_EQ(0, result);
}
#undef __
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment