Index: src/x64/codegen-x64.cc |
diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc |
index f3ee40c13b80ced05b9af099edb7f8c7d7c6a126..3b1aeaedbc84786af0679ecdff25de6b8158b4c1 100644 |
--- a/src/x64/codegen-x64.cc |
+++ b/src/x64/codegen-x64.cc |
@@ -592,7 +592,6 @@ bool CodeGenerator::HasValidEntryRegisters() { |
&& (allocator()->count(r9) == (frame()->is_used(r9) ? 1 : 0)) |
&& (allocator()->count(r11) == (frame()->is_used(r11) ? 1 : 0)) |
&& (allocator()->count(r14) == (frame()->is_used(r14) ? 1 : 0)) |
- && (allocator()->count(r15) == (frame()->is_used(r15) ? 1 : 0)) |
&& (allocator()->count(r12) == (frame()->is_used(r12) ? 1 : 0)); |
} |
#endif |
@@ -3606,17 +3605,16 @@ void CodeGenerator::VisitCountOperation(CountOperation* node) { |
__ JumpIfNotSmi(new_value.reg(), deferred->entry_label()); |
} |
if (is_increment) { |
- __ SmiAddConstant(kScratchRegister, |
+ __ SmiAddConstant(new_value.reg(), |
new_value.reg(), |
Smi::FromInt(1), |
deferred->entry_label()); |
} else { |
- __ SmiSubConstant(kScratchRegister, |
+ __ SmiSubConstant(new_value.reg(), |
new_value.reg(), |
Smi::FromInt(1), |
deferred->entry_label()); |
} |
- __ movq(new_value.reg(), kScratchRegister); |
deferred->BindExit(); |
// Postfix count operations return their input converted to |
@@ -8727,26 +8725,26 @@ void RegExpExecStub::Generate(MacroAssembler* masm) { |
__ bind(&seq_ascii_string); |
// rax: subject string (sequential ascii) |
// rcx: RegExp data (FixedArray) |
- __ movq(r12, FieldOperand(rcx, JSRegExp::kDataAsciiCodeOffset)); |
+ __ movq(r11, FieldOperand(rcx, JSRegExp::kDataAsciiCodeOffset)); |
__ Set(rdi, 1); // Type is ascii. |
__ jmp(&check_code); |
__ bind(&seq_two_byte_string); |
// rax: subject string (flat two-byte) |
// rcx: RegExp data (FixedArray) |
- __ movq(r12, FieldOperand(rcx, JSRegExp::kDataUC16CodeOffset)); |
+ __ movq(r11, FieldOperand(rcx, JSRegExp::kDataUC16CodeOffset)); |
__ Set(rdi, 0); // Type is two byte. |
__ bind(&check_code); |
// Check that the irregexp code has been generated for the actual string |
// encoding. If it has, the field contains a code object otherwise it contains |
// the hole. |
- __ CmpObjectType(r12, CODE_TYPE, kScratchRegister); |
+ __ CmpObjectType(r11, CODE_TYPE, kScratchRegister); |
__ j(not_equal, &runtime); |
// rax: subject string |
// rdi: encoding of subject string (1 if ascii, 0 if two_byte); |
- // r12: code |
+ // r11: code |
// Load used arguments before starting to push arguments for call to native |
// RegExp code to avoid handling changing stack height. |
__ SmiToInteger64(rbx, Operand(rsp, kPreviousIndexOffset)); |
@@ -8754,7 +8752,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) { |
// rax: subject string |
// rbx: previous index |
// rdi: encoding of subject string (1 if ascii 0 if two_byte); |
- // r12: code |
+ // r11: code |
// All checks done. Now push arguments for native regexp code. |
__ IncrementCounter(&Counters::regexp_entry_native, 1); |
@@ -8804,7 +8802,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) { |
// rax: subject string |
// rbx: previous index |
// rdi: encoding of subject string (1 if ascii 0 if two_byte); |
- // r12: code |
+ // r11: code |
// Argument 4: End of string data |
// Argument 3: Start of string data |
@@ -8828,8 +8826,8 @@ void RegExpExecStub::Generate(MacroAssembler* masm) { |
__ movq(arg1, rax); |
// Locate the code entry and call it. |
- __ addq(r12, Immediate(Code::kHeaderSize - kHeapObjectTag)); |
- __ CallCFunction(r12, kRegExpExecuteArguments); |
+ __ addq(r11, Immediate(Code::kHeaderSize - kHeapObjectTag)); |
+ __ CallCFunction(r11, kRegExpExecuteArguments); |
// rsi is caller save, as it is used to pass parameter. |
__ pop(rsi); |
@@ -9627,7 +9625,7 @@ void CEntryStub::GenerateCore(MacroAssembler* masm, |
// rbp: frame pointer (restored after C call). |
// rsp: stack pointer (restored after C call). |
// r14: number of arguments including receiver (C callee-saved). |
- // r15: pointer to the first argument (C callee-saved). |
+ // r12: pointer to the first argument (C callee-saved). |
// This pointer is reused in LeaveExitFrame(), so it is stored in a |
// callee-saved register. |
@@ -9668,7 +9666,7 @@ void CEntryStub::GenerateCore(MacroAssembler* masm, |
// Windows 64-bit ABI passes arguments in rcx, rdx, r8, r9 |
// Store Arguments object on stack, below the 4 WIN64 ABI parameter slots. |
__ movq(Operand(rsp, 4 * kPointerSize), r14); // argc. |
- __ movq(Operand(rsp, 5 * kPointerSize), r15); // argv. |
+ __ movq(Operand(rsp, 5 * kPointerSize), r12); // argv. |
if (result_size_ < 2) { |
// Pass a pointer to the Arguments object as the first argument. |
// Return result in single register (rax). |
@@ -9684,7 +9682,7 @@ void CEntryStub::GenerateCore(MacroAssembler* masm, |
#else // _WIN64 |
// GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9. |
__ movq(rdi, r14); // argc. |
- __ movq(rsi, r15); // argv. |
+ __ movq(rsi, r12); // argv. |
#endif |
__ call(rbx); |
// Result is in rax - do not destroy this register! |
@@ -9886,7 +9884,7 @@ void CEntryStub::Generate(MacroAssembler* masm) { |
// rbp: frame pointer of exit frame (restored after C call). |
// rsp: stack pointer (restored after C call). |
// r14: number of arguments including receiver (C callee-saved). |
- // r15: argv pointer (C callee-saved). |
+ // r12: argv pointer (C callee-saved). |
Label throw_normal_exception; |
Label throw_termination_exception; |
@@ -9946,24 +9944,38 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { |
// Push the stack frame type marker twice. |
int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY; |
- __ Push(Smi::FromInt(marker)); // context slot |
- __ Push(Smi::FromInt(marker)); // function slot |
- // Save callee-saved registers (X64 calling conventions). |
+ // Scratch register is neither callee-save, nor an argument register on any |
+ // platform. It's free to use at this point. |
+ // Cannot use smi-register for loading yet. |
+ __ movq(kScratchRegister, |
+ reinterpret_cast<uint64_t>(Smi::FromInt(marker)), |
+ RelocInfo::NONE); |
+ __ push(kScratchRegister); // context slot |
+ __ push(kScratchRegister); // function slot |
+ // Save callee-saved registers (X64/Win64 calling conventions). |
__ push(r12); |
__ push(r13); |
__ push(r14); |
__ push(r15); |
- __ push(rdi); |
- __ push(rsi); |
+#ifdef _WIN64 |
+ __ push(rdi); // Only callee save in Win64 ABI, argument in AMD64 ABI. |
+ __ push(rsi); // Only callee save in Win64 ABI, argument in AMD64 ABI. |
+#endif |
__ push(rbx); |
- // TODO(X64): Push XMM6-XMM15 (low 64 bits) as well, or make them |
- // callee-save in JS code as well. |
+ // TODO(X64): On Win64, if we ever use XMM6-XMM15, the low low 64 bits are |
+ // callee save as well. |
// Save copies of the top frame descriptor on the stack. |
ExternalReference c_entry_fp(Top::k_c_entry_fp_address); |
__ load_rax(c_entry_fp); |
__ push(rax); |
+ // Set up the roots and smi constant registers. |
+ // Needs to be done before any further smi loads. |
+ ExternalReference roots_address = ExternalReference::roots_address(); |
+ __ movq(kRootRegister, roots_address); |
+ __ InitializeSmiConstantRegister(); |
+ |
#ifdef ENABLE_LOGGING_AND_PROFILING |
// If this is the outermost JS call, set js_entry_sp value. |
ExternalReference js_entry_sp(Top::k_js_entry_sp_address); |
@@ -10034,8 +10046,11 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { |
// Restore callee-saved registers (X64 conventions). |
__ pop(rbx); |
+#ifdef _WIN64 |
+ // Callee save on in Win64 ABI, arguments/volatile in AMD64 ABI. |
__ pop(rsi); |
__ pop(rdi); |
+#endif |
__ pop(r15); |
__ pop(r14); |
__ pop(r13); |
@@ -11269,7 +11284,7 @@ void StringAddStub::Generate(MacroAssembler* masm) { |
// Check that both strings are non-external ascii strings. |
__ JumpIfBothInstanceTypesAreNotSequentialAscii(r8, r9, rbx, rcx, |
- &string_add_runtime); |
+ &string_add_runtime); |
// Get the two characters forming the sub string. |
__ movzxbq(rbx, FieldOperand(rax, SeqAsciiString::kHeaderSize)); |
@@ -11279,7 +11294,7 @@ void StringAddStub::Generate(MacroAssembler* masm) { |
// just allocate a new one. |
Label make_two_character_string, make_flat_ascii_string; |
StringHelper::GenerateTwoCharacterSymbolTableProbe( |
- masm, rbx, rcx, r14, r12, rdi, r15, &make_two_character_string); |
+ masm, rbx, rcx, r14, r11, rdi, r12, &make_two_character_string); |
__ IncrementCounter(&Counters::string_add_native, 1); |
__ ret(2 * kPointerSize); |
@@ -11371,7 +11386,7 @@ void StringAddStub::Generate(MacroAssembler* masm) { |
__ bind(&make_flat_ascii_string); |
// Both strings are ascii strings. As they are short they are both flat. |
- __ AllocateAsciiString(rcx, rbx, rdi, r14, r15, &string_add_runtime); |
+ __ AllocateAsciiString(rcx, rbx, rdi, r14, r11, &string_add_runtime); |
// rcx: result string |
__ movq(rbx, rcx); |
// Locate first character of result. |
@@ -11408,7 +11423,7 @@ void StringAddStub::Generate(MacroAssembler* masm) { |
__ j(not_zero, &string_add_runtime); |
// Both strings are two byte strings. As they are short they are both |
// flat. |
- __ AllocateTwoByteString(rcx, rbx, rdi, r14, r15, &string_add_runtime); |
+ __ AllocateTwoByteString(rcx, rbx, rdi, r14, r11, &string_add_runtime); |
// rcx: result string |
__ movq(rbx, rcx); |
// Locate first character of result. |