Commit 04da7b90 authored by lrn@chromium.org's avatar lrn@chromium.org

X64: Added register holding Smi::FromInt(1).

Don't use r15 for anything any more.

Review URL: http://codereview.chromium.org/2885018

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5009 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 47b5b3f9
......@@ -1238,10 +1238,6 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
__ movq(rbx, r8);
#endif // _WIN64
// Set up the roots register.
ExternalReference roots_address = ExternalReference::roots_address();
__ movq(kRootRegister, roots_address);
// Current stack contents:
// [rsp + 2 * kPointerSize ... ]: Internal frame
// [rsp + kPointerSize] : function
......
......@@ -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.
......
......@@ -56,7 +56,11 @@ class StackHandlerConstants : public AllStatic {
class EntryFrameConstants : public AllStatic {
public:
#ifdef _WIN64
static const int kCallerFPOffset = -10 * kPointerSize;
#else
static const int kCallerFPOffset = -8 * kPointerSize;
#endif
static const int kArgvOffset = 6 * kPointerSize;
};
......
This diff is collapsed.
......@@ -47,8 +47,11 @@ enum AllocationFlags {
// Default scratch register used by MacroAssembler (and other code that needs
// a spare register). The register isn't callee save, and not used by the
// function calling convention.
static const Register kScratchRegister = { 10 }; // r10.
static const Register kRootRegister = { 13 }; // r13
static const Register kScratchRegister = { 10 }; // r10.
static const Register kSmiConstantRegister = { 15 }; // r15 (callee save).
static const Register kRootRegister = { 13 }; // r13 (callee save).
// Value of smi in kSmiConstantRegister.
static const int kSmiConstantRegisterValue = 1;
// Convenience for platform-independent signatures.
typedef Operand MemOperand;
......@@ -202,6 +205,12 @@ class MacroAssembler: public Assembler {
// ---------------------------------------------------------------------------
// Smi tagging, untagging and operations on tagged smis.
void InitializeSmiConstantRegister() {
movq(kSmiConstantRegister,
reinterpret_cast<uint64_t>(Smi::FromInt(kSmiConstantRegisterValue)),
RelocInfo::NONE);
}
// Conversions between tagged smi values and non-tagged integer values.
// Tag an integer value. The result must be known to be a valid smi value.
......@@ -469,11 +478,12 @@ class MacroAssembler: public Assembler {
// Basic Smi operations.
void Move(Register dst, Smi* source) {
Set(dst, reinterpret_cast<int64_t>(source));
LoadSmiConstant(dst, source);
}
void Move(const Operand& dst, Smi* source) {
Set(dst, reinterpret_cast<int64_t>(source));
Register constant = GetSmiConstant(source);
movq(dst, constant);
}
void Push(Smi* smi);
......@@ -820,6 +830,14 @@ class MacroAssembler: public Assembler {
private:
bool generating_stub_;
bool allow_stub_calls_;
// Returns a register holding the smi value. The register MUST NOT be
// modified. It may be the "smi 1 constant" register.
Register GetSmiConstant(Smi* value);
// Moves the smi value to the destination register.
void LoadSmiConstant(Register dst, Smi* value);
// This handle will be patched with the code object on installation.
Handle<Object> code_object_;
......
......@@ -38,7 +38,8 @@ namespace internal {
bool RegisterAllocator::IsReserved(Register reg) {
return reg.is(rsp) || reg.is(rbp) || reg.is(rsi) ||
reg.is(kScratchRegister) || reg.is(kRootRegister);
reg.is(kScratchRegister) || reg.is(kRootRegister) ||
reg.is(kSmiConstantRegister);
}
......@@ -58,11 +59,11 @@ int RegisterAllocator::ToNumber(Register reg) {
5, // r8
6, // r9
-1, // r10 Scratch register.
9, // r11
10, // r12
8, // r11
9, // r12
-1, // r13 Roots array. This is callee saved.
7, // r14
8 // r15
-1 // r15 Smi constant register.
};
return kNumbers[reg.code()];
}
......@@ -71,7 +72,7 @@ int RegisterAllocator::ToNumber(Register reg) {
Register RegisterAllocator::ToRegister(int num) {
ASSERT(num >= 0 && num < kNumRegisters);
const Register kRegisters[] =
{ rax, rbx, rcx, rdx, rdi, r8, r9, r14, r15, r11, r12 };
{ rax, rbx, rcx, rdx, rdi, r8, r9, r14, r11, r12 };
return kRegisters[num];
}
......
......@@ -33,7 +33,7 @@ namespace internal {
class RegisterAllocatorConstants : public AllStatic {
public:
static const int kNumRegisters = 11;
static const int kNumRegisters = 10;
static const int kInvalidRegister = -1;
};
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment