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

Side by Side 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, 7 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 // shell when hit. 426 // shell when hit.
427 RedoBreakpoints(); 427 RedoBreakpoints();
428 428
429 #undef COMMAND_SIZE 429 #undef COMMAND_SIZE
430 #undef ARG_SIZE 430 #undef ARG_SIZE
431 431
432 #undef STR 432 #undef STR
433 #undef XSTR 433 #undef XSTR
434 } 434 }
435 435
436 static const int kICachePageSize = 0x1000;
437 static const int kICachePageMask = 0xfff;
438 static const int kICachePageShift = 12;
439 static const int kICacheLineLength = 4;
440 static const int kICacheLineMask = 3;
441 static const int kPageSpace = kICachePageSize
442 + kICachePageSize / kICacheLineLength;
443
444
445 static bool ICacheMatch(void* one, void* two) {
446 ASSERT((reinterpret_cast<intptr_t>(one) & kICachePageMask) == 0);
447 return one == two;
448 }
449
450
451 static uint32_t ICacheHash(void* key) {
452 return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(key)) >> 2;
453 }
454
455
456 static char* CacheValid(char* cache_page, int offset) {
457 return &cache_page[kICachePageSize + offset / kICacheLineLength];
458 }
459
460
461 static bool AllOnOnePage(uintptr_t start, int size) {
462 intptr_t start_page = (start & ~kICachePageMask);
463 intptr_t end_page = ((start + size) & ~kICachePageMask);
464 return start_page == end_page;
465 }
466
467
468 void Simulator::FlushICache(void* start_addr, size_t size) {
469 intptr_t start = reinterpret_cast<intptr_t>(start_addr);
470 int intra_line = (start & kICacheLineMask);
471 start -= intra_line;
472 size += intra_line;
473 size = ((size - 1) | kICacheLineMask) + 1;
474 int offset = (start & kICachePageMask);
475 while (!AllOnOnePage(start, size - 1)) {
476 int bytes_to_flush = kICachePageSize - offset;
477 FlushOnePage(start, bytes_to_flush);
478 start += bytes_to_flush;
479 size -= bytes_to_flush;
480 ASSERT_EQ(0, start & kICachePageMask);
481 offset = 0;
482 }
483 if (size != 0) {
484 FlushOnePage(start, size);
485 }
486 }
487
488
489 char* Simulator::GetCachePage(void* page) {
490 v8::internal::HashMap::Entry* entry = i_cache_.Lookup(page,
491 ICacheHash(page),
492 true);
493 if (entry->value == NULL) {
494 char* new_page = new char[kPageSpace];
495 // Set the ICache to invalid for the new pages.
496 memset(new_page, 1, kPageSpace);
497 entry->value = new_page;
498 // printf("New cache allocated from %p to %p\n",
499 // (void*)(new_page), (void*)(new_page + kPageSpace));
500 }
501 return reinterpret_cast<char*>(entry->value);
502 }
503
504
505 // Flush from start up to and not including start + size.
506 void Simulator::FlushOnePage(intptr_t start, int size) {
507 // printf("Flushing icache from %p to %p\n",
508 // (void*)start, (void*)(start + size));
509 ASSERT(size <= kICachePageSize);
510 ASSERT(AllOnOnePage(start, size - 1));
511 ASSERT((start & kICacheLineMask) == 0);
512 ASSERT((size & kICacheLineMask) == 0);
513 void* page = reinterpret_cast<void*>(start & (~kICachePageMask));
514 int offset = (start & kICachePageMask);
515 char* cache_page = GetCachePage(page);
516 char* valid_bytemap = CacheValid(cache_page, offset);
517 // printf("Zero bytes from %p to %p\n", (void*)valid_bytemap,
518 // (void*)(valid_bytemap + size / kICacheLineLength));
519 memset(valid_bytemap, 0, size / kICacheLineLength);
520 }
521
522
523 void Simulator::CheckICache(Instr* instr) {
524 intptr_t address = reinterpret_cast<intptr_t>(instr);
525 void* page = reinterpret_cast<void*>(address & (~kICachePageMask));
526 void* line = reinterpret_cast<void*>(address & (~kICacheLineMask));
527 int offset = (address & kICachePageMask);
528 char* cache_page = GetCachePage(page);
529 char* cache_valid_byte = CacheValid(cache_page, offset);
530 bool cache_hit = (*cache_valid_byte != 0);
531 char* cached_insn = cache_page + (offset & ~kICacheLineMask);
532 if (cache_hit) {
533 // Check that the data in memory matches the contents of the I-cache.
534 // printf("Checked cache byte at %p\n", (void*)cache_valid_byte);
535 // printf("Check instructions in cache for %p from %p to %p\n",
536 // (void*)instr, (void*)cached_insn,
537 // (void*)(cached_insn + kICacheLineLength));
538 CHECK(memcmp(reinterpret_cast<void*>(instr),
539 cache_page + offset,
540 Instr::kInstrSize) == 0);
541 } {
542 // Cache miss. Load memory into the cache.
543 // printf("Set instructions in cache for %p from %p to %p\n",
544 // (void*)instr, (void*)cached_insn,
545 // (void*)(cached_insn + kICacheLineLength));
546 memcpy(cached_insn, line, Instr::kInstrSize);
547 // printf("Set cache byte at %p\n", (void*)cache_valid_byte);
548 *cache_valid_byte = 1;
549 }
550 }
551
436 552
437 // Create one simulator per thread and keep it in thread local storage. 553 // Create one simulator per thread and keep it in thread local storage.
438 static v8::internal::Thread::LocalStorageKey simulator_key; 554 static v8::internal::Thread::LocalStorageKey simulator_key;
439 555
440 556
441 bool Simulator::initialized_ = false; 557 bool Simulator::initialized_ = false;
442 558
443 559
444 void Simulator::Initialize() { 560 void Simulator::Initialize() {
445 if (initialized_) return; 561 if (initialized_) return;
446 simulator_key = v8::internal::Thread::CreateThreadLocalKey(); 562 simulator_key = v8::internal::Thread::CreateThreadLocalKey();
447 initialized_ = true; 563 initialized_ = true;
448 ::v8::internal::ExternalReference::set_redirector(&RedirectExternalReference); 564 ::v8::internal::ExternalReference::set_redirector(&RedirectExternalReference);
449 } 565 }
450 566
451 567
452 Simulator::Simulator() { 568 Simulator::Simulator() : i_cache_(&ICacheMatch) {
453 Initialize(); 569 Initialize();
454 // Setup simulator support first. Some of this information is needed to 570 // Setup simulator support first. Some of this information is needed to
455 // setup the architecture state. 571 // setup the architecture state.
456 size_t stack_size = 1 * 1024*1024; // allocate 1MB for stack 572 size_t stack_size = 1 * 1024*1024; // allocate 1MB for stack
457 stack_ = reinterpret_cast<char*>(malloc(stack_size)); 573 stack_ = reinterpret_cast<char*>(malloc(stack_size));
458 pc_modified_ = false; 574 pc_modified_ = false;
459 icount_ = 0; 575 icount_ = 0;
460 break_pc_ = NULL; 576 break_pc_ = NULL;
461 break_instr_ = 0; 577 break_instr_ = 0;
462 578
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
507 // reference to a swi (software-interrupt) instruction that is handled by 623 // reference to a swi (software-interrupt) instruction that is handled by
508 // the simulator. We write the original destination of the jump just at a known 624 // the simulator. We write the original destination of the jump just at a known
509 // offset from the swi instruction so the simulator knows what to call. 625 // offset from the swi instruction so the simulator knows what to call.
510 class Redirection { 626 class Redirection {
511 public: 627 public:
512 Redirection(void* external_function, bool fp_return) 628 Redirection(void* external_function, bool fp_return)
513 : external_function_(external_function), 629 : external_function_(external_function),
514 swi_instruction_((AL << 28) | (0xf << 24) | call_rt_redirected), 630 swi_instruction_((AL << 28) | (0xf << 24) | call_rt_redirected),
515 fp_return_(fp_return), 631 fp_return_(fp_return),
516 next_(list_) { 632 next_(list_) {
633 assembler::arm::Simulator::current()->
634 FlushICache(reinterpret_cast<void*>(&swi_instruction_),
635 Instr::kInstrSize);
517 list_ = this; 636 list_ = this;
518 } 637 }
519 638
520 void* address_of_swi_instruction() { 639 void* address_of_swi_instruction() {
521 return reinterpret_cast<void*>(&swi_instruction_); 640 return reinterpret_cast<void*>(&swi_instruction_);
522 } 641 }
523 642
524 void* external_function() { return external_function_; } 643 void* external_function() { return external_function_; }
525 bool fp_return() { return fp_return_; } 644 bool fp_return() { return fp_return_; }
526 645
(...skipping 1035 matching lines...) Expand 10 before | Expand all | Expand 10 after
1562 } 1681 }
1563 1682
1564 case TST: { 1683 case TST: {
1565 if (instr->HasS()) { 1684 if (instr->HasS()) {
1566 // Format(instr, "tst'cond 'rn, 'shift_rm"); 1685 // Format(instr, "tst'cond 'rn, 'shift_rm");
1567 // Format(instr, "tst'cond 'rn, 'imm"); 1686 // Format(instr, "tst'cond 'rn, 'imm");
1568 alu_out = rn_val & shifter_operand; 1687 alu_out = rn_val & shifter_operand;
1569 SetNZFlags(alu_out); 1688 SetNZFlags(alu_out);
1570 SetCFlag(shifter_carry_out); 1689 SetCFlag(shifter_carry_out);
1571 } else { 1690 } else {
1572 UNIMPLEMENTED(); 1691 // Format(instr, "movw'cond 'rd, 'imm");
1692 alu_out = instr->ImmedMovwMovtField();
1693 set_register(rd, alu_out);
1573 } 1694 }
1574 break; 1695 break;
1575 } 1696 }
1576 1697
1577 case TEQ: { 1698 case TEQ: {
1578 if (instr->HasS()) { 1699 if (instr->HasS()) {
1579 // Format(instr, "teq'cond 'rn, 'shift_rm"); 1700 // Format(instr, "teq'cond 'rn, 'shift_rm");
1580 // Format(instr, "teq'cond 'rn, 'imm"); 1701 // Format(instr, "teq'cond 'rn, 'imm");
1581 alu_out = rn_val ^ shifter_operand; 1702 alu_out = rn_val ^ shifter_operand;
1582 SetNZFlags(alu_out); 1703 SetNZFlags(alu_out);
(...skipping 20 matching lines...) Expand all
1603 1724
1604 case CMP: { 1725 case CMP: {
1605 if (instr->HasS()) { 1726 if (instr->HasS()) {
1606 // Format(instr, "cmp'cond 'rn, 'shift_rm"); 1727 // Format(instr, "cmp'cond 'rn, 'shift_rm");
1607 // Format(instr, "cmp'cond 'rn, 'imm"); 1728 // Format(instr, "cmp'cond 'rn, 'imm");
1608 alu_out = rn_val - shifter_operand; 1729 alu_out = rn_val - shifter_operand;
1609 SetNZFlags(alu_out); 1730 SetNZFlags(alu_out);
1610 SetCFlag(!BorrowFrom(rn_val, shifter_operand)); 1731 SetCFlag(!BorrowFrom(rn_val, shifter_operand));
1611 SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, false)); 1732 SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, false));
1612 } else { 1733 } else {
1613 UNIMPLEMENTED(); 1734 // Format(instr, "movt'cond 'rd, 'imm");
1735 alu_out = (get_register(rd) & 0xffff) |
1736 (instr->ImmedMovwMovtField() << 16);
1737 set_register(rd, alu_out);
1614 } 1738 }
1615 break; 1739 break;
1616 } 1740 }
1617 1741
1618 case CMN: { 1742 case CMN: {
1619 if (instr->HasS()) { 1743 if (instr->HasS()) {
1620 // Format(instr, "cmn'cond 'rn, 'shift_rm"); 1744 // Format(instr, "cmn'cond 'rn, 'shift_rm");
1621 // Format(instr, "cmn'cond 'rn, 'imm"); 1745 // Format(instr, "cmn'cond 'rn, 'imm");
1622 alu_out = rn_val + shifter_operand; 1746 alu_out = rn_val + shifter_operand;
1623 SetNZFlags(alu_out); 1747 SetNZFlags(alu_out);
(...skipping 641 matching lines...) Expand 10 before | Expand all | Expand 10 after
2265 break; 2389 break;
2266 } 2390 }
2267 } else { 2391 } else {
2268 UNIMPLEMENTED(); // Not used by V8. 2392 UNIMPLEMENTED(); // Not used by V8.
2269 } 2393 }
2270 } 2394 }
2271 2395
2272 2396
2273 // Executes the current instruction. 2397 // Executes the current instruction.
2274 void Simulator::InstructionDecode(Instr* instr) { 2398 void Simulator::InstructionDecode(Instr* instr) {
2399 CheckICache(instr);
2275 pc_modified_ = false; 2400 pc_modified_ = false;
2276 if (::v8::internal::FLAG_trace_sim) { 2401 if (::v8::internal::FLAG_trace_sim) {
2277 disasm::NameConverter converter; 2402 disasm::NameConverter converter;
2278 disasm::Disassembler dasm(converter); 2403 disasm::Disassembler dasm(converter);
2279 // use a reasonably large buffer 2404 // use a reasonably large buffer
2280 v8::internal::EmbeddedVector<char, 256> buffer; 2405 v8::internal::EmbeddedVector<char, 256> buffer;
2281 dasm.InstructionDecode(buffer, 2406 dasm.InstructionDecode(buffer,
2282 reinterpret_cast<byte*>(instr)); 2407 reinterpret_cast<byte*>(instr));
2283 PrintF(" 0x%08x %s\n", instr, buffer.start()); 2408 PrintF(" 0x%08x %s\n", instr, buffer.start());
2284 } 2409 }
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
2459 2584
2460 2585
2461 uintptr_t Simulator::PopAddress() { 2586 uintptr_t Simulator::PopAddress() {
2462 int current_sp = get_register(sp); 2587 int current_sp = get_register(sp);
2463 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp); 2588 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp);
2464 uintptr_t address = *stack_slot; 2589 uintptr_t address = *stack_slot;
2465 set_register(sp, current_sp + sizeof(uintptr_t)); 2590 set_register(sp, current_sp + sizeof(uintptr_t));
2466 return address; 2591 return address;
2467 } 2592 }
2468 2593
2469
2470 } } // namespace assembler::arm 2594 } } // namespace assembler::arm
2471 2595
2472 #endif // !defined(__arm__) 2596 #endif // !defined(__arm__)
OLDNEW
« 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