diff options
Diffstat (limited to 'deps/v8/src/compiler/x64/code-generator-x64.cc')
-rw-r--r-- | deps/v8/src/compiler/x64/code-generator-x64.cc | 473 |
1 files changed, 206 insertions, 267 deletions
diff --git a/deps/v8/src/compiler/x64/code-generator-x64.cc b/deps/v8/src/compiler/x64/code-generator-x64.cc index fdf63855d5..be9af48d4b 100644 --- a/deps/v8/src/compiler/x64/code-generator-x64.cc +++ b/deps/v8/src/compiler/x64/code-generator-x64.cc @@ -19,130 +19,29 @@ namespace compiler { #define __ masm()-> -// TODO(turbofan): Cleanup these hacks. -enum Immediate64Type { kImm64Value, kImm64Handle, kImm64Reference }; - - -struct Immediate64 { - uint64_t value; - Handle<Object> handle; - ExternalReference reference; - Immediate64Type type; -}; - - -enum RegisterOrOperandType { kRegister, kDoubleRegister, kOperand }; - - -struct RegisterOrOperand { - RegisterOrOperand() : operand(no_reg, 0) {} - Register reg; - DoubleRegister double_reg; - Operand operand; - RegisterOrOperandType type; -}; - - // Adds X64 specific methods for decoding operands. class X64OperandConverter : public InstructionOperandConverter { public: X64OperandConverter(CodeGenerator* gen, Instruction* instr) : InstructionOperandConverter(gen, instr) {} - RegisterOrOperand InputRegisterOrOperand(int index) { - return ToRegisterOrOperand(instr_->InputAt(index)); - } - Immediate InputImmediate(int index) { return ToImmediate(instr_->InputAt(index)); } - RegisterOrOperand OutputRegisterOrOperand() { - return ToRegisterOrOperand(instr_->Output()); - } + Operand InputOperand(int index) { return ToOperand(instr_->InputAt(index)); } - Immediate64 InputImmediate64(int index) { - return ToImmediate64(instr_->InputAt(index)); - } - - Immediate64 ToImmediate64(InstructionOperand* operand) { - Constant constant = ToConstant(operand); - Immediate64 immediate; - immediate.value = 0xbeefdeaddeefbeed; - immediate.type = kImm64Value; - switch (constant.type()) { - case Constant::kInt32: - case Constant::kInt64: - immediate.value = constant.ToInt64(); - return immediate; - case Constant::kFloat32: - immediate.type = kImm64Handle; - immediate.handle = - isolate()->factory()->NewNumber(constant.ToFloat32(), TENURED); - return immediate; - case Constant::kFloat64: - immediate.type = kImm64Handle; - immediate.handle = - isolate()->factory()->NewNumber(constant.ToFloat64(), TENURED); - return immediate; - case Constant::kExternalReference: - immediate.type = kImm64Reference; - immediate.reference = constant.ToExternalReference(); - return immediate; - case Constant::kHeapObject: - immediate.type = kImm64Handle; - immediate.handle = constant.ToHeapObject(); - return immediate; - } - UNREACHABLE(); - return immediate; - } + Operand OutputOperand() { return ToOperand(instr_->Output()); } Immediate ToImmediate(InstructionOperand* operand) { - Constant constant = ToConstant(operand); - switch (constant.type()) { - case Constant::kInt32: - return Immediate(constant.ToInt32()); - case Constant::kInt64: - case Constant::kFloat32: - case Constant::kFloat64: - case Constant::kExternalReference: - case Constant::kHeapObject: - break; - } - UNREACHABLE(); - return Immediate(-1); + return Immediate(ToConstant(operand).ToInt32()); } Operand ToOperand(InstructionOperand* op, int extra = 0) { - RegisterOrOperand result = ToRegisterOrOperand(op, extra); - DCHECK_EQ(kOperand, result.type); - return result.operand; - } - - RegisterOrOperand ToRegisterOrOperand(InstructionOperand* op, int extra = 0) { - RegisterOrOperand result; - if (op->IsRegister()) { - DCHECK(extra == 0); - result.type = kRegister; - result.reg = ToRegister(op); - return result; - } else if (op->IsDoubleRegister()) { - DCHECK(extra == 0); - DCHECK(extra == 0); - result.type = kDoubleRegister; - result.double_reg = ToDoubleRegister(op); - return result; - } - DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot()); - - result.type = kOperand; // The linkage computes where all spill slots are located. FrameOffset offset = linkage()->GetFrameOffset(op->index(), frame(), extra); - result.operand = - Operand(offset.from_stack_pointer() ? rsp : rbp, offset.offset()); - return result; + return Operand(offset.from_stack_pointer() ? rsp : rbp, offset.offset()); } static int NextOffset(int* offset) { @@ -232,33 +131,79 @@ static bool HasImmediateInput(Instruction* instr, int index) { } -#define ASSEMBLE_BINOP(asm_instr) \ - do { \ - if (HasImmediateInput(instr, 1)) { \ - RegisterOrOperand input = i.InputRegisterOrOperand(0); \ - if (input.type == kRegister) { \ - __ asm_instr(input.reg, i.InputImmediate(1)); \ - } else { \ - __ asm_instr(input.operand, i.InputImmediate(1)); \ - } \ - } else { \ - RegisterOrOperand input = i.InputRegisterOrOperand(1); \ - if (input.type == kRegister) { \ - __ asm_instr(i.InputRegister(0), input.reg); \ - } else { \ - __ asm_instr(i.InputRegister(0), input.operand); \ - } \ - } \ +#define ASSEMBLE_UNOP(asm_instr) \ + do { \ + if (instr->Output()->IsRegister()) { \ + __ asm_instr(i.OutputRegister()); \ + } else { \ + __ asm_instr(i.OutputOperand()); \ + } \ + } while (0) + + +#define ASSEMBLE_BINOP(asm_instr) \ + do { \ + if (HasImmediateInput(instr, 1)) { \ + if (instr->InputAt(0)->IsRegister()) { \ + __ asm_instr(i.InputRegister(0), i.InputImmediate(1)); \ + } else { \ + __ asm_instr(i.InputOperand(0), i.InputImmediate(1)); \ + } \ + } else { \ + if (instr->InputAt(1)->IsRegister()) { \ + __ asm_instr(i.InputRegister(0), i.InputRegister(1)); \ + } else { \ + __ asm_instr(i.InputRegister(0), i.InputOperand(1)); \ + } \ + } \ + } while (0) + + +#define ASSEMBLE_MULT(asm_instr) \ + do { \ + if (HasImmediateInput(instr, 1)) { \ + if (instr->InputAt(0)->IsRegister()) { \ + __ asm_instr(i.OutputRegister(), i.InputRegister(0), \ + i.InputImmediate(1)); \ + } else { \ + __ asm_instr(i.OutputRegister(), i.InputOperand(0), \ + i.InputImmediate(1)); \ + } \ + } else { \ + if (instr->InputAt(1)->IsRegister()) { \ + __ asm_instr(i.OutputRegister(), i.InputRegister(1)); \ + } else { \ + __ asm_instr(i.OutputRegister(), i.InputOperand(1)); \ + } \ + } \ } while (0) -#define ASSEMBLE_SHIFT(asm_instr, width) \ - do { \ - if (HasImmediateInput(instr, 1)) { \ - __ asm_instr(i.OutputRegister(), Immediate(i.InputInt##width(1))); \ - } else { \ - __ asm_instr##_cl(i.OutputRegister()); \ - } \ +#define ASSEMBLE_SHIFT(asm_instr, width) \ + do { \ + if (HasImmediateInput(instr, 1)) { \ + if (instr->Output()->IsRegister()) { \ + __ asm_instr(i.OutputRegister(), Immediate(i.InputInt##width(1))); \ + } else { \ + __ asm_instr(i.OutputOperand(), Immediate(i.InputInt##width(1))); \ + } \ + } else { \ + if (instr->Output()->IsRegister()) { \ + __ asm_instr##_cl(i.OutputRegister()); \ + } else { \ + __ asm_instr##_cl(i.OutputOperand()); \ + } \ + } \ + } while (0) + + +#define ASSEMBLE_DOUBLE_BINOP(asm_instr) \ + do { \ + if (instr->InputAt(1)->IsDoubleRegister()) { \ + __ asm_instr(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); \ + } else { \ + __ asm_instr(i.InputDoubleRegister(0), i.InputOperand(1)); \ + } \ } while (0) @@ -293,7 +238,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { break; } case kArchJmp: - __ jmp(code_->GetLabel(i.InputBlock(0))); + __ jmp(GetLabel(i.InputRpo(0))); break; case kArchNop: // don't emit code for nops. @@ -301,6 +246,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { case kArchRet: AssembleReturn(); break; + case kArchStackPointer: + __ movq(i.OutputRegister(), rsp); + break; case kArchTruncateDoubleToI: __ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0)); break; @@ -335,37 +283,23 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { ASSEMBLE_BINOP(testq); break; case kX64Imul32: - if (HasImmediateInput(instr, 1)) { - RegisterOrOperand input = i.InputRegisterOrOperand(0); - if (input.type == kRegister) { - __ imull(i.OutputRegister(), input.reg, i.InputImmediate(1)); - } else { - __ imull(i.OutputRegister(), input.operand, i.InputImmediate(1)); - } + ASSEMBLE_MULT(imull); + break; + case kX64Imul: + ASSEMBLE_MULT(imulq); + break; + case kX64ImulHigh32: + if (instr->InputAt(1)->IsRegister()) { + __ imull(i.InputRegister(1)); } else { - RegisterOrOperand input = i.InputRegisterOrOperand(1); - if (input.type == kRegister) { - __ imull(i.OutputRegister(), input.reg); - } else { - __ imull(i.OutputRegister(), input.operand); - } + __ imull(i.InputOperand(1)); } break; - case kX64Imul: - if (HasImmediateInput(instr, 1)) { - RegisterOrOperand input = i.InputRegisterOrOperand(0); - if (input.type == kRegister) { - __ imulq(i.OutputRegister(), input.reg, i.InputImmediate(1)); - } else { - __ imulq(i.OutputRegister(), input.operand, i.InputImmediate(1)); - } + case kX64UmulHigh32: + if (instr->InputAt(1)->IsRegister()) { + __ mull(i.InputRegister(1)); } else { - RegisterOrOperand input = i.InputRegisterOrOperand(1); - if (input.type == kRegister) { - __ imulq(i.OutputRegister(), input.reg); - } else { - __ imulq(i.OutputRegister(), input.operand); - } + __ mull(i.InputOperand(1)); } break; case kX64Idiv32: @@ -384,42 +318,18 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { __ xorq(rdx, rdx); __ divq(i.InputRegister(1)); break; - case kX64Not: { - RegisterOrOperand output = i.OutputRegisterOrOperand(); - if (output.type == kRegister) { - __ notq(output.reg); - } else { - __ notq(output.operand); - } + case kX64Not: + ASSEMBLE_UNOP(notq); break; - } - case kX64Not32: { - RegisterOrOperand output = i.OutputRegisterOrOperand(); - if (output.type == kRegister) { - __ notl(output.reg); - } else { - __ notl(output.operand); - } + case kX64Not32: + ASSEMBLE_UNOP(notl); break; - } - case kX64Neg: { - RegisterOrOperand output = i.OutputRegisterOrOperand(); - if (output.type == kRegister) { - __ negq(output.reg); - } else { - __ negq(output.operand); - } + case kX64Neg: + ASSEMBLE_UNOP(negq); break; - } - case kX64Neg32: { - RegisterOrOperand output = i.OutputRegisterOrOperand(); - if (output.type == kRegister) { - __ negl(output.reg); - } else { - __ negl(output.operand); - } + case kX64Neg32: + ASSEMBLE_UNOP(negl); break; - } case kX64Or32: ASSEMBLE_BINOP(orl); break; @@ -456,26 +366,20 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { case kX64Ror: ASSEMBLE_SHIFT(rorq, 6); break; - case kSSEFloat64Cmp: { - RegisterOrOperand input = i.InputRegisterOrOperand(1); - if (input.type == kDoubleRegister) { - __ ucomisd(i.InputDoubleRegister(0), input.double_reg); - } else { - __ ucomisd(i.InputDoubleRegister(0), input.operand); - } + case kSSEFloat64Cmp: + ASSEMBLE_DOUBLE_BINOP(ucomisd); break; - } case kSSEFloat64Add: - __ addsd(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); + ASSEMBLE_DOUBLE_BINOP(addsd); break; case kSSEFloat64Sub: - __ subsd(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); + ASSEMBLE_DOUBLE_BINOP(subsd); break; case kSSEFloat64Mul: - __ mulsd(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); + ASSEMBLE_DOUBLE_BINOP(mulsd); break; case kSSEFloat64Div: - __ divsd(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); + ASSEMBLE_DOUBLE_BINOP(divsd); break; case kSSEFloat64Mod: { __ subq(rsp, Immediate(kDoubleSize)); @@ -508,56 +412,76 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { __ addq(rsp, Immediate(kDoubleSize)); break; } - case kSSEFloat64Sqrt: { - RegisterOrOperand input = i.InputRegisterOrOperand(0); - if (input.type == kDoubleRegister) { - __ sqrtsd(i.OutputDoubleRegister(), input.double_reg); + case kSSEFloat64Sqrt: + if (instr->InputAt(0)->IsDoubleRegister()) { + __ sqrtsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); } else { - __ sqrtsd(i.OutputDoubleRegister(), input.operand); + __ sqrtsd(i.OutputDoubleRegister(), i.InputOperand(0)); } break; + case kSSEFloat64Floor: { + CpuFeatureScope sse_scope(masm(), SSE4_1); + __ roundsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0), + v8::internal::Assembler::kRoundDown); + break; + } + case kSSEFloat64Ceil: { + CpuFeatureScope sse_scope(masm(), SSE4_1); + __ roundsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0), + v8::internal::Assembler::kRoundUp); + break; + } + case kSSEFloat64RoundTruncate: { + CpuFeatureScope sse_scope(masm(), SSE4_1); + __ roundsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0), + v8::internal::Assembler::kRoundToZero); + break; } case kSSECvtss2sd: - __ cvtss2sd(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); + if (instr->InputAt(0)->IsDoubleRegister()) { + __ cvtss2sd(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); + } else { + __ cvtss2sd(i.OutputDoubleRegister(), i.InputOperand(0)); + } break; case kSSECvtsd2ss: - __ cvtsd2ss(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); + if (instr->InputAt(0)->IsDoubleRegister()) { + __ cvtsd2ss(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); + } else { + __ cvtsd2ss(i.OutputDoubleRegister(), i.InputOperand(0)); + } break; - case kSSEFloat64ToInt32: { - RegisterOrOperand input = i.InputRegisterOrOperand(0); - if (input.type == kDoubleRegister) { - __ cvttsd2si(i.OutputRegister(), input.double_reg); + case kSSEFloat64ToInt32: + if (instr->InputAt(0)->IsDoubleRegister()) { + __ cvttsd2si(i.OutputRegister(), i.InputDoubleRegister(0)); } else { - __ cvttsd2si(i.OutputRegister(), input.operand); + __ cvttsd2si(i.OutputRegister(), i.InputOperand(0)); } break; - } case kSSEFloat64ToUint32: { - RegisterOrOperand input = i.InputRegisterOrOperand(0); - if (input.type == kDoubleRegister) { - __ cvttsd2siq(i.OutputRegister(), input.double_reg); + if (instr->InputAt(0)->IsDoubleRegister()) { + __ cvttsd2siq(i.OutputRegister(), i.InputDoubleRegister(0)); } else { - __ cvttsd2siq(i.OutputRegister(), input.operand); + __ cvttsd2siq(i.OutputRegister(), i.InputOperand(0)); } - __ andl(i.OutputRegister(), i.OutputRegister()); // clear upper bits. - // TODO(turbofan): generated code should not look at the upper 32 bits - // of the result, but those bits could escape to the outside world. + __ AssertZeroExtended(i.OutputRegister()); break; } - case kSSEInt32ToFloat64: { - RegisterOrOperand input = i.InputRegisterOrOperand(0); - if (input.type == kRegister) { - __ cvtlsi2sd(i.OutputDoubleRegister(), input.reg); + case kSSEInt32ToFloat64: + if (instr->InputAt(0)->IsRegister()) { + __ cvtlsi2sd(i.OutputDoubleRegister(), i.InputRegister(0)); } else { - __ cvtlsi2sd(i.OutputDoubleRegister(), input.operand); + __ cvtlsi2sd(i.OutputDoubleRegister(), i.InputOperand(0)); } break; - } - case kSSEUint32ToFloat64: { - // TODO(turbofan): X64 SSE cvtqsi2sd should support operands. - __ cvtqsi2sd(i.OutputDoubleRegister(), i.InputRegister(0)); + case kSSEUint32ToFloat64: + if (instr->InputAt(0)->IsRegister()) { + __ movl(kScratchRegister, i.InputRegister(0)); + } else { + __ movl(kScratchRegister, i.InputOperand(0)); + } + __ cvtqsi2sd(i.OutputDoubleRegister(), kScratchRegister); break; - } case kX64Movsxbl: __ movsxbl(i.OutputRegister(), i.MemoryOperand()); break; @@ -593,11 +517,10 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { case kX64Movl: if (instr->HasOutput()) { if (instr->addressing_mode() == kMode_None) { - RegisterOrOperand input = i.InputRegisterOrOperand(0); - if (input.type == kRegister) { - __ movl(i.OutputRegister(), input.reg); + if (instr->InputAt(0)->IsRegister()) { + __ movl(i.OutputRegister(), i.InputRegister(0)); } else { - __ movl(i.OutputRegister(), input.operand); + __ movl(i.OutputRegister(), i.InputOperand(0)); } } else { __ movl(i.OutputRegister(), i.MemoryOperand()); @@ -613,11 +536,10 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { } break; case kX64Movsxlq: { - RegisterOrOperand input = i.InputRegisterOrOperand(0); - if (input.type == kRegister) { - __ movsxlq(i.OutputRegister(), input.reg); + if (instr->InputAt(0)->IsRegister()) { + __ movsxlq(i.OutputRegister(), i.InputRegister(0)); } else { - __ movsxlq(i.OutputRegister(), input.operand); + __ movsxlq(i.OutputRegister(), i.InputOperand(0)); } break; } @@ -652,15 +574,20 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { __ movsd(operand, i.InputDoubleRegister(index)); } break; + case kX64Lea32: + __ leal(i.OutputRegister(), i.MemoryOperand()); + break; + case kX64Lea: + __ leaq(i.OutputRegister(), i.MemoryOperand()); + break; case kX64Push: if (HasImmediateInput(instr, 0)) { __ pushq(i.InputImmediate(0)); } else { - RegisterOrOperand input = i.InputRegisterOrOperand(0); - if (input.type == kRegister) { - __ pushq(input.reg); + if (instr->InputAt(0)->IsRegister()) { + __ pushq(i.InputRegister(0)); } else { - __ pushq(input.operand); + __ pushq(i.InputOperand(0)); } } break; @@ -671,9 +598,8 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { __ movsxlq(index, index); __ movq(Operand(object, index, times_1, 0), value); __ leaq(index, Operand(object, index, times_1, 0)); - SaveFPRegsMode mode = code_->frame()->DidAllocateDoubleRegisters() - ? kSaveFPRegs - : kDontSaveFPRegs; + SaveFPRegsMode mode = + frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs; __ RecordWrite(object, index, value, mode); break; } @@ -689,11 +615,13 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr, // Emit a branch. The true and false targets are always the last two inputs // to the instruction. - BasicBlock* tblock = i.InputBlock(static_cast<int>(instr->InputCount()) - 2); - BasicBlock* fblock = i.InputBlock(static_cast<int>(instr->InputCount()) - 1); + BasicBlock::RpoNumber tblock = + i.InputRpo(static_cast<int>(instr->InputCount()) - 2); + BasicBlock::RpoNumber fblock = + i.InputRpo(static_cast<int>(instr->InputCount()) - 1); bool fallthru = IsNextInAssemblyOrder(fblock); - Label* tlabel = code()->GetLabel(tblock); - Label* flabel = fallthru ? &done : code()->GetLabel(fblock); + Label* tlabel = GetLabel(tblock); + Label* flabel = fallthru ? &done : GetLabel(fblock); Label::Distance flabel_distance = fallthru ? Label::kNear : Label::kFar; switch (condition) { case kUnorderedEqual: @@ -765,7 +693,7 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr, // Materialize a full 64-bit 1 or 0 value. The result register is always the // last output of the instruction. Label check; - DCHECK_NE(0, instr->OutputCount()); + DCHECK_NE(0, static_cast<int>(instr->OutputCount())); Register reg = i.OutputRegister(static_cast<int>(instr->OutputCount() - 1)); Condition cc = no_condition; switch (condition) { @@ -867,7 +795,7 @@ void CodeGenerator::AssemblePrologue() { frame()->SetRegisterSaveAreaSize(register_save_area_size); } } else if (descriptor->IsJSFunctionCall()) { - CompilationInfo* info = linkage()->info(); + CompilationInfo* info = this->info(); __ Prologue(info->IsCodePreAgingActive()); frame()->SetRegisterSaveAreaSize( StandardFrameConstants::kFixedFrameSizeFromFp); @@ -968,16 +896,27 @@ void CodeGenerator::AssembleMove(InstructionOperand* source, if (destination->IsRegister() || destination->IsStackSlot()) { Register dst = destination->IsRegister() ? g.ToRegister(destination) : kScratchRegister; - Immediate64 imm = g.ToImmediate64(constant_source); - switch (imm.type) { - case kImm64Value: - __ Set(dst, imm.value); + switch (src.type()) { + case Constant::kInt32: + // TODO(dcarney): don't need scratch in this case. + __ Set(dst, src.ToInt32()); + break; + case Constant::kInt64: + __ Set(dst, src.ToInt64()); + break; + case Constant::kFloat32: + __ Move(dst, + isolate()->factory()->NewNumber(src.ToFloat32(), TENURED)); + break; + case Constant::kFloat64: + __ Move(dst, + isolate()->factory()->NewNumber(src.ToFloat64(), TENURED)); break; - case kImm64Reference: - __ Move(dst, imm.reference); + case Constant::kExternalReference: + __ Move(dst, src.ToExternalReference()); break; - case kImm64Handle: - __ Move(dst, imm.handle); + case Constant::kHeapObject: + __ Move(dst, src.ToHeapObject()); break; } if (destination->IsStackSlot()) { @@ -985,22 +924,22 @@ void CodeGenerator::AssembleMove(InstructionOperand* source, } } else if (src.type() == Constant::kFloat32) { // TODO(turbofan): Can we do better here? - __ movl(kScratchRegister, Immediate(bit_cast<int32_t>(src.ToFloat32()))); + uint32_t src_const = bit_cast<uint32_t>(src.ToFloat32()); if (destination->IsDoubleRegister()) { - XMMRegister dst = g.ToDoubleRegister(destination); - __ movq(dst, kScratchRegister); + __ Move(g.ToDoubleRegister(destination), src_const); } else { DCHECK(destination->IsDoubleStackSlot()); Operand dst = g.ToOperand(destination); - __ movl(dst, kScratchRegister); + __ movl(dst, Immediate(src_const)); } } else { DCHECK_EQ(Constant::kFloat64, src.type()); - __ movq(kScratchRegister, bit_cast<int64_t>(src.ToFloat64())); + uint64_t src_const = bit_cast<uint64_t>(src.ToFloat64()); if (destination->IsDoubleRegister()) { - __ movq(g.ToDoubleRegister(destination), kScratchRegister); + __ Move(g.ToDoubleRegister(destination), src_const); } else { DCHECK(destination->IsDoubleStackSlot()); + __ movq(kScratchRegister, src_const); __ movq(g.ToOperand(destination), kScratchRegister); } } @@ -1082,7 +1021,7 @@ void CodeGenerator::AddNopForSmiCodeInlining() { __ nop(); } void CodeGenerator::EnsureSpaceForLazyDeopt() { int space_needed = Deoptimizer::patch_size(); - if (!linkage()->info()->IsStub()) { + if (!info()->IsStub()) { // Ensure that we have enough space after the previous lazy-bailout // instruction for patching the code here. int current_pc = masm()->pc_offset(); |