| Index: src/x64/macro-assembler-x64.cc
|
| diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc
|
| index a690bd525613dde095e6d0c90cf2579b3d2f5963..2fc825fc0bbf2402c4158590baaaa7665b1277cf 100644
|
| --- a/src/x64/macro-assembler-x64.cc
|
| +++ b/src/x64/macro-assembler-x64.cc
|
| @@ -375,6 +375,16 @@ void MacroAssembler::CallRuntime(Runtime::FunctionId id, int num_arguments) {
|
| }
|
|
|
|
|
| +void MacroAssembler::CallRuntimeSaveDoubles(Runtime::FunctionId id) {
|
| + Runtime::Function* function = Runtime::FunctionForId(id);
|
| + Set(rax, function->nargs);
|
| + movq(rbx, ExternalReference(function));
|
| + CEntryStub ces(1);
|
| + ces.SaveDoubles();
|
| + CallStub(&ces);
|
| +}
|
| +
|
| +
|
| MaybeObject* MacroAssembler::TryCallRuntime(Runtime::FunctionId id,
|
| int num_arguments) {
|
| return TryCallRuntime(Runtime::FunctionForId(id), num_arguments);
|
| @@ -967,6 +977,27 @@ Condition MacroAssembler::CheckUInteger32ValidSmiValue(Register src) {
|
| }
|
|
|
|
|
| +void MacroAssembler::CheckSmiToIndicator(Register dst, Register src) {
|
| + if (dst.is(src)) {
|
| + andl(dst, Immediate(kSmiTagMask));
|
| + } else {
|
| + movl(dst, Immediate(kSmiTagMask));
|
| + andl(dst, src);
|
| + }
|
| +}
|
| +
|
| +
|
| +void MacroAssembler::CheckSmiToIndicator(Register dst, const Operand& src) {
|
| + if (!(src.AddressUsesRegister(dst))) {
|
| + movl(dst, Immediate(kSmiTagMask));
|
| + andl(dst, src);
|
| + } else {
|
| + movl(dst, src);
|
| + andl(dst, Immediate(kSmiTagMask));
|
| + }
|
| +}
|
| +
|
| +
|
| void MacroAssembler::SmiAddConstant(Register dst, Register src, Smi* constant) {
|
| if (constant->value() == 0) {
|
| if (!dst.is(src)) {
|
| @@ -1427,6 +1458,34 @@ void MacroAssembler::Popad() {
|
| }
|
|
|
|
|
| +void MacroAssembler::Dropad() {
|
| + const int kRegistersPushedByPushad = 11;
|
| + addq(rsp, Immediate(kRegistersPushedByPushad * kPointerSize));
|
| +}
|
| +
|
| +
|
| +// Order general registers are pushed by Pushad:
|
| +// rax, rcx, rdx, rbx, rsi, rdi, r8, r9, r11, r12, r14.
|
| +int MacroAssembler::kSafepointPushRegisterIndices[Register::kNumRegisters] = {
|
| + 0,
|
| + 1,
|
| + 2,
|
| + 3,
|
| + -1,
|
| + -1,
|
| + 4,
|
| + 5,
|
| + 6,
|
| + 7,
|
| + -1,
|
| + 8,
|
| + 9,
|
| + -1,
|
| + 10,
|
| + -1
|
| +};
|
| +
|
| +
|
| void MacroAssembler::PushTryHandler(CodeLocation try_location,
|
| HandlerType type) {
|
| // Adjust this code if not the case.
|
| @@ -1775,12 +1834,24 @@ void MacroAssembler::EnterExitFramePrologue(bool save_rax) {
|
| }
|
|
|
|
|
| -void MacroAssembler::EnterExitFrameEpilogue(int arg_stack_space) {
|
| +void MacroAssembler::EnterExitFrameEpilogue(int arg_stack_space,
|
| + bool save_doubles) {
|
| #ifdef _WIN64
|
| - const int kShaddowSpace = 4;
|
| - arg_stack_space += kShaddowSpace;
|
| + const int kShadowSpace = 4;
|
| + arg_stack_space += kShadowSpace;
|
| #endif
|
| - if (arg_stack_space > 0) {
|
| + // Optionally save all XMM registers.
|
| + if (save_doubles) {
|
| + CpuFeatures::Scope scope(SSE2);
|
| + int space = XMMRegister::kNumRegisters * kDoubleSize +
|
| + arg_stack_space * kPointerSize;
|
| + subq(rsp, Immediate(space));
|
| + int offset = -2 * kPointerSize;
|
| + for (int i = 0; i < XMMRegister::kNumAllocatableRegisters; i++) {
|
| + XMMRegister reg = XMMRegister::FromAllocationIndex(i);
|
| + movsd(Operand(rbp, offset - ((i + 1) * kDoubleSize)), reg);
|
| + }
|
| + } else if (arg_stack_space > 0) {
|
| subq(rsp, Immediate(arg_stack_space * kPointerSize));
|
| }
|
|
|
| @@ -1797,7 +1868,7 @@ void MacroAssembler::EnterExitFrameEpilogue(int arg_stack_space) {
|
| }
|
|
|
|
|
| -void MacroAssembler::EnterExitFrame(int arg_stack_space) {
|
| +void MacroAssembler::EnterExitFrame(int arg_stack_space, bool save_doubles) {
|
| EnterExitFramePrologue(true);
|
|
|
| // Setup argv in callee-saved register r12. It is reused in LeaveExitFrame,
|
| @@ -1805,25 +1876,31 @@ void MacroAssembler::EnterExitFrame(int arg_stack_space) {
|
| int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize;
|
| lea(r12, Operand(rbp, r14, times_pointer_size, offset));
|
|
|
| - EnterExitFrameEpilogue(arg_stack_space);
|
| + EnterExitFrameEpilogue(arg_stack_space, save_doubles);
|
| }
|
|
|
|
|
| void MacroAssembler::EnterApiExitFrame(int arg_stack_space) {
|
| EnterExitFramePrologue(false);
|
| - EnterExitFrameEpilogue(arg_stack_space);
|
| + EnterExitFrameEpilogue(arg_stack_space, false);
|
| }
|
|
|
|
|
| -void MacroAssembler::LeaveExitFrame() {
|
| +void MacroAssembler::LeaveExitFrame(bool save_doubles) {
|
| // Registers:
|
| // r12 : argv
|
| -
|
| + if (save_doubles) {
|
| + int offset = -2 * kPointerSize;
|
| + for (int i = 0; i < XMMRegister::kNumAllocatableRegisters; i++) {
|
| + XMMRegister reg = XMMRegister::FromAllocationIndex(i);
|
| + movsd(reg, Operand(rbp, offset - ((i + 1) * kDoubleSize)));
|
| + }
|
| + }
|
| // Get the return address from the stack and restore the frame pointer.
|
| movq(rcx, Operand(rbp, 1 * kPointerSize));
|
| movq(rbp, Operand(rbp, 0 * kPointerSize));
|
|
|
| - // Pop everything up to and including the arguments and the receiver
|
| + // Drop everything up to and including the arguments and the receiver
|
| // from the caller stack.
|
| lea(rsp, Operand(r12, 1 * kPointerSize));
|
|
|
|
|