[x64] Use vmovapd and vmovsd when AVX is enabled.

R=bmeurer@chromium.org
BUG=v8:4406
LOG=N

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

Cr-Commit-Position: refs/heads/master@{#31275}
This commit is contained in:
alph 2015-10-14 21:14:31 -07:00 committed by Commit bot
parent facf9953d2
commit 5cda2bcfab
14 changed files with 186 additions and 92 deletions

View File

@ -181,7 +181,7 @@ class OutOfLineTruncateDoubleToI final : public OutOfLineCode {
void Generate() final {
__ subp(rsp, Immediate(kDoubleSize));
__ movsd(MemOperand(rsp, 0), input_);
__ Movsd(MemOperand(rsp, 0), input_);
__ SlowTruncateToI(result_, rsp, 0);
__ addp(rsp, Immediate(kDoubleSize));
}
@ -835,9 +835,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
case kSSEFloat64Mod: {
__ subq(rsp, Immediate(kDoubleSize));
// Move values to st(0) and st(1).
__ movsd(Operand(rsp, 0), i.InputDoubleRegister(1));
__ Movsd(Operand(rsp, 0), i.InputDoubleRegister(1));
__ fld_d(Operand(rsp, 0));
__ movsd(Operand(rsp, 0), i.InputDoubleRegister(0));
__ Movsd(Operand(rsp, 0), i.InputDoubleRegister(0));
__ fld_d(Operand(rsp, 0));
// Loop while fprem isn't done.
Label mod_loop;
@ -860,7 +860,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
// Move output to stack and clean up.
__ fstp(1);
__ fstp_d(Operand(rsp, 0));
__ movsd(i.OutputDoubleRegister(), Operand(rsp, 0));
__ Movsd(i.OutputDoubleRegister(), Operand(rsp, 0));
__ addq(rsp, Immediate(kDoubleSize));
break;
}
@ -1164,11 +1164,11 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
break;
case kX64Movsd:
if (instr->HasOutput()) {
__ movsd(i.OutputDoubleRegister(), i.MemoryOperand());
__ Movsd(i.OutputDoubleRegister(), i.MemoryOperand());
} else {
size_t index = 0;
Operand operand = i.MemoryOperand(&index);
__ movsd(operand, i.InputDoubleRegister(index));
__ Movsd(operand, i.InputDoubleRegister(index));
}
break;
case kX64BitcastFI:
@ -1196,7 +1196,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
if (instr->InputAt(0)->IsRegister()) {
__ movq(i.OutputDoubleRegister(), i.InputRegister(0));
} else {
__ movsd(i.OutputDoubleRegister(), i.InputOperand(0));
__ Movsd(i.OutputDoubleRegister(), i.InputOperand(0));
}
break;
case kX64Lea32: {
@ -1251,7 +1251,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
} else if (instr->InputAt(0)->IsDoubleRegister()) {
// TODO(titzer): use another machine instruction?
__ subq(rsp, Immediate(kDoubleSize));
__ movsd(Operand(rsp, 0), i.InputDoubleRegister(0));
__ Movsd(Operand(rsp, 0), i.InputDoubleRegister(0));
} else {
__ pushq(i.InputOperand(0));
}
@ -1306,7 +1306,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
ASSEMBLE_CHECKED_LOAD_FLOAT(movss);
break;
case kCheckedLoadFloat64:
ASSEMBLE_CHECKED_LOAD_FLOAT(movsd);
ASSEMBLE_CHECKED_LOAD_FLOAT(Movsd);
break;
case kCheckedStoreWord8:
ASSEMBLE_CHECKED_STORE_INTEGER(movb);
@ -1324,7 +1324,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
ASSEMBLE_CHECKED_STORE_FLOAT(movss);
break;
case kCheckedStoreFloat64:
ASSEMBLE_CHECKED_STORE_FLOAT(movsd);
ASSEMBLE_CHECKED_STORE_FLOAT(Movsd);
break;
case kX64StackCheck:
__ CompareRoot(rsp, Heap::kStackLimitRootIndex);
@ -1724,19 +1724,19 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
} else {
DCHECK(destination->IsDoubleStackSlot());
Operand dst = g.ToOperand(destination);
__ movsd(dst, src);
__ Movsd(dst, src);
}
} else if (source->IsDoubleStackSlot()) {
DCHECK(destination->IsDoubleRegister() || destination->IsDoubleStackSlot());
Operand src = g.ToOperand(source);
if (destination->IsDoubleRegister()) {
XMMRegister dst = g.ToDoubleRegister(destination);
__ movsd(dst, src);
__ Movsd(dst, src);
} else {
// We rely on having xmm0 available as a fixed scratch register.
Operand dst = g.ToOperand(destination);
__ movsd(xmm0, src);
__ movsd(dst, xmm0);
__ Movsd(xmm0, src);
__ Movsd(dst, xmm0);
}
} else {
UNREACHABLE();
@ -1779,9 +1779,9 @@ void CodeGenerator::AssembleSwap(InstructionOperand* source,
// available as a fixed scratch register.
XMMRegister src = g.ToDoubleRegister(source);
Operand dst = g.ToOperand(destination);
__ movsd(xmm0, src);
__ movsd(src, dst);
__ movsd(dst, xmm0);
__ Movsd(xmm0, src);
__ Movsd(src, dst);
__ Movsd(dst, xmm0);
} else {
// No other combinations are possible.
UNREACHABLE();

View File

@ -2685,6 +2685,7 @@ void Assembler::pinsrd(XMMRegister dst, const Operand& src, int8_t imm8) {
void Assembler::movsd(const Operand& dst, XMMRegister src) {
DCHECK(!IsEnabled(AVX));
EnsureSpace ensure_space(this);
emit(0xF2); // double
emit_optional_rex_32(src, dst);
@ -2695,6 +2696,7 @@ void Assembler::movsd(const Operand& dst, XMMRegister src) {
void Assembler::movsd(XMMRegister dst, XMMRegister src) {
DCHECK(!IsEnabled(AVX));
EnsureSpace ensure_space(this);
emit(0xF2); // double
emit_optional_rex_32(dst, src);
@ -2705,6 +2707,7 @@ void Assembler::movsd(XMMRegister dst, XMMRegister src) {
void Assembler::movsd(XMMRegister dst, const Operand& src) {
DCHECK(!IsEnabled(AVX));
EnsureSpace ensure_space(this);
emit(0xF2); // double
emit_optional_rex_32(dst, src);
@ -3458,6 +3461,15 @@ void Assembler::vfmass(byte op, XMMRegister dst, XMMRegister src1,
}
void Assembler::vmovapd(XMMRegister dst, XMMRegister src) {
DCHECK(IsEnabled(AVX));
EnsureSpace ensure_space(this);
emit_vex_prefix(dst, xmm0, src, kLIG, k66, k0F, kWIG);
emit(0x28);
emit_sse_operand(dst, src);
}
void Assembler::vucomisd(XMMRegister dst, XMMRegister src) {
DCHECK(IsEnabled(AVX));
EnsureSpace ensure_space(this);

View File

@ -1267,6 +1267,14 @@ class Assembler : public AssemblerBase {
void vfmass(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2);
void vfmass(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2);
void vmovapd(XMMRegister dst, XMMRegister src);
void vmovsd(XMMRegister dst, const Operand& src) {
vsd(0x10, dst, xmm0, src);
}
void vmovsd(XMMRegister dst, XMMRegister src) { vsd(0x10, dst, xmm0, src); }
void vmovsd(const Operand& dst, XMMRegister src) {
vsd(0x11, src, xmm0, dst);
}
void vaddsd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
vsd(0x58, dst, src1, src2);
}

View File

@ -180,7 +180,7 @@ void DoubleToIStub::Generate(MacroAssembler* masm) {
bool stash_exponent_copy = !input_reg.is(rsp);
__ movl(scratch1, mantissa_operand);
__ movsd(xmm0, mantissa_operand);
__ Movsd(xmm0, mantissa_operand);
__ movl(rcx, exponent_operand);
if (stash_exponent_copy) __ pushq(rcx);
@ -237,14 +237,14 @@ void FloatingPointHelper::LoadSSE2UnknownOperands(MacroAssembler* masm,
__ JumpIfSmi(rdx, &load_smi_rdx);
__ cmpp(FieldOperand(rdx, HeapObject::kMapOffset), rcx);
__ j(not_equal, not_numbers); // Argument in rdx is not a number.
__ movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset));
__ Movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset));
// Load operand in rax into xmm1, or branch to not_numbers.
__ JumpIfSmi(rax, &load_smi_rax);
__ bind(&load_nonsmi_rax);
__ cmpp(FieldOperand(rax, HeapObject::kMapOffset), rcx);
__ j(not_equal, not_numbers);
__ movsd(xmm1, FieldOperand(rax, HeapNumber::kValueOffset));
__ Movsd(xmm1, FieldOperand(rax, HeapNumber::kValueOffset));
__ jmp(&done);
__ bind(&load_smi_rdx);
@ -288,7 +288,7 @@ void MathPowStub::Generate(MacroAssembler* masm) {
Heap::kHeapNumberMapRootIndex);
__ j(not_equal, &call_runtime);
__ movsd(double_base, FieldOperand(base, HeapNumber::kValueOffset));
__ Movsd(double_base, FieldOperand(base, HeapNumber::kValueOffset));
__ jmp(&unpack_exponent, Label::kNear);
__ bind(&base_is_smi);
@ -304,14 +304,14 @@ void MathPowStub::Generate(MacroAssembler* masm) {
__ CompareRoot(FieldOperand(exponent, HeapObject::kMapOffset),
Heap::kHeapNumberMapRootIndex);
__ j(not_equal, &call_runtime);
__ movsd(double_exponent, FieldOperand(exponent, HeapNumber::kValueOffset));
__ Movsd(double_exponent, FieldOperand(exponent, HeapNumber::kValueOffset));
} else if (exponent_type() == TAGGED) {
__ JumpIfNotSmi(exponent, &exponent_not_smi, Label::kNear);
__ SmiToInteger32(exponent, exponent);
__ jmp(&int_exponent);
__ bind(&exponent_not_smi);
__ movsd(double_exponent, FieldOperand(exponent, HeapNumber::kValueOffset));
__ Movsd(double_exponent, FieldOperand(exponent, HeapNumber::kValueOffset));
}
if (exponent_type() != INTEGER) {
@ -405,9 +405,9 @@ void MathPowStub::Generate(MacroAssembler* masm) {
__ fnclex(); // Clear flags to catch exceptions later.
// Transfer (B)ase and (E)xponent onto the FPU register stack.
__ subp(rsp, Immediate(kDoubleSize));
__ movsd(Operand(rsp, 0), double_exponent);
__ Movsd(Operand(rsp, 0), double_exponent);
__ fld_d(Operand(rsp, 0)); // E
__ movsd(Operand(rsp, 0), double_base);
__ Movsd(Operand(rsp, 0), double_base);
__ fld_d(Operand(rsp, 0)); // B, E
// Exponent is in st(1) and base is in st(0)
@ -430,7 +430,7 @@ void MathPowStub::Generate(MacroAssembler* masm) {
__ testb(rax, Immediate(0x5F)); // Check for all but precision exception.
__ j(not_zero, &fast_power_failed, Label::kNear);
__ fstp_d(Operand(rsp, 0));
__ movsd(double_result, Operand(rsp, 0));
__ Movsd(double_result, Operand(rsp, 0));
__ addp(rsp, Immediate(kDoubleSize));
__ jmp(&done);
@ -445,8 +445,8 @@ void MathPowStub::Generate(MacroAssembler* masm) {
const XMMRegister double_scratch2 = double_exponent;
// Back up exponent as we need to check if exponent is negative later.
__ movp(scratch, exponent); // Back up exponent.
__ movsd(double_scratch, double_base); // Back up base.
__ movsd(double_scratch2, double_result); // Load double_exponent with 1.
__ Movsd(double_scratch, double_base); // Back up base.
__ Movsd(double_scratch2, double_result); // Load double_exponent with 1.
// Get absolute value of exponent.
Label no_neg, while_true, while_false;
@ -460,7 +460,7 @@ void MathPowStub::Generate(MacroAssembler* masm) {
// Above condition means CF==0 && ZF==0. This means that the
// bit that has been shifted out is 0 and the result is not 0.
__ j(above, &while_true, Label::kNear);
__ movsd(double_result, double_scratch);
__ Movsd(double_result, double_scratch);
__ j(zero, &while_false, Label::kNear);
__ bind(&while_true);
@ -475,7 +475,7 @@ void MathPowStub::Generate(MacroAssembler* masm) {
__ testl(exponent, exponent);
__ j(greater, &done);
__ divsd(double_scratch2, double_result);
__ movsd(double_result, double_scratch2);
__ Movsd(double_result, double_scratch2);
// Test whether result is zero. Bail out to check for subnormal result.
// Due to subnormals, x^-y == (1/x)^y does not hold in all cases.
__ xorps(double_scratch2, double_scratch2);
@ -497,13 +497,13 @@ void MathPowStub::Generate(MacroAssembler* masm) {
// as heap number in rax.
__ bind(&done);
__ AllocateHeapNumber(rax, rcx, &call_runtime);
__ movsd(FieldOperand(rax, HeapNumber::kValueOffset), double_result);
__ Movsd(FieldOperand(rax, HeapNumber::kValueOffset), double_result);
__ IncrementCounter(counters->math_pow(), 1);
__ ret(2 * kPointerSize);
} else {
__ bind(&call_runtime);
// Move base to the correct argument register. Exponent is already in xmm1.
__ movsd(xmm0, double_base);
__ Movsd(xmm0, double_base);
DCHECK(double_exponent.is(xmm1));
{
AllowExternalCallThatCantCauseGC scope(masm);
@ -512,7 +512,7 @@ void MathPowStub::Generate(MacroAssembler* masm) {
ExternalReference::power_double_double_function(isolate()), 2);
}
// Return value is in xmm0.
__ movsd(double_result, xmm0);
__ Movsd(double_result, xmm0);
__ bind(&done);
__ IncrementCounter(counters->math_pow(), 1);
@ -1565,7 +1565,7 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
// greater-equal. Return -1 for them, so the comparison yields
// false for all conditions except not-equal.
__ Set(rax, EQUAL);
__ movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset));
__ Movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset));
__ ucomisd(xmm0, xmm0);
__ setcc(parity_even, rax);
// rax is 0 for equal non-NaN heapnumbers, 1 for NaNs.
@ -3434,7 +3434,7 @@ void CompareICStub::GenerateNumbers(MacroAssembler* masm) {
__ JumpIfSmi(rax, &right_smi, Label::kNear);
__ CompareMap(rax, isolate()->factory()->heap_number_map());
__ j(not_equal, &maybe_undefined1, Label::kNear);
__ movsd(xmm1, FieldOperand(rax, HeapNumber::kValueOffset));
__ Movsd(xmm1, FieldOperand(rax, HeapNumber::kValueOffset));
__ jmp(&left, Label::kNear);
__ bind(&right_smi);
__ SmiToInteger32(rcx, rax); // Can't clobber rax yet.
@ -3444,7 +3444,7 @@ void CompareICStub::GenerateNumbers(MacroAssembler* masm) {
__ JumpIfSmi(rdx, &left_smi, Label::kNear);
__ CompareMap(rdx, isolate()->factory()->heap_number_map());
__ j(not_equal, &maybe_undefined2, Label::kNear);
__ movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset));
__ Movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset));
__ jmp(&done);
__ bind(&left_smi);
__ SmiToInteger32(rcx, rdx); // Can't clobber rdx yet.

View File

@ -51,7 +51,7 @@ UnaryMathFunction CreateExpFunction() {
__ popq(rbx);
__ popq(rax);
__ movsd(xmm0, result);
__ Movsd(xmm0, result);
__ Ret();
CodeDesc desc;
@ -95,7 +95,7 @@ ModuloFunction CreateModuloFunction() {
byte* buffer = static_cast<byte*>(
base::OS::Allocate(Assembler::kMinimalBufferSize, &actual_size, true));
CHECK(buffer);
Assembler masm(NULL, buffer, static_cast<int>(actual_size));
MacroAssembler masm(NULL, buffer, static_cast<int>(actual_size));
// Generated code is put into a fixed, unmovable, buffer, and not into
// the V8 heap. We can't, and don't, refer to any relocatable addresses
// (e.g. the JavaScript nan-object).
@ -107,8 +107,8 @@ ModuloFunction CreateModuloFunction() {
// Compute x mod y.
// Load y and x (use argument backing store as temporary storage).
__ movsd(Operand(rsp, kRegisterSize * 2), xmm1);
__ movsd(Operand(rsp, kRegisterSize), xmm0);
__ Movsd(Operand(rsp, kRegisterSize * 2), xmm1);
__ Movsd(Operand(rsp, kRegisterSize), xmm0);
__ fld_d(Operand(rsp, kRegisterSize * 2));
__ fld_d(Operand(rsp, kRegisterSize));
@ -147,13 +147,13 @@ ModuloFunction CreateModuloFunction() {
int64_t kNaNValue = V8_INT64_C(0x7ff8000000000000);
__ movq(rcx, kNaNValue);
__ movq(Operand(rsp, kRegisterSize), rcx);
__ movsd(xmm0, Operand(rsp, kRegisterSize));
__ Movsd(xmm0, Operand(rsp, kRegisterSize));
__ jmp(&return_result);
// If result is valid, return that.
__ bind(&valid_result);
__ fstp_d(Operand(rsp, kRegisterSize));
__ movsd(xmm0, Operand(rsp, kRegisterSize));
__ Movsd(xmm0, Operand(rsp, kRegisterSize));
// Clean up FPU stack and exceptions and return xmm0
__ bind(&return_result);
@ -333,8 +333,7 @@ void ElementsTransitionGenerator::GenerateSmiToDouble(
__ JumpIfNotSmi(rbx, &convert_hole);
__ SmiToInteger32(rbx, rbx);
__ Cvtlsi2sd(xmm0, rbx);
__ movsd(FieldOperand(r14, r9, times_8, FixedDoubleArray::kHeaderSize),
xmm0);
__ Movsd(FieldOperand(r14, r9, times_8, FixedDoubleArray::kHeaderSize), xmm0);
__ jmp(&entry);
__ bind(&convert_hole);
@ -604,20 +603,20 @@ void MathExpGenerator::EmitMathExp(MacroAssembler* masm,
Label done;
__ Move(kScratchRegister, ExternalReference::math_exp_constants(0));
__ movsd(double_scratch, Operand(kScratchRegister, 0 * kDoubleSize));
__ Movsd(double_scratch, Operand(kScratchRegister, 0 * kDoubleSize));
__ xorpd(result, result);
__ ucomisd(double_scratch, input);
__ j(above_equal, &done);
__ ucomisd(input, Operand(kScratchRegister, 1 * kDoubleSize));
__ movsd(result, Operand(kScratchRegister, 2 * kDoubleSize));
__ Movsd(result, Operand(kScratchRegister, 2 * kDoubleSize));
__ j(above_equal, &done);
__ movsd(double_scratch, Operand(kScratchRegister, 3 * kDoubleSize));
__ movsd(result, Operand(kScratchRegister, 4 * kDoubleSize));
__ Movsd(double_scratch, Operand(kScratchRegister, 3 * kDoubleSize));
__ Movsd(result, Operand(kScratchRegister, 4 * kDoubleSize));
__ mulsd(double_scratch, input);
__ addsd(double_scratch, result);
__ movq(temp2, double_scratch);
__ subsd(double_scratch, result);
__ movsd(result, Operand(kScratchRegister, 6 * kDoubleSize));
__ Movsd(result, Operand(kScratchRegister, 6 * kDoubleSize));
__ leaq(temp1, Operand(temp2, 0x1ff800));
__ andq(temp2, Immediate(0x7ff));
__ shrq(temp1, Immediate(11));
@ -627,7 +626,7 @@ void MathExpGenerator::EmitMathExp(MacroAssembler* masm,
__ orq(temp1, Operand(kScratchRegister, temp2, times_8, 0));
__ Move(kScratchRegister, ExternalReference::math_exp_constants(0));
__ subsd(double_scratch, input);
__ movsd(input, double_scratch);
__ Movsd(input, double_scratch);
__ subsd(result, double_scratch);
__ mulsd(input, double_scratch);
__ mulsd(result, input);

View File

@ -147,7 +147,7 @@ void Deoptimizer::TableEntryGenerator::Generate() {
int code = config->GetAllocatableDoubleCode(i);
XMMRegister xmm_reg = XMMRegister::from_code(code);
int offset = code * kDoubleSize;
__ movsd(Operand(rsp, offset), xmm_reg);
__ Movsd(Operand(rsp, offset), xmm_reg);
}
// We push all registers onto the stack, even though we do not need
@ -280,7 +280,7 @@ void Deoptimizer::TableEntryGenerator::Generate() {
int code = config->GetAllocatableDoubleCode(i);
XMMRegister xmm_reg = XMMRegister::from_code(code);
int src_offset = code * kDoubleSize + double_regs_offset;
__ movsd(xmm_reg, Operand(rbx, src_offset));
__ Movsd(xmm_reg, Operand(rbx, src_offset));
}
// Push state, pc, and continuation from the last output frame.

View File

@ -988,6 +988,15 @@ int DisassemblerX64::AVXInstruction(byte* data) {
int mod, regop, rm, vvvv = vex_vreg();
get_modrm(*current, &mod, &regop, &rm);
switch (opcode) {
case 0x10:
AppendToBuffer("vmovsd %s,", NameOfXMMRegister(regop));
current += PrintRightXMMOperand(current);
break;
case 0x11:
AppendToBuffer("vmovsd ");
current += PrintRightXMMOperand(current);
AppendToBuffer(",%s", NameOfXMMRegister(regop));
break;
case 0x58:
AppendToBuffer("vaddsd %s,%s,", NameOfXMMRegister(regop),
NameOfXMMRegister(vvvv));
@ -1154,6 +1163,15 @@ int DisassemblerX64::AVXInstruction(byte* data) {
int mod, regop, rm, vvvv = vex_vreg();
get_modrm(*current, &mod, &regop, &rm);
switch (opcode) {
case 0x28:
AppendToBuffer("vmovapd %s,", NameOfXMMRegister(regop));
current += PrintRightXMMOperand(current);
break;
case 0x29:
AppendToBuffer("vmovapd ");
current += PrintRightXMMOperand(current);
AppendToBuffer(",%s", NameOfXMMRegister(regop));
break;
case 0x2e:
AppendToBuffer("vucomisd %s,", NameOfXMMRegister(regop));
current += PrintRightXMMOperand(current);

View File

@ -88,7 +88,7 @@ void LCodeGen::SaveCallerDoubles() {
BitVector* doubles = chunk()->allocated_double_registers();
BitVector::Iterator save_iterator(doubles);
while (!save_iterator.Done()) {
__ movsd(MemOperand(rsp, count * kDoubleSize),
__ Movsd(MemOperand(rsp, count * kDoubleSize),
XMMRegister::from_code(save_iterator.Current()));
save_iterator.Advance();
count++;
@ -104,7 +104,7 @@ void LCodeGen::RestoreCallerDoubles() {
BitVector::Iterator save_iterator(doubles);
int count = 0;
while (!save_iterator.Done()) {
__ movsd(XMMRegister::from_code(save_iterator.Current()),
__ Movsd(XMMRegister::from_code(save_iterator.Current()),
MemOperand(rsp, count * kDoubleSize));
save_iterator.Advance();
count++;
@ -1991,7 +1991,7 @@ void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
__ ucomisd(left_reg, left_reg); // NaN check.
__ j(parity_even, &return_left, Label::kNear);
__ bind(&return_right);
__ movaps(left_reg, right_reg);
__ Movapd(left_reg, right_reg);
__ bind(&return_left);
}
@ -2040,16 +2040,16 @@ void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
}
// Don't delete this mov. It may improve performance on some CPUs,
// when there is a (v)mulsd depending on the result
__ movaps(result, result);
__ Movapd(result, result);
break;
case Token::MOD: {
XMMRegister xmm_scratch = double_scratch0();
__ PrepareCallCFunction(2);
__ movaps(xmm_scratch, left);
__ Movapd(xmm_scratch, left);
DCHECK(right.is(xmm1));
__ CallCFunction(
ExternalReference::mod_two_doubles_operation(isolate()), 2);
__ movaps(result, xmm_scratch);
__ Movapd(result, xmm_scratch);
break;
}
default:
@ -2391,7 +2391,7 @@ void LCodeGen::DoCmpHoleAndBranch(LCmpHoleAndBranch* instr) {
EmitFalseBranch(instr, parity_odd);
__ subp(rsp, Immediate(kDoubleSize));
__ movsd(MemOperand(rsp, 0), input_reg);
__ Movsd(MemOperand(rsp, 0), input_reg);
__ addp(rsp, Immediate(kDoubleSize));
int offset = sizeof(kHoleNanUpper32);
@ -2869,7 +2869,7 @@ void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
if (instr->hydrogen()->representation().IsDouble()) {
DCHECK(access.IsInobject());
XMMRegister result = ToDoubleRegister(instr->result());
__ movsd(result, FieldOperand(object, offset));
__ Movsd(result, FieldOperand(object, offset));
return;
}
@ -3002,7 +3002,7 @@ void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
__ movss(result, operand);
__ cvtss2sd(result, result);
} else if (elements_kind == FLOAT64_ELEMENTS) {
__ movsd(ToDoubleRegister(instr->result()), operand);
__ Movsd(ToDoubleRegister(instr->result()), operand);
} else {
Register result(ToRegister(instr->result()));
switch (elements_kind) {
@ -3073,7 +3073,7 @@ void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) {
instr->hydrogen()->key()->representation(),
FAST_DOUBLE_ELEMENTS,
instr->base_offset());
__ movsd(result, double_load_operand);
__ Movsd(result, double_load_operand);
}
@ -3825,16 +3825,16 @@ void LCodeGen::DoMathLog(LMathLog* instr) {
ExternalReference ninf =
ExternalReference::address_of_negative_infinity();
Operand ninf_operand = masm()->ExternalOperand(ninf);
__ movsd(input_reg, ninf_operand);
__ Movsd(input_reg, ninf_operand);
__ jmp(&done, Label::kNear);
__ bind(&positive);
__ fldln2();
__ subp(rsp, Immediate(kDoubleSize));
__ movsd(Operand(rsp, 0), input_reg);
__ Movsd(Operand(rsp, 0), input_reg);
__ fld_d(Operand(rsp, 0));
__ fyl2x();
__ fstp_d(Operand(rsp, 0));
__ movsd(input_reg, Operand(rsp, 0));
__ Movsd(input_reg, Operand(rsp, 0));
__ addp(rsp, Immediate(kDoubleSize));
__ bind(&done);
}
@ -4025,7 +4025,7 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
DCHECK(!hinstr->has_transition());
DCHECK(!hinstr->NeedsWriteBarrier());
XMMRegister value = ToDoubleRegister(instr->value());
__ movsd(FieldOperand(object, offset), value);
__ Movsd(FieldOperand(object, offset), value);
return;
}
@ -4073,7 +4073,7 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
if (FLAG_unbox_double_fields && representation.IsDouble()) {
DCHECK(access.IsInobject());
XMMRegister value = ToDoubleRegister(instr->value());
__ movsd(operand, value);
__ Movsd(operand, value);
} else if (instr->value()->IsRegister()) {
Register value = ToRegister(instr->value());
@ -4246,7 +4246,7 @@ void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
__ cvtsd2ss(value, value);
__ movss(operand, value);
} else if (elements_kind == FLOAT64_ELEMENTS) {
__ movsd(operand, ToDoubleRegister(instr->value()));
__ Movsd(operand, ToDoubleRegister(instr->value()));
} else {
Register value(ToRegister(instr->value()));
switch (elements_kind) {
@ -4304,7 +4304,7 @@ void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
FAST_DOUBLE_ELEMENTS,
instr->base_offset());
__ movsd(double_store_operand, value);
__ Movsd(double_store_operand, value);
}
@ -4811,7 +4811,7 @@ void LCodeGen::DoDeferredNumberTagIU(LInstruction* instr,
// Done. Put the value in temp_xmm into the value of the allocated heap
// number.
__ bind(&done);
__ movsd(FieldOperand(reg, HeapNumber::kValueOffset), temp_xmm);
__ Movsd(FieldOperand(reg, HeapNumber::kValueOffset), temp_xmm);
}
@ -4838,7 +4838,7 @@ void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
__ jmp(deferred->entry());
}
__ bind(deferred->exit());
__ movsd(FieldOperand(reg, HeapNumber::kValueOffset), input_reg);
__ Movsd(FieldOperand(reg, HeapNumber::kValueOffset), input_reg);
}
@ -4914,7 +4914,7 @@ void LCodeGen::EmitNumberUntagD(LNumberUntagD* instr, Register input_reg,
// On x64 it is safe to load at heap number offset before evaluating the map
// check, since all heap objects are at least two words long.
__ movsd(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset));
__ Movsd(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset));
if (can_convert_undefined_to_nan) {
__ j(not_equal, &convert, Label::kNear);
@ -4993,7 +4993,7 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr, Label* done) {
__ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset),
Heap::kHeapNumberMapRootIndex);
DeoptimizeIf(not_equal, instr, Deoptimizer::kNotAHeapNumber);
__ movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
__ Movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
__ cvttsd2si(input_reg, xmm0);
__ Cvtlsi2sd(scratch, input_reg);
__ ucomisd(xmm0, scratch);
@ -5305,7 +5305,7 @@ void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
// Heap number
__ bind(&heap_number);
__ movsd(xmm_scratch, FieldOperand(input_reg, HeapNumber::kValueOffset));
__ Movsd(xmm_scratch, FieldOperand(input_reg, HeapNumber::kValueOffset));
__ ClampDoubleToUint8(xmm_scratch, temp_xmm_reg, input_reg);
__ jmp(&done, Label::kNear);

View File

@ -214,16 +214,16 @@ void LGapResolver::EmitMove(int index) {
__ movaps(cgen_->ToDoubleRegister(destination), src);
} else {
DCHECK(destination->IsDoubleStackSlot());
__ movsd(cgen_->ToOperand(destination), src);
__ Movsd(cgen_->ToOperand(destination), src);
}
} else if (source->IsDoubleStackSlot()) {
Operand src = cgen_->ToOperand(source);
if (destination->IsDoubleRegister()) {
__ movsd(cgen_->ToDoubleRegister(destination), src);
__ Movsd(cgen_->ToDoubleRegister(destination), src);
} else {
DCHECK(destination->IsDoubleStackSlot());
__ movsd(xmm0, src);
__ movsd(cgen_->ToOperand(destination), xmm0);
__ Movsd(xmm0, src);
__ Movsd(cgen_->ToOperand(destination), xmm0);
}
} else {
UNREACHABLE();
@ -261,9 +261,9 @@ void LGapResolver::EmitSwap(int index) {
// Swap two stack slots or two double stack slots.
Operand src = cgen_->ToOperand(source);
Operand dst = cgen_->ToOperand(destination);
__ movsd(xmm0, src);
__ Movsd(xmm0, src);
__ movp(kScratchRegister, dst);
__ movsd(dst, xmm0);
__ Movsd(dst, xmm0);
__ movp(src, kScratchRegister);
} else if (source->IsDoubleRegister() && destination->IsDoubleRegister()) {
@ -284,8 +284,8 @@ void LGapResolver::EmitSwap(int index) {
LOperand* other = source->IsDoubleRegister() ? destination : source;
DCHECK(other->IsDoubleStackSlot());
Operand other_operand = cgen_->ToOperand(other);
__ movsd(xmm0, other_operand);
__ movsd(other_operand, reg);
__ Movsd(xmm0, other_operand);
__ Movsd(other_operand, reg);
__ movaps(reg, xmm0);
} else {

View File

@ -761,7 +761,7 @@ void MacroAssembler::PushCallerSaved(SaveFPRegsMode fp_mode,
subp(rsp, Immediate(kDoubleSize * XMMRegister::kMaxNumRegisters));
for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) {
XMMRegister reg = XMMRegister::from_code(i);
movsd(Operand(rsp, i * kDoubleSize), reg);
Movsd(Operand(rsp, i * kDoubleSize), reg);
}
}
}
@ -774,7 +774,7 @@ void MacroAssembler::PopCallerSaved(SaveFPRegsMode fp_mode,
if (fp_mode == kSaveFPRegs) {
for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) {
XMMRegister reg = XMMRegister::from_code(i);
movsd(reg, Operand(rsp, i * kDoubleSize));
Movsd(reg, Operand(rsp, i * kDoubleSize));
}
addp(rsp, Immediate(kDoubleSize * XMMRegister::kMaxNumRegisters));
}
@ -2437,6 +2437,46 @@ void MacroAssembler::Move(XMMRegister dst, uint64_t src) {
}
void MacroAssembler::Movapd(XMMRegister dst, XMMRegister src) {
if (CpuFeatures::IsSupported(AVX)) {
CpuFeatureScope scope(this, AVX);
vmovapd(dst, src);
} else {
movapd(dst, src);
}
}
void MacroAssembler::Movsd(XMMRegister dst, XMMRegister src) {
if (CpuFeatures::IsSupported(AVX)) {
CpuFeatureScope scope(this, AVX);
vmovsd(dst, src);
} else {
movsd(dst, src);
}
}
void MacroAssembler::Movsd(XMMRegister dst, const Operand& src) {
if (CpuFeatures::IsSupported(AVX)) {
CpuFeatureScope scope(this, AVX);
vmovsd(dst, src);
} else {
movsd(dst, src);
}
}
void MacroAssembler::Movsd(const Operand& dst, XMMRegister src) {
if (CpuFeatures::IsSupported(AVX)) {
CpuFeatureScope scope(this, AVX);
vmovsd(dst, src);
} else {
movsd(dst, src);
}
}
void MacroAssembler::Cmp(Register dst, Handle<Object> source) {
AllowDeferredHandleDereference smi_check;
if (source->IsSmi()) {
@ -3045,7 +3085,7 @@ void MacroAssembler::StoreNumberToDoubleElements(
SmiToInteger32(kScratchRegister, maybe_number);
Cvtlsi2sd(xmm_scratch, kScratchRegister);
bind(&done);
movsd(FieldOperand(elements, index, times_8,
Movsd(FieldOperand(elements, index, times_8,
FixedDoubleArray::kHeaderSize - elements_offset),
xmm_scratch);
}
@ -3125,7 +3165,7 @@ void MacroAssembler::SlowTruncateToI(Register result_reg,
void MacroAssembler::TruncateHeapNumberToI(Register result_reg,
Register input_reg) {
Label done;
movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
Movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
cvttsd2siq(result_reg, xmm0);
cmpq(result_reg, Immediate(1));
j(no_overflow, &done, Label::kNear);
@ -3133,7 +3173,7 @@ void MacroAssembler::TruncateHeapNumberToI(Register result_reg,
// Slow case.
if (input_reg.is(result_reg)) {
subp(rsp, Immediate(kDoubleSize));
movsd(MemOperand(rsp, 0), xmm0);
Movsd(MemOperand(rsp, 0), xmm0);
SlowTruncateToI(result_reg, rsp, 0);
addp(rsp, Immediate(kDoubleSize));
} else {
@ -3154,7 +3194,7 @@ void MacroAssembler::TruncateDoubleToI(Register result_reg,
j(no_overflow, &done, Label::kNear);
subp(rsp, Immediate(kDoubleSize));
movsd(MemOperand(rsp, 0), input_reg);
Movsd(MemOperand(rsp, 0), input_reg);
SlowTruncateToI(result_reg, rsp, 0);
addp(rsp, Immediate(kDoubleSize));
@ -3720,7 +3760,7 @@ void MacroAssembler::EnterExitFrameEpilogue(int arg_stack_space,
for (int i = 0; i < config->num_allocatable_double_registers(); ++i) {
DoubleRegister reg =
DoubleRegister::from_code(config->GetAllocatableDoubleCode(i));
movsd(Operand(rbp, offset - ((i + 1) * kDoubleSize)), reg);
Movsd(Operand(rbp, offset - ((i + 1) * kDoubleSize)), reg);
}
} else if (arg_stack_space > 0) {
subp(rsp, Immediate(arg_stack_space * kRegisterSize));
@ -3766,7 +3806,7 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles, bool pop_arguments) {
for (int i = 0; i < config->num_allocatable_double_registers(); ++i) {
DoubleRegister reg =
DoubleRegister::from_code(config->GetAllocatableDoubleCode(i));
movsd(reg, Operand(rbp, offset - ((i + 1) * kDoubleSize)));
Movsd(reg, Operand(rbp, offset - ((i + 1) * kDoubleSize)));
}
}

View File

@ -894,6 +894,11 @@ class MacroAssembler: public Assembler {
void Move(XMMRegister dst, float src) { Move(dst, bit_cast<uint32_t>(src)); }
void Move(XMMRegister dst, double src) { Move(dst, bit_cast<uint64_t>(src)); }
void Movapd(XMMRegister dst, XMMRegister src);
void Movsd(XMMRegister dst, XMMRegister src);
void Movsd(XMMRegister dst, const Operand& src);
void Movsd(const Operand& dst, XMMRegister src);
// Control Flow
void Jump(Address destination, RelocInfo::Mode rmode);
void Jump(ExternalReference ext);

View File

@ -1353,7 +1353,14 @@ TEST(AssemblerX64AVX_sd) {
// arguments in xmm0, xmm1 and xmm2
__ movl(rax, Immediate(0));
__ vmaxsd(xmm3, xmm0, xmm1);
__ vmaxsd(xmm4, xmm0, xmm1);
__ subq(rsp, Immediate(kDoubleSize * 2)); // For memory operand
__ vmovsd(Operand(rsp, kDoubleSize), xmm4);
__ vmovsd(xmm5, Operand(rsp, kDoubleSize));
__ vmovsd(xmm6, xmm5);
__ vmovapd(xmm3, xmm6);
__ addq(rsp, Immediate(kDoubleSize * 2));
__ vucomisd(xmm3, xmm1);
__ j(parity_even, &exit);
__ j(not_equal, &exit);

View File

@ -88,7 +88,7 @@ ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate,
// Put the double argument into the designated double argument slot.
__ subq(rsp, Immediate(kDoubleSize));
__ movsd(MemOperand(rsp, 0), xmm0);
__ Movsd(MemOperand(rsp, 0), xmm0);
// Call through to the actual stub
__ Call(start, RelocInfo::EXTERNAL_REFERENCE);

View File

@ -511,6 +511,11 @@ TEST(DisasmX64) {
__ vucomiss(xmm9, xmm1);
__ vucomiss(xmm8, Operand(rbx, rdx, times_2, 10981));
__ vmovapd(xmm7, xmm0);
__ vmovsd(xmm6, xmm2);
__ vmovsd(xmm9, Operand(rbx, rcx, times_4, 10000));
__ vmovsd(Operand(rbx, rcx, times_4, 10000), xmm0);
__ vaddsd(xmm0, xmm1, xmm2);
__ vaddsd(xmm0, xmm1, Operand(rbx, rcx, times_4, 10000));
__ vmulsd(xmm0, xmm1, xmm2);