Revision: 4739
Author: [email protected]
Date: Thu May 27 03:25:33 2010
Log: X64: Many small tweaks and more usages of "load smi as int32".
Review URL: http://codereview.chromium.org/2266003
http://code.google.com/p/v8/source/detail?r=4739
Modified:
/branches/bleeding_edge/src/x64/assembler-x64.h
/branches/bleeding_edge/src/x64/codegen-x64.cc
/branches/bleeding_edge/src/x64/ic-x64.cc
/branches/bleeding_edge/src/x64/macro-assembler-x64.cc
/branches/bleeding_edge/src/x64/macro-assembler-x64.h
=======================================
--- /branches/bleeding_edge/src/x64/assembler-x64.h Wed May 26 03:02:07 2010
+++ /branches/bleeding_edge/src/x64/assembler-x64.h Thu May 27 03:25:33 2010
@@ -307,7 +307,7 @@
private:
byte rex_;
- byte buf_[10];
+ byte buf_[6];
// The number of bytes in buf_.
unsigned int len_;
=======================================
--- /branches/bleeding_edge/src/x64/codegen-x64.cc Wed May 26 09:11:30 2010
+++ /branches/bleeding_edge/src/x64/codegen-x64.cc Thu May 27 03:25:33 2010
@@ -891,10 +891,11 @@
// 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
@@ -4675,7 +4676,7 @@
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.
@@ -4699,11 +4700,10 @@
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_);
@@ -4717,14 +4717,15 @@
__ 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_);
@@ -4755,29 +4756,30 @@
// 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.
@@ -4848,16 +4850,13 @@
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();
@@ -8653,14 +8652,13 @@
// 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));
@@ -8680,12 +8678,12 @@
// 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
@@ -11193,8 +11191,7 @@
// 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
@@ -11203,8 +11200,7 @@
// 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
@@ -11232,8 +11228,7 @@
// 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
@@ -11242,8 +11237,7 @@
// 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
@@ -11272,15 +11266,15 @@
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);
}
@@ -11293,38 +11287,39 @@
// Copy characters using rep movs of doublewords. Align destination on 4
byte
// boundary before starting rep movs. Copy remaining characters after
running
// 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.
@@ -11332,9 +11327,9 @@
__ 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);
@@ -11354,13 +11349,11 @@
// 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);
@@ -11384,8 +11377,8 @@
// 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;
@@ -11415,10 +11408,10 @@
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);
@@ -11495,9 +11488,7 @@
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));
@@ -11509,7 +11500,6 @@
// 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);
=======================================
--- /branches/bleeding_edge/src/x64/ic-x64.cc Wed May 26 07:23:19 2010
+++ /branches/bleeding_edge/src/x64/ic-x64.cc Thu May 27 03:25:33 2010
@@ -104,8 +104,7 @@
const int kCapacityOffset =
StringDictionary::kHeaderSize +
StringDictionary::kCapacityIndex * kPointerSize;
- __ movq(r2, FieldOperand(r0, kCapacityOffset));
- __ SmiToInteger32(r2, r2);
+ __ SmiToInteger32(r2, FieldOperand(r0, kCapacityOffset));
__ decl(r2);
// Generate an unrolled loop that performs a few probes before
@@ -202,8 +201,8 @@
__ xorl(r0, r1);
// Compute capacity mask.
- __ movq(r1, FieldOperand(elements, NumberDictionary::kCapacityOffset));
- __ SmiToInteger32(r1, r1);
+ __ SmiToInteger32(r1,
+ FieldOperand(elements,
NumberDictionary::kCapacityOffset));
__ decl(r1);
// Generate an unrolled loop that performs a few probes before giving up.
=======================================
--- /branches/bleeding_edge/src/x64/macro-assembler-x64.cc Wed May 26
03:02:07 2010
+++ /branches/bleeding_edge/src/x64/macro-assembler-x64.cc Thu May 27
03:25:33 2010
@@ -571,6 +571,11 @@
}
shr(dst, Immediate(kSmiShift));
}
+
+
+void MacroAssembler::SmiToInteger32(Register dst, const Operand& src) {
+ movl(dst, Operand(src, kSmiShift / kBitsPerByte));
+}
void MacroAssembler::SmiToInteger64(Register dst, Register src) {
@@ -614,7 +619,7 @@
void MacroAssembler::SmiCompare(const Operand& dst, Smi* src) {
- cmpl(Operand(dst, kIntSize), Immediate(src->value()));
+ cmpl(Operand(dst, kSmiShift / kBitsPerByte), Immediate(src->value()));
}
@@ -916,7 +921,7 @@
void MacroAssembler::SmiAddConstant(const Operand& dst, Smi* constant) {
if (constant->value() != 0) {
- addl(Operand(dst, kIntSize), Immediate(constant->value()));
+ addl(Operand(dst, kSmiShift / kBitsPerByte),
Immediate(constant->value()));
}
}
=======================================
--- /branches/bleeding_edge/src/x64/macro-assembler-x64.h Wed May 26
02:24:44 2010
+++ /branches/bleeding_edge/src/x64/macro-assembler-x64.h Thu May 27
03:25:33 2010
@@ -210,6 +210,7 @@
// Convert smi to 32-bit integer. I.e., not sign extended into
// high 32 bits of destination.
void SmiToInteger32(Register dst, Register src);
+ void SmiToInteger32(Register dst, const Operand& src);
// Convert smi to 64-bit integer (sign extended if necessary).
void SmiToInteger64(Register dst, Register src);
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev