Commit 87c46838 authored by alph's avatar alph Committed by Commit bot

[x64] Implement vpcmpeqd, vpslld, vpsrld AVX instructions.

BUG=v8:4406
LOG=N

Review URL: https://codereview.chromium.org/1419983002

Cr-Commit-Position: refs/heads/master@{#31452}
parent 1ee09b29
......@@ -166,7 +166,7 @@ class OutOfLineLoadNaN final : public OutOfLineCode {
OutOfLineLoadNaN(CodeGenerator* gen, XMMRegister result)
: OutOfLineCode(gen), result_(result) {}
void Generate() final { __ pcmpeqd(result_, result_); }
void Generate() final { __ Pcmpeqd(result_, result_); }
private:
XMMRegister const result_;
......@@ -335,7 +335,7 @@ class OutOfLineTruncateDoubleToI final : public OutOfLineCode {
\
void Generate() final { \
__ leal(kScratchRegister, Operand(index1_, index2_)); \
__ pcmpeqd(result_, result_); \
__ Pcmpeqd(result_, result_); \
__ cmpl(kScratchRegister, Immediate(length_)); \
__ j(above_equal, exit()); \
__ asm_instr(result_, \
......@@ -1044,9 +1044,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
break;
case kAVXFloat32Abs: {
// TODO(bmeurer): Use RIP relative 128-bit constants.
__ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
__ psrlq(kScratchDoubleReg, 33);
CpuFeatureScope avx_scope(masm(), AVX);
__ vpcmpeqd(kScratchDoubleReg, kScratchDoubleReg, kScratchDoubleReg);
__ vpsrlq(kScratchDoubleReg, kScratchDoubleReg, 33);
if (instr->InputAt(0)->IsDoubleRegister()) {
__ vandps(i.OutputDoubleRegister(), kScratchDoubleReg,
i.InputDoubleRegister(0));
......@@ -1058,9 +1058,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
}
case kAVXFloat32Neg: {
// TODO(bmeurer): Use RIP relative 128-bit constants.
__ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
__ psllq(kScratchDoubleReg, 31);
CpuFeatureScope avx_scope(masm(), AVX);
__ vpcmpeqd(kScratchDoubleReg, kScratchDoubleReg, kScratchDoubleReg);
__ vpsllq(kScratchDoubleReg, kScratchDoubleReg, 31);
if (instr->InputAt(0)->IsDoubleRegister()) {
__ vxorps(i.OutputDoubleRegister(), kScratchDoubleReg,
i.InputDoubleRegister(0));
......@@ -1072,9 +1072,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
}
case kAVXFloat64Abs: {
// TODO(bmeurer): Use RIP relative 128-bit constants.
__ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
__ psrlq(kScratchDoubleReg, 1);
CpuFeatureScope avx_scope(masm(), AVX);
__ vpcmpeqd(kScratchDoubleReg, kScratchDoubleReg, kScratchDoubleReg);
__ vpsrlq(kScratchDoubleReg, kScratchDoubleReg, 1);
if (instr->InputAt(0)->IsDoubleRegister()) {
__ vandpd(i.OutputDoubleRegister(), kScratchDoubleReg,
i.InputDoubleRegister(0));
......@@ -1086,9 +1086,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
}
case kAVXFloat64Neg: {
// TODO(bmeurer): Use RIP relative 128-bit constants.
__ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
__ psllq(kScratchDoubleReg, 63);
CpuFeatureScope avx_scope(masm(), AVX);
__ vpcmpeqd(kScratchDoubleReg, kScratchDoubleReg, kScratchDoubleReg);
__ vpsllq(kScratchDoubleReg, kScratchDoubleReg, 63);
if (instr->InputAt(0)->IsDoubleRegister()) {
__ vxorpd(i.OutputDoubleRegister(), kScratchDoubleReg,
i.InputDoubleRegister(0));
......
......@@ -3819,7 +3819,7 @@ void LCodeGen::DoMathLog(LMathLog* instr) {
__ Ucomisd(input_reg, xmm_scratch);
__ j(above, &positive, Label::kNear);
__ j(not_carry, &zero, Label::kNear);
__ pcmpeqd(input_reg, input_reg);
__ Pcmpeqd(input_reg, input_reg);
__ jmp(&done, Label::kNear);
__ bind(&zero);
ExternalReference ninf =
......@@ -4940,7 +4940,7 @@ void LCodeGen::EmitNumberUntagD(LNumberUntagD* instr, Register input_reg,
__ CompareRoot(input_reg, Heap::kUndefinedValueRootIndex);
DeoptimizeIf(not_equal, instr, Deoptimizer::kNotAHeapNumberUndefined);
__ pcmpeqd(result_reg, result_reg);
__ Pcmpeqd(result_reg, result_reg);
__ jmp(&done, Label::kNear);
}
} else {
......
......@@ -2986,6 +2986,7 @@ void Assembler::movss(const Operand& src, XMMRegister dst) {
void Assembler::psllq(XMMRegister reg, byte imm8) {
DCHECK(!IsEnabled(AVX));
EnsureSpace ensure_space(this);
emit(0x66);
emit_optional_rex_32(reg);
......@@ -2997,6 +2998,7 @@ void Assembler::psllq(XMMRegister reg, byte imm8) {
void Assembler::psrlq(XMMRegister reg, byte imm8) {
DCHECK(!IsEnabled(AVX));
EnsureSpace ensure_space(this);
emit(0x66);
emit_optional_rex_32(reg);
......@@ -3449,6 +3451,7 @@ void Assembler::movmskps(Register dst, XMMRegister src) {
void Assembler::pcmpeqd(XMMRegister dst, XMMRegister src) {
DCHECK(!IsEnabled(AVX));
EnsureSpace ensure_space(this);
emit(0x66);
emit_optional_rex_32(dst, src);
......
......@@ -1326,6 +1326,7 @@ class Assembler : public AssemblerBase {
AVX_SP_3(vmax, 0x5f);
AVX_P_3(vand, 0x54);
AVX_P_3(vxor, 0x57);
AVX_3(vpcmpeqd, 0x76, vpd);
AVX_3(vcvtsd2ss, 0x5a, vsd);
#undef AVX_3
......@@ -1333,6 +1334,16 @@ class Assembler : public AssemblerBase {
#undef AVX_P_3
#undef AVX_SP_3
void vpsrlq(XMMRegister dst, XMMRegister src, byte imm8) {
XMMRegister iop = {2};
vpd(0x73, iop, dst, src);
emit(imm8);
}
void vpsllq(XMMRegister dst, XMMRegister src, byte imm8) {
XMMRegister iop = {6};
vpd(0x73, iop, dst, src);
emit(imm8);
}
void vcvtss2sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
vsd(0x5a, dst, src1, src2, kF3, k0F, kWIG);
}
......
......@@ -1250,6 +1250,17 @@ int DisassemblerX64::AVXInstruction(byte* data) {
NameOfXMMRegister(regop));
current += PrintRightOperand(current);
break;
case 0x73:
AppendToBuffer("%s %s,", regop == 6 ? "vpsllq" : "vpsrlq",
NameOfXMMRegister(vvvv));
current += PrintRightXMMOperand(current);
AppendToBuffer(",%u", *current++);
break;
case 0x76:
AppendToBuffer("vpcmpeqd %s,%s,", NameOfXMMRegister(regop),
NameOfXMMRegister(vvvv));
current += PrintRightXMMOperand(current);
break;
case 0x7e:
AppendToBuffer("vmov%c ", vex_w() ? 'q' : 'd');
current += PrintRightOperand(current);
......
......@@ -2490,7 +2490,7 @@ void MacroAssembler::Move(XMMRegister dst, uint32_t src) {
unsigned pop = base::bits::CountPopulation32(src);
DCHECK_NE(0u, pop);
if (pop == 32) {
pcmpeqd(dst, dst);
Pcmpeqd(dst, dst);
} else {
movl(kScratchRegister, Immediate(src));
Movq(dst, kScratchRegister);
......@@ -2508,13 +2508,13 @@ void MacroAssembler::Move(XMMRegister dst, uint64_t src) {
unsigned pop = base::bits::CountPopulation64(src);
DCHECK_NE(0u, pop);
if (pop == 64) {
pcmpeqd(dst, dst);
Pcmpeqd(dst, dst);
} else if (pop + ntz == 64) {
pcmpeqd(dst, dst);
psllq(dst, ntz);
Pcmpeqd(dst, dst);
Psllq(dst, ntz);
} else if (pop + nlz == 64) {
pcmpeqd(dst, dst);
psrlq(dst, nlz);
Pcmpeqd(dst, dst);
Psrlq(dst, nlz);
} else {
uint32_t lower = static_cast<uint32_t>(src);
uint32_t upper = static_cast<uint32_t>(src >> 32);
......@@ -2719,6 +2719,36 @@ void MacroAssembler::Xorpd(XMMRegister dst, XMMRegister src) {
}
void MacroAssembler::Pcmpeqd(XMMRegister dst, XMMRegister src) {
if (CpuFeatures::IsSupported(AVX)) {
CpuFeatureScope scope(this, AVX);
vpcmpeqd(dst, dst, src);
} else {
pcmpeqd(dst, src);
}
}
void MacroAssembler::Psllq(XMMRegister dst, byte imm8) {
if (CpuFeatures::IsSupported(AVX)) {
CpuFeatureScope scope(this, AVX);
vpsllq(dst, dst, imm8);
} else {
psllq(dst, imm8);
}
}
void MacroAssembler::Psrlq(XMMRegister dst, byte imm8) {
if (CpuFeatures::IsSupported(AVX)) {
CpuFeatureScope scope(this, AVX);
vpsrlq(dst, dst, imm8);
} else {
psrlq(dst, imm8);
}
}
void MacroAssembler::Cmp(Register dst, Handle<Object> source) {
AllowDeferredHandleDereference smi_check;
if (source->IsSmi()) {
......
......@@ -927,6 +927,9 @@ class MacroAssembler: public Assembler {
void Ucomisd(XMMRegister src1, const Operand& src2);
void Xorpd(XMMRegister dst, XMMRegister src);
void Pcmpeqd(XMMRegister dst, XMMRegister src);
void Psllq(XMMRegister dst, byte imm8);
void Psrlq(XMMRegister dst, byte imm8);
// Control Flow
void Jump(Address destination, RelocInfo::Mode rmode);
......
......@@ -1423,6 +1423,33 @@ TEST(AssemblerX64AVX_sd) {
__ cmpl(rdx, Immediate(2));
__ j(not_equal, &exit);
// Test vpcmpeqd
__ movq(rdx, V8_UINT64_C(0x0123456789abcdef));
__ movq(rcx, V8_UINT64_C(0x0123456788888888));
__ vmovq(xmm6, rdx);
__ vmovq(xmm7, rcx);
__ vpcmpeqd(xmm8, xmm6, xmm7);
__ vmovq(rdx, xmm8);
__ movq(rcx, V8_UINT64_C(0xffffffff00000000));
__ cmpq(rcx, rdx);
__ movl(rax, Immediate(13));
__ j(not_equal, &exit);
// Test vpsllq, vpsrlq
__ movl(rax, Immediate(13));
__ movq(rdx, V8_UINT64_C(0x0123456789abcdef));
__ vmovq(xmm6, rdx);
__ vpsrlq(xmm7, xmm6, 4);
__ vmovq(rdx, xmm7);
__ movq(rcx, V8_UINT64_C(0x00123456789abcde));
__ cmpq(rdx, rcx);
__ j(not_equal, &exit);
__ vpsllq(xmm7, xmm6, 12);
__ vmovq(rdx, xmm7);
__ movq(rcx, V8_UINT64_C(0x3456789abcdef000));
__ cmpq(rdx, rcx);
__ j(not_equal, &exit);
__ movl(rdx, Immediate(6));
__ vcvtlsi2sd(xmm6, xmm6, rdx);
__ movl(Operand(rsp, 0), Immediate(5));
......
......@@ -567,6 +567,11 @@ TEST(DisasmX64) {
__ vandpd(xmm9, xmm1, Operand(rbx, rcx, times_4, 10000));
__ vxorpd(xmm0, xmm1, xmm9);
__ vxorpd(xmm0, xmm1, Operand(rbx, rcx, times_4, 10000));
__ vpcmpeqd(xmm0, xmm15, xmm5);
__ vpcmpeqd(xmm15, xmm0, Operand(rbx, rcx, times_4, 10000));
__ vpsllq(xmm0, xmm15, 21);
__ vpsrlq(xmm15, xmm0, 21);
}
}
......
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