Index: src/x64/builtins-x64.cc |
=================================================================== |
--- src/x64/builtins-x64.cc (revision 15486) |
+++ src/x64/builtins-x64.cc (working copy) |
@@ -38,8 +38,11 @@ |
#define __ ACCESS_MASM(masm) |
+#define __k __ |
+#define __q __ |
+#define __a __ |
+#define __a __ |
- |
void Builtins::Generate_Adaptor(MacroAssembler* masm, |
CFunctionId id, |
BuiltinExtraArguments extra_args) { |
@@ -59,9 +62,9 @@ |
int num_extra_args = 0; |
if (extra_args == NEEDS_CALLED_FUNCTION) { |
num_extra_args = 1; |
- __ pop(kScratchRegister); // Save return address. |
+ __k pop(kScratchRegister); // Save return address. |
__ push(rdi); |
- __ push(kScratchRegister); // Restore return address. |
+ __k push(kScratchRegister); // Restore return address. |
} else { |
ASSERT(extra_args == NO_EXTRA_ARGUMENTS); |
} |
@@ -429,10 +432,10 @@ |
} |
// Remove caller arguments from the stack and return. |
- __ pop(rcx); |
+ __k pop(rcx); |
SmiIndex index = masm->SmiToIndex(rbx, rbx, kPointerSizeLog2); |
__ lea(rsp, Operand(rsp, index.reg, index.scale, 1 * kPointerSize)); |
- __ push(rcx); |
+ __k push(rcx); |
Counters* counters = masm->isolate()->counters(); |
__ IncrementCounter(counters->constructed_objects(), 1); |
__ ret(0); |
@@ -689,7 +692,7 @@ |
// Tear down internal frame. |
} |
- __ pop(MemOperand(rsp, 0)); // Ignore state offset |
+ __k pop(MemOperand(rsp, 0)); // Ignore state offset |
__ ret(0); // Return to IC Miss stub, continuation still on stack. |
} |
@@ -708,19 +711,19 @@ |
} |
// Get the full codegen state from the stack and untag it. |
- __ SmiToInteger32(r10, Operand(rsp, 1 * kPointerSize)); |
+ __a SmiToInteger32(r10, Operand(rsp, 1 * kPointerSize)); |
// Switch on the state. |
Label not_no_registers, not_tos_rax; |
__ cmpq(r10, Immediate(FullCodeGenerator::NO_REGISTERS)); |
__ j(not_equal, ¬_no_registers, Label::kNear); |
- __ ret(1 * kPointerSize); // Remove state. |
+ __q ret(1 * kPointerSize); // Remove state. |
__ bind(¬_no_registers); |
- __ movq(rax, Operand(rsp, 2 * kPointerSize)); |
+ __q movq(rax, Operand(rsp, 2 * kPointerSize)); |
__ cmpq(r10, Immediate(FullCodeGenerator::TOS_REG)); |
__ j(not_equal, ¬_tos_rax, Label::kNear); |
- __ ret(2 * kPointerSize); // Remove state, rax. |
+ __a ret(2 * kPointerSize); // Remove state, rax. |
__ bind(¬_tos_rax); |
__ Abort("no cases left"); |
@@ -771,9 +774,9 @@ |
{ Label done; |
__ testq(rax, rax); |
__ j(not_zero, &done); |
- __ pop(rbx); |
+ __k pop(rbx); |
__ Push(masm->isolate()->factory()->undefined_value()); |
- __ push(rbx); |
+ __k push(rbx); |
__ incq(rax); |
__ bind(&done); |
} |
@@ -782,7 +785,7 @@ |
// if it is a function. |
Label slow, non_function; |
// The function to call is at position n+1 on the stack. |
- __ movq(rdi, Operand(rsp, rax, times_pointer_size, 1 * kPointerSize)); |
+ __a movq(rdi, Operand(rsp, rax, times_pointer_size, 1 * kPointerSize)); |
__ JumpIfSmi(rdi, &non_function); |
__ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); |
__ j(not_equal, &slow); |
@@ -807,7 +810,7 @@ |
__ j(not_zero, &shift_arguments); |
// Compute the receiver in non-strict mode. |
- __ movq(rbx, Operand(rsp, rax, times_pointer_size, 0)); |
+ __a movq(rbx, Operand(rsp, rax, times_pointer_size, 0)); |
__ JumpIfSmi(rbx, &convert_to_object, Label::kNear); |
__ CompareRoot(rbx, Heap::kNullValueRootIndex); |
@@ -836,7 +839,7 @@ |
} |
// Restore the function to rdi. |
- __ movq(rdi, Operand(rsp, rax, times_pointer_size, 1 * kPointerSize)); |
+ __a movq(rdi, Operand(rsp, rax, times_pointer_size, 1 * kPointerSize)); |
__ jmp(&patch_receiver, Label::kNear); |
// Use the global receiver object from the called function as the |
@@ -850,8 +853,7 @@ |
__ movq(rbx, FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset)); |
__ bind(&patch_receiver); |
- __ movq(Operand(rsp, rax, times_pointer_size, 0), rbx); |
- |
+ __a movq(Operand(rsp, rax, times_pointer_size, 0), rbx); |
__ jmp(&shift_arguments); |
} |
@@ -867,7 +869,7 @@ |
// CALL_NON_FUNCTION builtin expects the non-function callee as |
// receiver, so overwrite the first argument which will ultimately |
// become the receiver. |
- __ movq(Operand(rsp, rax, times_pointer_size, 0), rdi); |
+ __a movq(Operand(rsp, rax, times_pointer_size, 0), rdi); |
// 4. Shift arguments and return address one slot down on the stack |
// (overwriting the original receiver). Adjust argument count to make |
@@ -875,12 +877,19 @@ |
__ bind(&shift_arguments); |
{ Label loop; |
__ movq(rcx, rax); |
+#ifdef V8_TARGET_ARCH_X32 |
+ __ incl(rcx); // HWRegSize = kPointerSize + kPointerSize |
+#endif |
__ bind(&loop); |
__ movq(rbx, Operand(rsp, rcx, times_pointer_size, 0)); |
__ movq(Operand(rsp, rcx, times_pointer_size, 1 * kPointerSize), rbx); |
__ decq(rcx); |
__ j(not_sign, &loop); // While non-negative (to copy return address). |
+#ifndef V8_TARGET_ARCH_X32 |
__ pop(rbx); // Discard copy of return address. |
+#else |
+ __ leal(rsp, Operand(rsp, 4)); // Discard bottom-half of return address |
+#endif |
__ decq(rax); // One fewer argument (first argument is new receiver). |
} |
@@ -894,9 +903,9 @@ |
__ cmpq(rdx, Immediate(1)); |
__ j(not_equal, &non_proxy); |
- __ pop(rdx); // return address |
+ __k pop(rdx); // return address |
__ push(rdi); // re-add proxy object as additional argument |
- __ push(rdx); |
+ __k push(rdx); |
__ incq(rax); |
__ GetBuiltinEntry(rdx, Builtins::CALL_FUNCTION_PROXY); |
__ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
@@ -913,9 +922,17 @@ |
// expected arguments matches what we're providing. If so, jump |
// (tail-call) to the code in register edx without checking arguments. |
__ movq(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); |
+#ifndef V8_TARGET_ARCH_X32 |
__ movsxlq(rbx, |
FieldOperand(rdx, |
SharedFunctionInfo::kFormalParameterCountOffset)); |
+#else |
+ // kFormalParameterCountOffset is not tagged in X64, while tagged in X32. |
+ __ movl(rbx, |
+ FieldOperand(rdx, |
+ SharedFunctionInfo::kFormalParameterCountOffset)); |
+ __ SmiToInteger32(rbx, rbx); |
+#endif |
__ movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); |
__ SetCallKind(rcx, CALL_AS_METHOD); |
__ cmpq(rax, rbx); |
@@ -943,9 +960,15 @@ |
// rbp[16] : function arguments |
// rbp[24] : receiver |
// rbp[32] : function |
+#ifndef V8_TARGET_ARCH_X32 |
static const int kArgumentsOffset = 2 * kPointerSize; |
static const int kReceiverOffset = 3 * kPointerSize; |
static const int kFunctionOffset = 4 * kPointerSize; |
+#else |
+ static const int kArgumentsOffset = 2 * kHWRegSize; |
+ static const int kReceiverOffset = 2 * kHWRegSize + 1 * kPointerSize; |
+ static const int kFunctionOffset = 2 * kHWRegSize + 2 * kPointerSize; |
+#endif |
__ push(Operand(rbp, kFunctionOffset)); |
__ push(Operand(rbp, kArgumentsOffset)); |
@@ -1180,10 +1203,10 @@ |
Label no_arguments; |
__ testq(rax, rax); |
__ j(zero, &no_arguments); |
- __ movq(rbx, Operand(rsp, rax, times_pointer_size, 0)); |
- __ pop(rcx); |
- __ lea(rsp, Operand(rsp, rax, times_pointer_size, kPointerSize)); |
- __ push(rcx); |
+ __a movq(rbx, Operand(rsp, rax, times_pointer_size, 0)); |
+ __k pop(rcx); |
+ __ lea(rsp, Operand(rsp, rax, times_pointer_size, 1 * kPointerSize)); |
+ __k push(rcx); |
__ movq(rax, rbx); |
// Lookup the argument in the number to string cache. |
@@ -1268,9 +1291,9 @@ |
// stack, and jump back to the case where the argument is a string. |
__ bind(&no_arguments); |
__ LoadRoot(rbx, Heap::kempty_stringRootIndex); |
- __ pop(rcx); |
- __ lea(rsp, Operand(rsp, kPointerSize)); |
- __ push(rcx); |
+ __k pop(rcx); |
+ __ lea(rsp, Operand(rsp, 1 * kPointerSize)); |
+ __k push(rcx); |
__ jmp(&argument_is_string); |
// At this point the argument is already a string. Call runtime to |
@@ -1313,10 +1336,10 @@ |
__ pop(rbp); |
// Remove caller arguments from the stack. |
- __ pop(rcx); |
+ __k pop(rcx); |
SmiIndex index = masm->SmiToIndex(rbx, rbx, kPointerSizeLog2); |
__ lea(rsp, Operand(rsp, index.reg, index.scale, 1 * kPointerSize)); |
- __ push(rcx); |
+ __k push(rcx); |
} |
@@ -1427,7 +1450,7 @@ |
__ bind(&skip); |
// Untag the AST id and push it on the stack. |
__ SmiToInteger32(rax, rax); |
- __ push(rax); |
+ __k push(rax); |
// Generate the code for doing the frame-to-frame translation using |
// the deoptimizer infrastructure. |
@@ -1435,7 +1458,10 @@ |
generator.Generate(); |
} |
- |
+#undef __a |
+#undef __a |
+#undef __q |
+#undef __k |
#undef __ |
} } // namespace v8::internal |