Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(16)

Unified Diff: src/arm/simulator-arm.cc

Issue 1128009: Replace the constant pool access ldr instructions with movw/movt, and remove ... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/arm/simulator-arm.cc
===================================================================
--- src/arm/simulator-arm.cc (revision 4311)
+++ src/arm/simulator-arm.cc (working copy)
@@ -433,7 +433,123 @@
#undef XSTR
}
+static const int kICachePageSize = 0x1000;
+static const int kICachePageMask = 0xfff;
+static const int kICachePageShift = 12;
+static const int kICacheLineLength = 4;
+static const int kICacheLineMask = 3;
+static const int kPageSpace = kICachePageSize
++ kICachePageSize / kICacheLineLength;
+
+static bool ICacheMatch(void* one, void* two) {
+ ASSERT((reinterpret_cast<intptr_t>(one) & kICachePageMask) == 0);
+ return one == two;
+}
+
+
+static uint32_t ICacheHash(void* key) {
+ return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(key)) >> 2;
+}
+
+
+static char* CacheValid(char* cache_page, int offset) {
+ return &cache_page[kICachePageSize + offset / kICacheLineLength];
+}
+
+
+static bool AllOnOnePage(uintptr_t start, int size) {
+ intptr_t start_page = (start & ~kICachePageMask);
+ intptr_t end_page = ((start + size) & ~kICachePageMask);
+ return start_page == end_page;
+}
+
+
+void Simulator::FlushICache(void* start_addr, size_t size) {
+ intptr_t start = reinterpret_cast<intptr_t>(start_addr);
+ int intra_line = (start & kICacheLineMask);
+ start -= intra_line;
+ size += intra_line;
+ size = ((size - 1) | kICacheLineMask) + 1;
+ int offset = (start & kICachePageMask);
+ while (!AllOnOnePage(start, size - 1)) {
+ int bytes_to_flush = kICachePageSize - offset;
+ FlushOnePage(start, bytes_to_flush);
+ start += bytes_to_flush;
+ size -= bytes_to_flush;
+ ASSERT_EQ(0, start & kICachePageMask);
+ offset = 0;
+ }
+ if (size != 0) {
+ FlushOnePage(start, size);
+ }
+}
+
+
+char* Simulator::GetCachePage(void* page) {
+ v8::internal::HashMap::Entry* entry = i_cache_.Lookup(page,
+ ICacheHash(page),
+ true);
+ if (entry->value == NULL) {
+ char* new_page = new char[kPageSpace];
+ // Set the ICache to invalid for the new pages.
+ memset(new_page, 1, kPageSpace);
+ entry->value = new_page;
+ // printf("New cache allocated from %p to %p\n",
+ // (void*)(new_page), (void*)(new_page + kPageSpace));
+ }
+ return reinterpret_cast<char*>(entry->value);
+}
+
+
+// Flush from start up to and not including start + size.
+void Simulator::FlushOnePage(intptr_t start, int size) {
+ // printf("Flushing icache from %p to %p\n",
+ // (void*)start, (void*)(start + size));
+ ASSERT(size <= kICachePageSize);
+ ASSERT(AllOnOnePage(start, size - 1));
+ ASSERT((start & kICacheLineMask) == 0);
+ ASSERT((size & kICacheLineMask) == 0);
+ void* page = reinterpret_cast<void*>(start & (~kICachePageMask));
+ int offset = (start & kICachePageMask);
+ char* cache_page = GetCachePage(page);
+ char* valid_bytemap = CacheValid(cache_page, offset);
+ // printf("Zero bytes from %p to %p\n", (void*)valid_bytemap,
+ // (void*)(valid_bytemap + size / kICacheLineLength));
+ memset(valid_bytemap, 0, size / kICacheLineLength);
+}
+
+
+void Simulator::CheckICache(Instr* instr) {
+ intptr_t address = reinterpret_cast<intptr_t>(instr);
+ void* page = reinterpret_cast<void*>(address & (~kICachePageMask));
+ void* line = reinterpret_cast<void*>(address & (~kICacheLineMask));
+ int offset = (address & kICachePageMask);
+ char* cache_page = GetCachePage(page);
+ char* cache_valid_byte = CacheValid(cache_page, offset);
+ bool cache_hit = (*cache_valid_byte != 0);
+ char* cached_insn = cache_page + (offset & ~kICacheLineMask);
+ if (cache_hit) {
+ // Check that the data in memory matches the contents of the I-cache.
+ // printf("Checked cache byte at %p\n", (void*)cache_valid_byte);
+ // printf("Check instructions in cache for %p from %p to %p\n",
+ // (void*)instr, (void*)cached_insn,
+ // (void*)(cached_insn + kICacheLineLength));
+ CHECK(memcmp(reinterpret_cast<void*>(instr),
+ cache_page + offset,
+ Instr::kInstrSize) == 0);
+ } {
+ // Cache miss. Load memory into the cache.
+ // printf("Set instructions in cache for %p from %p to %p\n",
+ // (void*)instr, (void*)cached_insn,
+ // (void*)(cached_insn + kICacheLineLength));
+ memcpy(cached_insn, line, Instr::kInstrSize);
+ // printf("Set cache byte at %p\n", (void*)cache_valid_byte);
+ *cache_valid_byte = 1;
+ }
+}
+
+
// Create one simulator per thread and keep it in thread local storage.
static v8::internal::Thread::LocalStorageKey simulator_key;
@@ -449,7 +565,7 @@
}
-Simulator::Simulator() {
+Simulator::Simulator() : i_cache_(&ICacheMatch) {
Initialize();
// Setup simulator support first. Some of this information is needed to
// setup the architecture state.
@@ -514,6 +630,9 @@
swi_instruction_((AL << 28) | (0xf << 24) | call_rt_redirected),
fp_return_(fp_return),
next_(list_) {
+ assembler::arm::Simulator::current()->
+ FlushICache(reinterpret_cast<void*>(&swi_instruction_),
+ Instr::kInstrSize);
list_ = this;
}
@@ -1569,7 +1688,9 @@
SetNZFlags(alu_out);
SetCFlag(shifter_carry_out);
} else {
- UNIMPLEMENTED();
+ // Format(instr, "movw'cond 'rd, 'imm");
+ alu_out = instr->ImmedMovwMovtField();
+ set_register(rd, alu_out);
}
break;
}
@@ -1610,7 +1731,10 @@
SetCFlag(!BorrowFrom(rn_val, shifter_operand));
SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, false));
} else {
- UNIMPLEMENTED();
+ // Format(instr, "movt'cond 'rd, 'imm");
+ alu_out = (get_register(rd) & 0xffff) |
+ (instr->ImmedMovwMovtField() << 16);
+ set_register(rd, alu_out);
}
break;
}
@@ -2272,6 +2396,7 @@
// Executes the current instruction.
void Simulator::InstructionDecode(Instr* instr) {
+ CheckICache(instr);
pc_modified_ = false;
if (::v8::internal::FLAG_trace_sim) {
disasm::NameConverter converter;
@@ -2466,7 +2591,6 @@
return address;
}
-
} } // namespace assembler::arm
#endif // !defined(__arm__)
« src/arm/macro-assembler-arm.cc ('K') | « src/arm/simulator-arm.h ('k') | src/assembler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698