OLD | NEW |
---|---|
1 // Copyright 2008 the V8 project authors. All rights reserved. | 1 // Copyright 2008 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 30 matching lines...) Expand all Loading... | |
41 using ::v8::internal::Object; | 41 using ::v8::internal::Object; |
42 using ::v8::internal::PrintF; | 42 using ::v8::internal::PrintF; |
43 using ::v8::internal::OS; | 43 using ::v8::internal::OS; |
44 using ::v8::internal::ReadLine; | 44 using ::v8::internal::ReadLine; |
45 using ::v8::internal::DeleteArray; | 45 using ::v8::internal::DeleteArray; |
46 | 46 |
47 // This macro provides a platform independent use of sscanf. The reason for | 47 // This macro provides a platform independent use of sscanf. The reason for |
48 // SScanF not beeing implemented in a platform independent was through | 48 // SScanF not beeing implemented in a platform independent was through |
49 // ::v8::internal::OS in the same way as SNPrintF is that the Windows C Run-Time | 49 // ::v8::internal::OS in the same way as SNPrintF is that the Windows C Run-Time |
50 // Library does not provide vsscanf. | 50 // Library does not provide vsscanf. |
51 #ifdef WIN32 | |
52 #define SScanF sscanf_s | |
53 #else | |
54 #define SScanF sscanf // NOLINT | 51 #define SScanF sscanf // NOLINT |
55 #endif | |
56 | 52 |
57 // The Debugger class is used by the simulator while debugging simulated ARM | 53 // The Debugger class is used by the simulator while debugging simulated ARM |
58 // code. | 54 // code. |
59 class Debugger { | 55 class Debugger { |
60 public: | 56 public: |
61 explicit Debugger(Simulator* sim); | 57 explicit Debugger(Simulator* sim); |
62 ~Debugger(); | 58 ~Debugger(); |
63 | 59 |
64 void Stop(Instr* instr); | 60 void Stop(Instr* instr); |
65 void Debug(); | 61 void Debug(); |
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
375 // allocated stack area. To be safe in potential stack underflows we leave | 371 // allocated stack area. To be safe in potential stack underflows we leave |
376 // some buffer below. | 372 // some buffer below. |
377 registers_[sp] = reinterpret_cast<int32_t>(stack_) + stack_size - 64; | 373 registers_[sp] = reinterpret_cast<int32_t>(stack_) + stack_size - 64; |
378 // The lr and pc are initialized to a known bad value that will cause an | 374 // The lr and pc are initialized to a known bad value that will cause an |
379 // access violation if the simulator ever tries to execute it. | 375 // access violation if the simulator ever tries to execute it. |
380 registers_[pc] = bad_lr; | 376 registers_[pc] = bad_lr; |
381 registers_[lr] = bad_lr; | 377 registers_[lr] = bad_lr; |
382 } | 378 } |
383 | 379 |
384 | 380 |
385 // This is the Simulator singleton. Currently only one thread is supported by | 381 // Create one simulator per thread and keep it in thread local storage. |
386 // V8. If we had multiple threads, then we should have a Simulator instance on | 382 static v8::internal::Thread::LocalStorageKey simulator_key = |
387 // a per thread basis. | 383 v8::internal::Thread::CreateThreadLocalKey(); |
388 static Simulator* the_sim = NULL; | |
389 | 384 |
390 | 385 // Get the active Simulator for the current thread. |
391 // Get the active Simulator for the current thread. See comment above about | |
392 // using a singleton currently. | |
393 Simulator* Simulator::current() { | 386 Simulator* Simulator::current() { |
394 if (the_sim == NULL) { | 387 Simulator* sim = reinterpret_cast<Simulator*>( |
395 the_sim = new Simulator(); | 388 v8::internal::Thread::GetThreadLocal(simulator_key)); |
389 if (sim == NULL) { | |
390 sim = new Simulator(); | |
391 v8::internal::Thread::SetThreadLocal(simulator_key, sim); | |
iposva
2008/11/12 20:16:42
Since there is no AttachCurrentThread/DetachCurren
| |
396 } | 392 } |
397 return the_sim; | 393 return sim; |
398 } | 394 } |
399 | 395 |
400 | 396 |
401 // Sets the register in the architecture state. It will also deal with updating | 397 // Sets the register in the architecture state. It will also deal with updating |
402 // Simulator internal state for special registers such as PC. | 398 // Simulator internal state for special registers such as PC. |
403 void Simulator::set_register(int reg, int32_t value) { | 399 void Simulator::set_register(int reg, int32_t value) { |
404 ASSERT((reg >= 0) && (reg < num_registers)); | 400 ASSERT((reg >= 0) && (reg < num_registers)); |
405 if (reg == pc) { | 401 if (reg == pc) { |
406 pc_modified_ = true; | 402 pc_modified_ = true; |
407 } | 403 } |
(...skipping 1080 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1488 } | 1484 } |
1489 } | 1485 } |
1490 } | 1486 } |
1491 if (!pc_modified_) { | 1487 if (!pc_modified_) { |
1492 set_register(pc, reinterpret_cast<int32_t>(instr) + Instr::kInstrSize); | 1488 set_register(pc, reinterpret_cast<int32_t>(instr) + Instr::kInstrSize); |
1493 } | 1489 } |
1494 } | 1490 } |
1495 | 1491 |
1496 | 1492 |
1497 // | 1493 // |
1498 void Simulator::execute() { | 1494 void Simulator::Execute() { |
1499 // Get the PC to simulate. Cannot use the accessor here as we need the | 1495 // Get the PC to simulate. Cannot use the accessor here as we need the |
1500 // raw PC value and not the one used as input to arithmetic instructions. | 1496 // raw PC value and not the one used as input to arithmetic instructions. |
1501 int program_counter = get_pc(); | 1497 int program_counter = get_pc(); |
1502 | 1498 |
1503 if (::v8::internal::FLAG_stop_sim_at == 0) { | 1499 if (::v8::internal::FLAG_stop_sim_at == 0) { |
1504 // Fast version of the dispatch loop without checking whether the simulator | 1500 // Fast version of the dispatch loop without checking whether the simulator |
1505 // should be stopping at a particular executed instruction. | 1501 // should be stopping at a particular executed instruction. |
1506 while (program_counter != end_sim_pc) { | 1502 while (program_counter != end_sim_pc) { |
1507 Instr* instr = reinterpret_cast<Instr*>(program_counter); | 1503 Instr* instr = reinterpret_cast<Instr*>(program_counter); |
1508 icount_++; | 1504 icount_++; |
(...skipping 11 matching lines...) Expand all Loading... | |
1520 dbg.Debug(); | 1516 dbg.Debug(); |
1521 } else { | 1517 } else { |
1522 InstructionDecode(instr); | 1518 InstructionDecode(instr); |
1523 } | 1519 } |
1524 program_counter = get_pc(); | 1520 program_counter = get_pc(); |
1525 } | 1521 } |
1526 } | 1522 } |
1527 } | 1523 } |
1528 | 1524 |
1529 | 1525 |
1530 Object* Simulator::call(int32_t entry, int32_t p0, int32_t p1, int32_t p2, | 1526 Object* Simulator::Call(int32_t entry, int32_t p0, int32_t p1, int32_t p2, |
1531 int32_t p3, int32_t p4) { | 1527 int32_t p3, int32_t p4) { |
1532 // Setup parameters | 1528 // Setup parameters |
1533 set_register(r0, p0); | 1529 set_register(r0, p0); |
1534 set_register(r1, p1); | 1530 set_register(r1, p1); |
1535 set_register(r2, p2); | 1531 set_register(r2, p2); |
1536 set_register(r3, p3); | 1532 set_register(r3, p3); |
1537 intptr_t* stack_pointer = reinterpret_cast<intptr_t*>(get_register(sp)); | 1533 intptr_t* stack_pointer = reinterpret_cast<intptr_t*>(get_register(sp)); |
1538 *(--stack_pointer) = p4; | 1534 *(--stack_pointer) = p4; |
1539 set_register(sp, reinterpret_cast<int32_t>(stack_pointer)); | 1535 set_register(sp, reinterpret_cast<int32_t>(stack_pointer)); |
1540 | 1536 |
(...skipping 22 matching lines...) Expand all Loading... | |
1563 set_register(r4, callee_saved_value); | 1559 set_register(r4, callee_saved_value); |
1564 set_register(r5, callee_saved_value); | 1560 set_register(r5, callee_saved_value); |
1565 set_register(r6, callee_saved_value); | 1561 set_register(r6, callee_saved_value); |
1566 set_register(r7, callee_saved_value); | 1562 set_register(r7, callee_saved_value); |
1567 set_register(r8, callee_saved_value); | 1563 set_register(r8, callee_saved_value); |
1568 set_register(r9, callee_saved_value); | 1564 set_register(r9, callee_saved_value); |
1569 set_register(r10, callee_saved_value); | 1565 set_register(r10, callee_saved_value); |
1570 set_register(r11, callee_saved_value); | 1566 set_register(r11, callee_saved_value); |
1571 | 1567 |
1572 // Start the simulation | 1568 // Start the simulation |
1573 execute(); | 1569 Execute(); |
1574 | 1570 |
1575 // Check that the callee-saved registers have been preserved. | 1571 // Check that the callee-saved registers have been preserved. |
1576 CHECK_EQ(get_register(r4), callee_saved_value); | 1572 CHECK_EQ(get_register(r4), callee_saved_value); |
1577 CHECK_EQ(get_register(r5), callee_saved_value); | 1573 CHECK_EQ(get_register(r5), callee_saved_value); |
1578 CHECK_EQ(get_register(r6), callee_saved_value); | 1574 CHECK_EQ(get_register(r6), callee_saved_value); |
1579 CHECK_EQ(get_register(r7), callee_saved_value); | 1575 CHECK_EQ(get_register(r7), callee_saved_value); |
1580 CHECK_EQ(get_register(r8), callee_saved_value); | 1576 CHECK_EQ(get_register(r8), callee_saved_value); |
1581 CHECK_EQ(get_register(r9), callee_saved_value); | 1577 CHECK_EQ(get_register(r9), callee_saved_value); |
1582 CHECK_EQ(get_register(r10), callee_saved_value); | 1578 CHECK_EQ(get_register(r10), callee_saved_value); |
1583 CHECK_EQ(get_register(r11), callee_saved_value); | 1579 CHECK_EQ(get_register(r11), callee_saved_value); |
1584 | 1580 |
1585 // Restore callee-saved registers with the original value. | 1581 // Restore callee-saved registers with the original value. |
1586 set_register(r4, r4_val); | 1582 set_register(r4, r4_val); |
1587 set_register(r5, r5_val); | 1583 set_register(r5, r5_val); |
1588 set_register(r6, r6_val); | 1584 set_register(r6, r6_val); |
1589 set_register(r7, r7_val); | 1585 set_register(r7, r7_val); |
1590 set_register(r8, r8_val); | 1586 set_register(r8, r8_val); |
1591 set_register(r9, r9_val); | 1587 set_register(r9, r9_val); |
1592 set_register(r10, r10_val); | 1588 set_register(r10, r10_val); |
1593 set_register(r11, r11_val); | 1589 set_register(r11, r11_val); |
1594 | 1590 |
1595 int result = get_register(r0); | 1591 int result = get_register(r0); |
1596 return reinterpret_cast<Object*>(result); | 1592 return reinterpret_cast<Object*>(result); |
1597 } | 1593 } |
1598 | 1594 |
1599 } } // namespace assembler::arm | 1595 } } // namespace assembler::arm |
1600 | 1596 |
1601 #endif // !defined(__arm__) | 1597 #endif // !defined(__arm__) |
OLD | NEW |