Index: src/x64/codegen-x64.cc |
diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc |
index 6f6670aa3b26c6a4b6e9657210923515b2620df1..e2ec4d0ae4a2f0f4b0166a69cdd190e6142515f0 100644 |
--- a/src/x64/codegen-x64.cc |
+++ b/src/x64/codegen-x64.cc |
@@ -857,10 +857,11 @@ void CodeGenerator::CallApplyLazy(Expression* applicand, |
// avoid copying too many arguments to avoid stack overflows. |
__ bind(&adapted); |
static const uint32_t kArgumentsLimit = 1 * KB; |
- __ movq(rax, Operand(rdx, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
- __ SmiToInteger32(rax, rax); |
- __ movq(rcx, rax); |
- __ cmpq(rax, Immediate(kArgumentsLimit)); |
+ __ SmiToInteger32(rax, |
+ Operand(rdx, |
+ ArgumentsAdaptorFrameConstants::kLengthOffset)); |
+ __ movl(rcx, rax); |
+ __ cmpl(rax, Immediate(kArgumentsLimit)); |
__ j(above, &build_args); |
// Loop through the arguments pushing them onto the execution |
@@ -4512,7 +4513,7 @@ class DeferredSearchCache: public DeferredCode { |
virtual void Generate(); |
private: |
- Register dst_; // on invocation index of finger (as Smi), on exit |
+ Register dst_; // on invocation index of finger (as int32), on exit |
// holds value being looked up. |
Register cache_; // instance of JSFunctionResultCache. |
Register key_; // key being looked up. |
@@ -4536,11 +4537,10 @@ void DeferredSearchCache::Generate() { |
Immediate kEntriesIndexImm = Immediate(JSFunctionResultCache::kEntriesIndex); |
Immediate kEntrySizeImm = Immediate(JSFunctionResultCache::kEntrySize); |
- __ SmiToInteger32(dst_, dst_); |
// Check the cache from finger to start of the cache. |
__ bind(&first_loop); |
- __ subq(dst_, kEntrySizeImm); |
- __ cmpq(dst_, kEntriesIndexImm); |
+ __ subl(dst_, kEntrySizeImm); |
+ __ cmpl(dst_, kEntriesIndexImm); |
__ j(less, &search_further); |
__ cmpq(ArrayElement(cache_, dst_), key_); |
@@ -4554,14 +4554,15 @@ void DeferredSearchCache::Generate() { |
__ bind(&search_further); |
// Check the cache from end of cache up to finger. |
- __ movq(dst_, FieldOperand(cache_, JSFunctionResultCache::kCacheSizeOffset)); |
- __ movq(scratch_, FieldOperand(cache_, JSFunctionResultCache::kFingerOffset)); |
- __ SmiToInteger32(dst_, dst_); |
- __ SmiToInteger32(scratch_, scratch_); |
+ __ SmiToInteger32(dst_, |
+ FieldOperand(cache_, |
+ JSFunctionResultCache::kCacheSizeOffset)); |
+ __ SmiToInteger32(scratch_, |
+ FieldOperand(cache_, JSFunctionResultCache::kFingerOffset)); |
__ bind(&second_loop); |
- __ subq(dst_, kEntrySizeImm); |
- __ cmpq(dst_, scratch_); |
+ __ subl(dst_, kEntrySizeImm); |
+ __ cmpl(dst_, scratch_); |
__ j(less_equal, &cache_miss); |
__ cmpq(ArrayElement(cache_, dst_), key_); |
@@ -4592,29 +4593,30 @@ void DeferredSearchCache::Generate() { |
// Check if we could add new entry to cache. |
__ movl(rbx, FieldOperand(rcx, FixedArray::kLengthOffset)); |
- __ movq(r9, FieldOperand(rcx, JSFunctionResultCache::kCacheSizeOffset)); |
- __ SmiToInteger32(r9, r9); |
- __ cmpq(rbx, r9); |
+ __ SmiToInteger32(r9, |
+ FieldOperand(rcx, JSFunctionResultCache::kCacheSizeOffset)); |
+ __ cmpl(rbx, r9); |
__ j(greater, &add_new_entry); |
// Check if we could evict entry after finger. |
- __ movq(rdx, FieldOperand(rcx, JSFunctionResultCache::kFingerOffset)); |
- __ SmiToInteger32(rdx, rdx); |
+ __ SmiToInteger32(rdx, |
+ FieldOperand(rcx, JSFunctionResultCache::kFingerOffset)); |
__ addq(rdx, kEntrySizeImm); |
Label forward; |
__ cmpq(rbx, rdx); |
__ j(greater, &forward); |
// Need to wrap over the cache. |
- __ movq(rdx, kEntriesIndexImm); |
+ __ movl(rdx, kEntriesIndexImm); |
__ bind(&forward); |
__ Integer32ToSmi(r9, rdx); |
__ jmp(&update_cache); |
__ bind(&add_new_entry); |
// r9 holds cache size as int. |
- __ movq(rdx, r9); |
+ __ movl(rdx, r9); |
__ Integer32ToSmi(r9, r9); |
- __ SmiAddConstant(rbx, r9, Smi::FromInt(JSFunctionResultCache::kEntrySize)); |
+ __ leal(rbx, Operand(rdx, JSFunctionResultCache::kEntrySize)); |
+ __ Integer32ToSmi(rbx, rbx); |
__ movq(FieldOperand(rcx, JSFunctionResultCache::kCacheSizeOffset), rbx); |
// Update the cache itself. |
@@ -4685,16 +4687,13 @@ void CodeGenerator::GenerateGetFromCache(ZoneList<Expression*>* args) { |
const int kFingerOffset = |
FixedArray::OffsetOfElementAt(JSFunctionResultCache::kFingerIndex); |
// tmp.reg() now holds finger offset as a smi. |
- __ movq(tmp.reg(), FieldOperand(cache.reg(), kFingerOffset)); |
- SmiIndex index = |
- masm()->SmiToIndex(kScratchRegister, tmp.reg(), kPointerSizeLog2); |
+ __ SmiToInteger32(tmp.reg(), FieldOperand(cache.reg(), kFingerOffset)); |
__ cmpq(key.reg(), FieldOperand(cache.reg(), |
- index.reg, index.scale, |
+ tmp.reg(), times_pointer_size, |
FixedArray::kHeaderSize)); |
- // Do NOT alter index.reg or tmp.reg() before cmpq below. |
deferred->Branch(not_equal); |
__ movq(tmp.reg(), FieldOperand(cache.reg(), |
- index.reg, index.scale, |
+ tmp.reg(), times_pointer_size, |
FixedArray::kHeaderSize + kPointerSize)); |
deferred->BindExit(); |
@@ -8491,14 +8490,13 @@ void RegExpExecStub::Generate(MacroAssembler* masm) { |
// Argument 3: Start of string data |
Label setup_two_byte, setup_rest; |
__ testb(rdi, rdi); |
- __ movq(rdi, FieldOperand(rax, String::kLengthOffset)); |
__ j(zero, &setup_two_byte); |
- __ SmiToInteger32(rdi, rdi); |
+ __ SmiToInteger32(rdi, FieldOperand(rax, String::kLengthOffset)); |
__ lea(arg4, FieldOperand(rax, rdi, times_1, SeqAsciiString::kHeaderSize)); |
__ lea(arg3, FieldOperand(rax, rbx, times_1, SeqAsciiString::kHeaderSize)); |
__ jmp(&setup_rest); |
__ bind(&setup_two_byte); |
- __ SmiToInteger32(rdi, rdi); |
+ __ SmiToInteger32(rdi, FieldOperand(rax, String::kLengthOffset)); |
__ lea(arg4, FieldOperand(rax, rdi, times_2, SeqTwoByteString::kHeaderSize)); |
__ lea(arg3, FieldOperand(rax, rbx, times_2, SeqTwoByteString::kHeaderSize)); |
@@ -8518,12 +8516,12 @@ void RegExpExecStub::Generate(MacroAssembler* masm) { |
// Check the result. |
Label success; |
- __ cmpq(rax, Immediate(NativeRegExpMacroAssembler::SUCCESS)); |
+ __ cmpl(rax, Immediate(NativeRegExpMacroAssembler::SUCCESS)); |
__ j(equal, &success); |
Label failure; |
- __ cmpq(rax, Immediate(NativeRegExpMacroAssembler::FAILURE)); |
+ __ cmpl(rax, Immediate(NativeRegExpMacroAssembler::FAILURE)); |
__ j(equal, &failure); |
- __ cmpq(rax, Immediate(NativeRegExpMacroAssembler::EXCEPTION)); |
+ __ cmpl(rax, Immediate(NativeRegExpMacroAssembler::EXCEPTION)); |
// If not exception it can only be retry. Handle that in the runtime system. |
__ j(not_equal, &runtime); |
// Result must now be exception. If there is no pending exception already a |
@@ -10984,8 +10982,7 @@ void StringAddStub::Generate(MacroAssembler* masm) { |
// Locate first character of result. |
__ addq(rcx, Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag)); |
// Locate first character of first argument |
- __ movq(rdi, FieldOperand(rax, String::kLengthOffset)); |
- __ SmiToInteger32(rdi, rdi); |
+ __ SmiToInteger32(rdi, FieldOperand(rax, String::kLengthOffset)); |
__ addq(rax, Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag)); |
// rax: first char of first argument |
// rbx: result string |
@@ -10994,8 +10991,7 @@ void StringAddStub::Generate(MacroAssembler* masm) { |
// rdi: length of first argument |
StringHelper::GenerateCopyCharacters(masm, rcx, rax, rdi, true); |
// Locate first character of second argument. |
- __ movq(rdi, FieldOperand(rdx, String::kLengthOffset)); |
- __ SmiToInteger32(rdi, rdi); |
+ __ SmiToInteger32(rdi, FieldOperand(rdx, String::kLengthOffset)); |
__ addq(rdx, Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag)); |
// rbx: result string |
// rcx: next character of result |
@@ -11023,8 +11019,7 @@ void StringAddStub::Generate(MacroAssembler* masm) { |
// Locate first character of result. |
__ addq(rcx, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); |
// Locate first character of first argument. |
- __ movq(rdi, FieldOperand(rax, String::kLengthOffset)); |
- __ SmiToInteger32(rdi, rdi); |
+ __ SmiToInteger32(rdi, FieldOperand(rax, String::kLengthOffset)); |
__ addq(rax, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); |
// rax: first char of first argument |
// rbx: result string |
@@ -11033,8 +11028,7 @@ void StringAddStub::Generate(MacroAssembler* masm) { |
// rdi: length of first argument |
StringHelper::GenerateCopyCharacters(masm, rcx, rax, rdi, false); |
// Locate first character of second argument. |
- __ movq(rdi, FieldOperand(rdx, String::kLengthOffset)); |
- __ SmiToInteger32(rdi, rdi); |
+ __ SmiToInteger32(rdi, FieldOperand(rdx, String::kLengthOffset)); |
__ addq(rdx, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); |
// rbx: result string |
// rcx: next character of result |
@@ -11063,15 +11057,15 @@ void StringHelper::GenerateCopyCharacters(MacroAssembler* masm, |
if (ascii) { |
__ movb(kScratchRegister, Operand(src, 0)); |
__ movb(Operand(dest, 0), kScratchRegister); |
- __ addq(src, Immediate(1)); |
- __ addq(dest, Immediate(1)); |
+ __ incq(src); |
+ __ incq(dest); |
} else { |
__ movzxwl(kScratchRegister, Operand(src, 0)); |
__ movw(Operand(dest, 0), kScratchRegister); |
__ addq(src, Immediate(2)); |
__ addq(dest, Immediate(2)); |
} |
- __ subl(count, Immediate(1)); |
+ __ decl(count); |
__ j(not_zero, &loop); |
} |
@@ -11084,38 +11078,39 @@ void StringHelper::GenerateCopyCharactersREP(MacroAssembler* masm, |
// Copy characters using rep movs of doublewords. Align destination on 4 byte |
// boundary before starting rep movs. Copy remaining characters after running |
William Hesse
2010/05/27 08:36:03
Where is the destination aligned to a 4-byte bound
|
// rep movs. |
+ // Count is positive int32, dest and src are character pointers. |
ASSERT(dest.is(rdi)); // rep movs destination |
ASSERT(src.is(rsi)); // rep movs source |
ASSERT(count.is(rcx)); // rep movs count |
// Nothing to do for zero characters. |
Label done; |
- __ testq(count, count); |
+ __ testl(count, count); |
__ j(zero, &done); |
// Make count the number of bytes to copy. |
if (!ascii) { |
ASSERT_EQ(2, sizeof(uc16)); // NOLINT |
- __ addq(count, count); |
+ __ addl(count, count); |
} |
// Don't enter the rep movs if there are less than 4 bytes to copy. |
Label last_bytes; |
- __ testq(count, Immediate(~7)); |
+ __ testl(count, Immediate(~7)); |
__ j(zero, &last_bytes); |
// Copy from edi to esi using rep movs instruction. |
- __ movq(kScratchRegister, count); |
- __ sar(count, Immediate(3)); // Number of doublewords to copy. |
+ __ movl(kScratchRegister, count); |
+ __ shr(count, Immediate(3)); // Number of doublewords to copy. |
__ repmovsq(); |
// Find number of bytes left. |
- __ movq(count, kScratchRegister); |
+ __ movl(count, kScratchRegister); |
__ and_(count, Immediate(7)); |
// Check if there are more bytes to copy. |
__ bind(&last_bytes); |
- __ testq(count, count); |
+ __ testl(count, count); |
__ j(zero, &done); |
// Copy remaining characters. |
@@ -11123,9 +11118,9 @@ void StringHelper::GenerateCopyCharactersREP(MacroAssembler* masm, |
__ bind(&loop); |
__ movb(kScratchRegister, Operand(src, 0)); |
__ movb(Operand(dest, 0), kScratchRegister); |
- __ addq(src, Immediate(1)); |
- __ addq(dest, Immediate(1)); |
- __ subq(count, Immediate(1)); |
+ __ incq(src); |
+ __ incq(dest); |
+ __ decl(count); |
__ j(not_zero, &loop); |
__ bind(&done); |
@@ -11145,13 +11140,11 @@ void StringHelper::GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm, |
// Make sure that both characters are not digits as such strings has a |
// different hash algorithm. Don't try to look for these in the symbol table. |
Label not_array_index; |
- __ movq(scratch, c1); |
- __ subq(scratch, Immediate(static_cast<int>('0'))); |
- __ cmpq(scratch, Immediate(static_cast<int>('9' - '0'))); |
+ __ leal(scratch, Operand(c1, -'0')); |
+ __ cmpl(scratch, Immediate(static_cast<int>('9' - '0'))); |
__ j(above, ¬_array_index); |
- __ movq(scratch, c2); |
- __ subq(scratch, Immediate(static_cast<int>('0'))); |
- __ cmpq(scratch, Immediate(static_cast<int>('9' - '0'))); |
+ __ leal(scratch, Operand(c2, -'0')); |
+ __ cmpl(scratch, Immediate(static_cast<int>('9' - '0'))); |
__ j(below_equal, not_found); |
__ bind(¬_array_index); |
@@ -11175,8 +11168,8 @@ void StringHelper::GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm, |
// Calculate capacity mask from the symbol table capacity. |
Register mask = scratch2; |
- __ movq(mask, FieldOperand(symbol_table, SymbolTable::kCapacityOffset)); |
- __ SmiToInteger32(mask, mask); |
+ __ SmiToInteger32(mask, |
+ FieldOperand(symbol_table, SymbolTable::kCapacityOffset)); |
__ decl(mask); |
Register undefined = scratch4; |
@@ -11206,10 +11199,10 @@ void StringHelper::GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm, |
Register candidate = scratch; // Scratch register contains candidate. |
ASSERT_EQ(1, SymbolTable::kEntrySize); |
__ movq(candidate, |
- FieldOperand(symbol_table, |
- scratch, |
- times_pointer_size, |
- SymbolTable::kElementsStartOffset)); |
+ FieldOperand(symbol_table, |
+ scratch, |
+ times_pointer_size, |
+ SymbolTable::kElementsStartOffset)); |
// If entry is undefined no string with this hash can be found. |
__ cmpq(candidate, undefined); |
@@ -11286,9 +11279,7 @@ void StringHelper::GenerateHashGetHash(MacroAssembler* masm, |
Register hash, |
Register scratch) { |
// hash += hash << 3; |
- __ movl(scratch, hash); |
- __ shll(scratch, Immediate(3)); |
- __ addl(hash, scratch); |
+ __ leal(hash, Operand(hash, hash, times_8, 0)); |
// hash ^= hash >> 11; |
__ movl(scratch, hash); |
__ sarl(scratch, Immediate(11)); |
@@ -11300,7 +11291,6 @@ void StringHelper::GenerateHashGetHash(MacroAssembler* masm, |
// if (hash == 0) hash = 27; |
Label hash_not_zero; |
- __ testl(hash, hash); |
__ j(not_zero, &hash_not_zero); |
__ movl(hash, Immediate(27)); |
__ bind(&hash_not_zero); |