Index: src/x64/macro-assembler-x64.cc |
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc |
index 6b84b0bc1aad2a8377890cc09140d7e0eec7fca9..efbaec468f6d96c36a7e04fd840556e5b4bec124 100644 |
--- a/src/x64/macro-assembler-x64.cc |
+++ b/src/x64/macro-assembler-x64.cc |
@@ -165,11 +165,11 @@ void MacroAssembler::PushAddress(ExternalReference source) { |
if (emit_debug_code()) { |
Move(kScratchRegister, kZapValue, Assembler::RelocInfoNone()); |
} |
- push(Immediate(static_cast<int32_t>(address))); |
+ Push(Immediate(static_cast<int32_t>(address))); |
return; |
} |
LoadAddress(kScratchRegister, source); |
- push(kScratchRegister); |
+ Push(kScratchRegister); |
} |
@@ -200,7 +200,7 @@ void MacroAssembler::StoreRoot(Register source, Heap::RootListIndex index) { |
void MacroAssembler::PushRoot(Heap::RootListIndex index) { |
ASSERT(root_array_available_); |
- push(Operand(kRootRegister, (index << kPointerSizeLog2) - kRootRegisterBias)); |
+ Push(Operand(kRootRegister, (index << kPointerSizeLog2) - kRootRegisterBias)); |
} |
@@ -518,10 +518,10 @@ void MacroAssembler::Abort(BailoutReason reason) { |
} |
#endif |
- push(rax); |
+ Push(rax); |
Move(kScratchRegister, Smi::FromInt(static_cast<int>(reason)), |
Assembler::RelocInfoNone()); |
- push(kScratchRegister); |
+ Push(kScratchRegister); |
if (!has_frame_) { |
// We don't actually want to generate a pile of code for this, so just |
@@ -881,7 +881,7 @@ void MacroAssembler::PushCallerSaved(SaveFPRegsMode fp_mode, |
for (int i = 0; i < kNumberOfSavedRegs; i++) { |
Register reg = saved_regs[i]; |
if (!reg.is(exclusion1) && !reg.is(exclusion2) && !reg.is(exclusion3)) { |
- push(reg); |
+ pushq(reg); |
} |
} |
// R12 to r15 are callee save on all platforms. |
@@ -909,7 +909,7 @@ void MacroAssembler::PopCallerSaved(SaveFPRegsMode fp_mode, |
for (int i = kNumberOfSavedRegs - 1; i >= 0; i--) { |
Register reg = saved_regs[i]; |
if (!reg.is(exclusion1) && !reg.is(exclusion2) && !reg.is(exclusion3)) { |
- pop(reg); |
+ popq(reg); |
} |
} |
} |
@@ -2231,10 +2231,10 @@ void MacroAssembler::AddSmiField(Register dst, const Operand& src) { |
void MacroAssembler::Push(Smi* source) { |
intptr_t smi = reinterpret_cast<intptr_t>(source); |
if (is_int32(smi)) { |
- push(Immediate(static_cast<int32_t>(smi))); |
+ Push(Immediate(static_cast<int32_t>(smi))); |
} else { |
Register constant = GetSmiConstant(source); |
- push(constant); |
+ Push(constant); |
} |
} |
@@ -2244,18 +2244,18 @@ void MacroAssembler::PushInt64AsTwoSmis(Register src, Register scratch) { |
// High bits. |
shr(src, Immediate(64 - kSmiShift)); |
shl(src, Immediate(kSmiShift)); |
- push(src); |
+ Push(src); |
// Low bits. |
shl(scratch, Immediate(kSmiShift)); |
- push(scratch); |
+ Push(scratch); |
} |
void MacroAssembler::PopInt64AsTwoSmis(Register dst, Register scratch) { |
- pop(scratch); |
+ Pop(scratch); |
// Low bits. |
shr(scratch, Immediate(kSmiShift)); |
- pop(dst); |
+ Pop(dst); |
shr(dst, Immediate(kSmiShift)); |
// High bits. |
shl(dst, Immediate(64 - kSmiShift)); |
@@ -2535,7 +2535,7 @@ void MacroAssembler::Push(Handle<Object> source) { |
Push(Smi::cast(*source)); |
} else { |
MoveHeapObject(kScratchRegister, source); |
- push(kScratchRegister); |
+ Push(kScratchRegister); |
} |
} |
@@ -2572,6 +2572,85 @@ void MacroAssembler::Drop(int stack_elements) { |
} |
+void MacroAssembler::Push(Register src) { |
+ if (kPointerSize == kInt64Size) { |
+ pushq(src); |
+ } else { |
+ ASSERT(kPointerSize == kInt32Size); |
+ // x32 uses 64-bit push for rbp in the prologue. |
+ ASSERT(src.code() != rbp.code()); |
+ leal(rsp, Operand(rsp, -4)); |
+ movp(Operand(rsp, 0), src); |
+ } |
+} |
+ |
+ |
+void MacroAssembler::Push(const Operand& src) { |
+ if (kPointerSize == kInt64Size) { |
+ pushq(src); |
+ } else { |
+ ASSERT(kPointerSize == kInt32Size); |
+ movp(kScratchRegister, src); |
+ leal(rsp, Operand(rsp, -4)); |
+ movp(Operand(rsp, 0), kScratchRegister); |
+ } |
+} |
+ |
+ |
+void MacroAssembler::Push(Immediate value) { |
+ if (kPointerSize == kInt64Size) { |
+ pushq(value); |
+ } else { |
+ ASSERT(kPointerSize == kInt32Size); |
+ leal(rsp, Operand(rsp, -4)); |
+ movp(Operand(rsp, 0), value); |
+ } |
+} |
+ |
+ |
+void MacroAssembler::PushImm32(int32_t imm32) { |
+ if (kPointerSize == kInt64Size) { |
+ pushq_imm32(imm32); |
+ } else { |
+ ASSERT(kPointerSize == kInt32Size); |
+ leal(rsp, Operand(rsp, -4)); |
+ movp(Operand(rsp, 0), Immediate(imm32)); |
+ } |
+} |
+ |
+ |
+void MacroAssembler::Pop(Register dst) { |
+ if (kPointerSize == kInt64Size) { |
+ popq(dst); |
+ } else { |
+ ASSERT(kPointerSize == kInt32Size); |
+ // x32 uses 64-bit pop for rbp in the epilogue. |
+ ASSERT(dst.code() != rbp.code()); |
+ movp(dst, Operand(rsp, 0)); |
+ leal(rsp, Operand(rsp, 4)); |
+ } |
+} |
+ |
+ |
+void MacroAssembler::Pop(const Operand& dst) { |
+ if (kPointerSize == kInt64Size) { |
+ popq(dst); |
+ } else { |
+ ASSERT(kPointerSize == kInt32Size); |
+ Register scratch = dst.AddressUsesRegister(kScratchRegister) |
+ ? kSmiConstantRegister : kScratchRegister; |
+ movp(scratch, Operand(rsp, 0)); |
+ movp(dst, scratch); |
+ leal(rsp, Operand(rsp, 4)); |
+ if (scratch.is(kSmiConstantRegister)) { |
+ // Restore kSmiConstantRegister. |
+ movp(kSmiConstantRegister, Smi::FromInt(kSmiConstantRegisterValue), |
+ Assembler::RelocInfoNone()); |
+ } |
+ } |
+} |
+ |
+ |
void MacroAssembler::TestBit(const Operand& src, int bits) { |
int byte_offset = bits / kBitsPerByte; |
int bit_in_byte = bits & (kBitsPerByte - 1); |
@@ -2666,21 +2745,21 @@ void MacroAssembler::Call(Handle<Code> code_object, |
void MacroAssembler::Pushad() { |
- push(rax); |
- push(rcx); |
- push(rdx); |
- push(rbx); |
+ Push(rax); |
+ Push(rcx); |
+ Push(rdx); |
+ Push(rbx); |
// Not pushing rsp or rbp. |
- push(rsi); |
- push(rdi); |
- push(r8); |
- push(r9); |
+ Push(rsi); |
+ Push(rdi); |
+ Push(r8); |
+ Push(r9); |
// r10 is kScratchRegister. |
- push(r11); |
+ Push(r11); |
// r12 is kSmiConstantRegister. |
// r13 is kRootRegister. |
- push(r14); |
- push(r15); |
+ Push(r14); |
+ Push(r15); |
STATIC_ASSERT(11 == kNumSafepointSavedRegisters); |
// Use lea for symmetry with Popad. |
int sp_delta = |
@@ -2694,17 +2773,17 @@ void MacroAssembler::Popad() { |
int sp_delta = |
(kNumSafepointRegisters - kNumSafepointSavedRegisters) * kPointerSize; |
lea(rsp, Operand(rsp, sp_delta)); |
- pop(r15); |
- pop(r14); |
- pop(r11); |
- pop(r9); |
- pop(r8); |
- pop(rdi); |
- pop(rsi); |
- pop(rbx); |
- pop(rdx); |
- pop(rcx); |
- pop(rax); |
+ Pop(r15); |
+ Pop(r14); |
+ Pop(r11); |
+ Pop(r9); |
+ Pop(r8); |
+ Pop(rdi); |
+ Pop(rsi); |
+ Pop(rbx); |
+ Pop(rdx); |
+ Pop(rcx); |
+ Pop(rax); |
} |
@@ -2774,23 +2853,23 @@ void MacroAssembler::PushTryHandler(StackHandler::Kind kind, |
// The frame pointer does not point to a JS frame so we save NULL for |
// rbp. We expect the code throwing an exception to check rbp before |
// dereferencing it to restore the context. |
- push(Immediate(0)); // NULL frame pointer. |
+ pushq(Immediate(0)); // NULL frame pointer. |
Push(Smi::FromInt(0)); // No context. |
} else { |
- push(rbp); |
- push(rsi); |
+ pushq(rbp); |
+ Push(rsi); |
} |
// Push the state and the code object. |
unsigned state = |
StackHandler::IndexField::encode(handler_index) | |
StackHandler::KindField::encode(kind); |
- push(Immediate(state)); |
+ Push(Immediate(state)); |
Push(CodeObject()); |
// Link the current handler as the next handler. |
ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); |
- push(ExternalOperand(handler_address)); |
+ Push(ExternalOperand(handler_address)); |
// Set this new handler as the current one. |
movp(ExternalOperand(handler_address), rsp); |
} |
@@ -2799,7 +2878,7 @@ void MacroAssembler::PushTryHandler(StackHandler::Kind kind, |
void MacroAssembler::PopTryHandler() { |
STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); |
ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); |
- pop(ExternalOperand(handler_address)); |
+ Pop(ExternalOperand(handler_address)); |
addq(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize)); |
} |
@@ -2836,15 +2915,15 @@ void MacroAssembler::Throw(Register value) { |
ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); |
movp(rsp, ExternalOperand(handler_address)); |
// Restore the next handler. |
- pop(ExternalOperand(handler_address)); |
+ Pop(ExternalOperand(handler_address)); |
// Remove the code object and state, compute the handler address in rdi. |
- pop(rdi); // Code object. |
- pop(rdx); // Offset and state. |
+ Pop(rdi); // Code object. |
+ Pop(rdx); // Offset and state. |
// Restore the context and frame pointer. |
- pop(rsi); // Context. |
- pop(rbp); // Frame pointer. |
+ Pop(rsi); // Context. |
+ popq(rbp); // Frame pointer. |
// If the handler is a JS frame, restore the context to the frame. |
// (kind == ENTRY) == (rbp == 0) == (rsi == 0), so we could test either |
@@ -2890,15 +2969,15 @@ void MacroAssembler::ThrowUncatchable(Register value) { |
j(not_zero, &fetch_next); |
// Set the top handler address to next handler past the top ENTRY handler. |
- pop(ExternalOperand(handler_address)); |
+ Pop(ExternalOperand(handler_address)); |
// Remove the code object and state, compute the handler address in rdi. |
- pop(rdi); // Code object. |
- pop(rdx); // Offset and state. |
+ Pop(rdi); // Code object. |
+ Pop(rdx); // Offset and state. |
// Clear the context pointer and frame pointer (0 was saved in the handler). |
- pop(rsi); |
- pop(rbp); |
+ Pop(rsi); |
+ popq(rbp); |
JumpToHandlerEntry(); |
} |
@@ -3219,7 +3298,7 @@ void MacroAssembler::Throw(BailoutReason reason) { |
} |
#endif |
- push(rax); |
+ Push(rax); |
Push(Smi::FromInt(reason)); |
if (!has_frame_) { |
// We don't actually want to generate a pile of code for this, so just |
@@ -3330,10 +3409,10 @@ void MacroAssembler::AssertString(Register object) { |
if (emit_debug_code()) { |
testb(object, Immediate(kSmiTagMask)); |
Check(not_equal, kOperandIsASmiAndNotAString); |
- push(object); |
+ Push(object); |
movp(object, FieldOperand(object, HeapObject::kMapOffset)); |
CmpInstanceType(object, FIRST_NONSTRING_TYPE); |
- pop(object); |
+ Pop(object); |
Check(below, kOperandIsNotAString); |
} |
} |
@@ -3343,10 +3422,10 @@ void MacroAssembler::AssertName(Register object) { |
if (emit_debug_code()) { |
testb(object, Immediate(kSmiTagMask)); |
Check(not_equal, kOperandIsASmiAndNotAName); |
- push(object); |
+ Push(object); |
movp(object, FieldOperand(object, HeapObject::kMapOffset)); |
CmpInstanceType(object, LAST_NAME_TYPE); |
- pop(object); |
+ Pop(object); |
Check(below_equal, kOperandIsNotAName); |
} |
} |
@@ -3659,9 +3738,9 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected, |
void MacroAssembler::Prologue(PrologueFrameMode frame_mode) { |
if (frame_mode == BUILD_STUB_FRAME) { |
- push(rbp); // Caller's frame pointer. |
+ pushq(rbp); // Caller's frame pointer. |
movp(rbp, rsp); |
- push(rsi); // Callee's context. |
+ Push(rsi); // Callee's context. |
Push(Smi::FromInt(StackFrame::STUB)); |
} else { |
PredictableCodeSizeScope predictible_code_size_scope(this, |
@@ -3672,22 +3751,22 @@ void MacroAssembler::Prologue(PrologueFrameMode frame_mode) { |
RelocInfo::CODE_AGE_SEQUENCE); |
Nop(kNoCodeAgeSequenceLength - Assembler::kShortCallInstructionLength); |
} else { |
- push(rbp); // Caller's frame pointer. |
+ pushq(rbp); // Caller's frame pointer. |
movp(rbp, rsp); |
- push(rsi); // Callee's context. |
- push(rdi); // Callee's JS function. |
+ Push(rsi); // Callee's context. |
+ Push(rdi); // Callee's JS function. |
} |
} |
} |
void MacroAssembler::EnterFrame(StackFrame::Type type) { |
- push(rbp); |
+ pushq(rbp); |
movp(rbp, rsp); |
- push(rsi); // Context. |
+ Push(rsi); // Context. |
Push(Smi::FromInt(type)); |
Move(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT); |
- push(kScratchRegister); |
+ Push(kScratchRegister); |
if (emit_debug_code()) { |
Move(kScratchRegister, |
isolate()->factory()->undefined_value(), |
@@ -3705,7 +3784,7 @@ void MacroAssembler::LeaveFrame(StackFrame::Type type) { |
Check(equal, kStackFrameTypesMustMatch); |
} |
movp(rsp, rbp); |
- pop(rbp); |
+ popq(rbp); |
} |
@@ -3716,14 +3795,14 @@ void MacroAssembler::EnterExitFramePrologue(bool save_rax) { |
kFPOnStackSize + kPCOnStackSize); |
ASSERT(ExitFrameConstants::kCallerPCOffset == kFPOnStackSize); |
ASSERT(ExitFrameConstants::kCallerFPOffset == 0 * kPointerSize); |
- push(rbp); |
+ pushq(rbp); |
movp(rbp, rsp); |
// Reserve room for entry stack pointer and push the code object. |
ASSERT(ExitFrameConstants::kSPOffset == -1 * kPointerSize); |
- push(Immediate(0)); // Saved entry sp, patched before call. |
+ Push(Immediate(0)); // Saved entry sp, patched before call. |
Move(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT); |
- push(kScratchRegister); // Accessed from EditFrame::code_slot. |
+ Push(kScratchRegister); // Accessed from EditFrame::code_slot. |
// Save the frame pointer and the context in top. |
if (save_rax) { |
@@ -3812,7 +3891,7 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles) { |
void MacroAssembler::LeaveApiExitFrame(bool restore_context) { |
movp(rsp, rbp); |
- pop(rbp); |
+ popq(rbp); |
LeaveExitFrameEpilogue(restore_context); |
} |
@@ -3877,7 +3956,7 @@ void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, |
// Check the context is a native context. |
if (emit_debug_code()) { |
// Preserve original value of holder_reg. |
- push(holder_reg); |
+ Push(holder_reg); |
movp(holder_reg, |
FieldOperand(holder_reg, JSGlobalProxy::kNativeContextOffset)); |
CompareRoot(holder_reg, Heap::kNullValueRootIndex); |
@@ -3887,7 +3966,7 @@ void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, |
movp(holder_reg, FieldOperand(holder_reg, HeapObject::kMapOffset)); |
CompareRoot(holder_reg, Heap::kNativeContextMapRootIndex); |
Check(equal, kJSGlobalObjectNativeContextShouldBeANativeContext); |
- pop(holder_reg); |
+ Pop(holder_reg); |
} |
movp(kScratchRegister, |
@@ -4603,13 +4682,13 @@ void MacroAssembler::EmitSeqStringSetCharCheck(Register string, |
Abort(kNonObject); |
bind(&is_object); |
- push(value); |
+ Push(value); |
movp(value, FieldOperand(string, HeapObject::kMapOffset)); |
movzxbq(value, FieldOperand(value, Map::kInstanceTypeOffset)); |
andb(value, Immediate(kStringRepresentationMask | kStringEncodingMask)); |
cmpq(value, Immediate(encoding_mask)); |
- pop(value); |
+ Pop(value); |
Check(equal, kUnexpectedStringType); |
// The index is assumed to be untagged coming in, tag it to compare with the |
@@ -4829,14 +4908,14 @@ void MacroAssembler::EnsureNotWhite( |
if (emit_debug_code()) { |
// Check for impossible bit pattern. |
Label ok; |
- push(mask_scratch); |
+ Push(mask_scratch); |
// shl. May overflow making the check conservative. |
addq(mask_scratch, mask_scratch); |
testq(Operand(bitmap_scratch, MemoryChunk::kHeaderSize), mask_scratch); |
j(zero, &ok, Label::kNear); |
int3(); |
bind(&ok); |
- pop(mask_scratch); |
+ Pop(mask_scratch); |
} |
// Value is white. We check whether it is data that doesn't need scanning. |