diff options
Diffstat (limited to 'deps/v8/src/ppc/simulator-ppc.h')
-rw-r--r-- | deps/v8/src/ppc/simulator-ppc.h | 418 |
1 files changed, 0 insertions, 418 deletions
diff --git a/deps/v8/src/ppc/simulator-ppc.h b/deps/v8/src/ppc/simulator-ppc.h deleted file mode 100644 index 02d1b5a350..0000000000 --- a/deps/v8/src/ppc/simulator-ppc.h +++ /dev/null @@ -1,418 +0,0 @@ -// Copyright 2014 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Declares a Simulator for PPC instructions if we are not generating a native -// PPC binary. This Simulator allows us to run and debug PPC code generation on -// regular desktop machines. -// V8 calls into generated code via the GeneratedCode wrapper, -// which will start execution in the Simulator or forwards to the real entry -// on a PPC HW platform. - -#ifndef V8_PPC_SIMULATOR_PPC_H_ -#define V8_PPC_SIMULATOR_PPC_H_ - -// globals.h defines USE_SIMULATOR. -#include "src/globals.h" - -#if defined(USE_SIMULATOR) -// Running with a simulator. - -#include "src/allocation.h" -#include "src/base/lazy-instance.h" -#include "src/base/platform/mutex.h" - -#include "src/assembler.h" -#include "src/base/hashmap.h" -#include "src/ppc/constants-ppc.h" -#include "src/simulator-base.h" - -namespace v8 { -namespace internal { - -class CachePage { - public: - static const int LINE_VALID = 0; - static const int LINE_INVALID = 1; - - static const int kPageShift = 12; - static const int kPageSize = 1 << kPageShift; - static const int kPageMask = kPageSize - 1; - static const int kLineShift = 2; // The cache line is only 4 bytes right now. - static const int kLineLength = 1 << kLineShift; - static const int kLineMask = kLineLength - 1; - - CachePage() { memset(&validity_map_, LINE_INVALID, sizeof(validity_map_)); } - - char* ValidityByte(int offset) { - return &validity_map_[offset >> kLineShift]; - } - - char* CachedData(int offset) { return &data_[offset]; } - - private: - char data_[kPageSize]; // The cached data. - static const int kValidityMapSize = kPageSize >> kLineShift; - char validity_map_[kValidityMapSize]; // One byte per line. -}; - -class Simulator : public SimulatorBase { - public: - friend class PPCDebugger; - enum Register { - no_reg = -1, - r0 = 0, - sp, - r2, - r3, - r4, - r5, - r6, - r7, - r8, - r9, - r10, - r11, - r12, - r13, - r14, - r15, - r16, - r17, - r18, - r19, - r20, - r21, - r22, - r23, - r24, - r25, - r26, - r27, - r28, - r29, - r30, - fp, - kNumGPRs = 32, - d0 = 0, - d1, - d2, - d3, - d4, - d5, - d6, - d7, - d8, - d9, - d10, - d11, - d12, - d13, - d14, - d15, - d16, - d17, - d18, - d19, - d20, - d21, - d22, - d23, - d24, - d25, - d26, - d27, - d28, - d29, - d30, - d31, - kNumFPRs = 32 - }; - - explicit Simulator(Isolate* isolate); - ~Simulator(); - - // The currently executing Simulator instance. Potentially there can be one - // for each native thread. - static Simulator* current(v8::internal::Isolate* isolate); - - // Accessors for register state. - void set_register(int reg, intptr_t value); - intptr_t get_register(int reg) const; - double get_double_from_register_pair(int reg); - void set_d_register_from_double(int dreg, const double dbl) { - DCHECK(dreg >= 0 && dreg < kNumFPRs); - *bit_cast<double*>(&fp_registers_[dreg]) = dbl; - } - double get_double_from_d_register(int dreg) { - DCHECK(dreg >= 0 && dreg < kNumFPRs); - return *bit_cast<double*>(&fp_registers_[dreg]); - } - void set_d_register(int dreg, int64_t value) { - DCHECK(dreg >= 0 && dreg < kNumFPRs); - fp_registers_[dreg] = value; - } - int64_t get_d_register(int dreg) { - DCHECK(dreg >= 0 && dreg < kNumFPRs); - return fp_registers_[dreg]; - } - - // Special case of set_register and get_register to access the raw PC value. - void set_pc(intptr_t value); - intptr_t get_pc() const; - - Address get_sp() const { return static_cast<Address>(get_register(sp)); } - - // Accessor to the internal simulator stack area. - uintptr_t StackLimit(uintptr_t c_limit) const; - - // Executes PPC instructions until the PC reaches end_sim_pc. - void Execute(); - - template <typename Return, typename... Args> - Return Call(Address entry, Args... args) { - return VariadicCall<Return>(this, &Simulator::CallImpl, entry, args...); - } - - // Alternative: call a 2-argument double function. - void CallFP(Address entry, double d0, double d1); - int32_t CallFPReturnsInt(Address entry, double d0, double d1); - double CallFPReturnsDouble(Address entry, double d0, double d1); - - // Push an address onto the JS stack. - uintptr_t PushAddress(uintptr_t address); - - // Pop an address from the JS stack. - uintptr_t PopAddress(); - - // Debugger input. - void set_last_debugger_input(char* input); - char* last_debugger_input() { return last_debugger_input_; } - - // Redirection support. - static void SetRedirectInstruction(Instruction* instruction); - - // ICache checking. - static bool ICacheMatch(void* one, void* two); - static void FlushICache(base::CustomMatcherHashMap* i_cache, void* start, - size_t size); - - // Returns true if pc register contains one of the 'special_values' defined - // below (bad_lr, end_sim_pc). - bool has_bad_pc() const; - - private: - enum special_values { - // Known bad pc value to ensure that the simulator does not execute - // without being properly setup. - bad_lr = -1, - // A pc value used to signal the simulator to stop execution. Generally - // the lr is set to this value on transition from native C code to - // simulated execution, so that the simulator can "return" to the native - // C code. - end_sim_pc = -2 - }; - - intptr_t CallImpl(Address entry, int argument_count, - const intptr_t* arguments); - - enum BCType { BC_OFFSET, BC_LINK_REG, BC_CTR_REG }; - - // Unsupported instructions use Format to print an error and stop execution. - void Format(Instruction* instr, const char* format); - - // Helper functions to set the conditional flags in the architecture state. - bool CarryFrom(int32_t left, int32_t right, int32_t carry = 0); - bool BorrowFrom(int32_t left, int32_t right); - bool OverflowFrom(int32_t alu_out, int32_t left, int32_t right, - bool addition); - - // Helper functions to decode common "addressing" modes - int32_t GetShiftRm(Instruction* instr, bool* carry_out); - int32_t GetImm(Instruction* instr, bool* carry_out); - void ProcessPUW(Instruction* instr, int num_regs, int operand_size, - intptr_t* start_address, intptr_t* end_address); - void HandleRList(Instruction* instr, bool load); - void HandleVList(Instruction* inst); - void SoftwareInterrupt(Instruction* instr); - - // Stop helper functions. - inline bool isStopInstruction(Instruction* instr); - inline bool isWatchedStop(uint32_t bkpt_code); - inline bool isEnabledStop(uint32_t bkpt_code); - inline void EnableStop(uint32_t bkpt_code); - inline void DisableStop(uint32_t bkpt_code); - inline void IncreaseStopCounter(uint32_t bkpt_code); - void PrintStopInfo(uint32_t code); - - // Read and write memory. - template <typename T> - inline void Read(uintptr_t address, T* value) { - base::MutexGuard lock_guard(&GlobalMonitor::Get()->mutex); - memcpy(value, reinterpret_cast<const char*>(address), sizeof(T)); - } - - template <typename T> - inline void ReadEx(uintptr_t address, T* value) { - base::MutexGuard lock_guard(&GlobalMonitor::Get()->mutex); - GlobalMonitor::Get()->NotifyLoadExcl( - address, static_cast<TransactionSize>(sizeof(T)), - isolate_->thread_id()); - memcpy(value, reinterpret_cast<const char*>(address), sizeof(T)); - } - - template <typename T> - inline void Write(uintptr_t address, T value) { - base::MutexGuard lock_guard(&GlobalMonitor::Get()->mutex); - GlobalMonitor::Get()->NotifyStore(address, - static_cast<TransactionSize>(sizeof(T)), - isolate_->thread_id()); - memcpy(reinterpret_cast<char*>(address), &value, sizeof(T)); - } - - template <typename T> - inline int32_t WriteEx(uintptr_t address, T value) { - base::MutexGuard lock_guard(&GlobalMonitor::Get()->mutex); - if (GlobalMonitor::Get()->NotifyStoreExcl( - address, static_cast<TransactionSize>(sizeof(T)), - isolate_->thread_id())) { - memcpy(reinterpret_cast<char*>(address), &value, sizeof(T)); - return 0; - } else { - return 1; - } - } - -#define RW_VAR_LIST(V) \ - V(DWU, uint64_t) \ - V(DW, int64_t) \ - V(WU, uint32_t) \ - V(W, int32_t) V(HU, uint16_t) V(H, int16_t) V(BU, uint8_t) V(B, int8_t) - -#define GENERATE_RW_FUNC(size, type) \ - inline type Read##size(uintptr_t addr); \ - inline type ReadEx##size(uintptr_t addr); \ - inline void Write##size(uintptr_t addr, type value); \ - inline int32_t WriteEx##size(uintptr_t addr, type value); - - RW_VAR_LIST(GENERATE_RW_FUNC) -#undef GENERATE_RW_FUNC - - void Trace(Instruction* instr); - void SetCR0(intptr_t result, bool setSO = false); - void ExecuteBranchConditional(Instruction* instr, BCType type); - void ExecuteGeneric(Instruction* instr); - - void SetFPSCR(int bit) { fp_condition_reg_ |= (1 << (31 - bit)); } - void ClearFPSCR(int bit) { fp_condition_reg_ &= ~(1 << (31 - bit)); } - - // Executes one instruction. - void ExecuteInstruction(Instruction* instr); - - // ICache. - static void CheckICache(base::CustomMatcherHashMap* i_cache, - Instruction* instr); - static void FlushOnePage(base::CustomMatcherHashMap* i_cache, intptr_t start, - int size); - static CachePage* GetCachePage(base::CustomMatcherHashMap* i_cache, - void* page); - - // Handle arguments and return value for runtime FP functions. - void GetFpArgs(double* x, double* y, intptr_t* z); - void SetFpResult(const double& result); - void TrashCallerSaveRegisters(); - - void CallInternal(Address entry); - - // Architecture state. - // Saturating instructions require a Q flag to indicate saturation. - // There is currently no way to read the CPSR directly, and thus read the Q - // flag, so this is left unimplemented. - intptr_t registers_[kNumGPRs]; - int32_t condition_reg_; - int32_t fp_condition_reg_; - intptr_t special_reg_lr_; - intptr_t special_reg_pc_; - intptr_t special_reg_ctr_; - int32_t special_reg_xer_; - - int64_t fp_registers_[kNumFPRs]; - - // Simulator support. - char* stack_; - static const size_t stack_protection_size_ = 256 * kPointerSize; - bool pc_modified_; - int icount_; - - // Debugger input. - char* last_debugger_input_; - - // Registered breakpoints. - Instruction* break_pc_; - Instr break_instr_; - - v8::internal::Isolate* isolate_; - - // A stop is watched if its code is less than kNumOfWatchedStops. - // Only watched stops support enabling/disabling and the counter feature. - static const uint32_t kNumOfWatchedStops = 256; - - // Breakpoint is disabled if bit 31 is set. - static const uint32_t kStopDisabledBit = 1 << 31; - - // A stop is enabled, meaning the simulator will stop when meeting the - // instruction, if bit 31 of watched_stops_[code].count is unset. - // The value watched_stops_[code].count & ~(1 << 31) indicates how many times - // the breakpoint was hit or gone through. - struct StopCountAndDesc { - uint32_t count; - char* desc; - }; - StopCountAndDesc watched_stops_[kNumOfWatchedStops]; - - // Synchronization primitives. See ARM DDI 0406C.b, A2.9. - enum class MonitorAccess { - Open, - Exclusive, - }; - - enum class TransactionSize { - None = 0, - Byte = 1, - HalfWord = 2, - Word = 4, - DWord = 8, - }; - - class GlobalMonitor { - public: - // Exposed so it can be accessed by Simulator::{Read,Write}Ex*. - base::Mutex mutex; - - void NotifyLoadExcl(uintptr_t addr, TransactionSize size, - ThreadId thread_id); - void NotifyStore(uintptr_t addr, TransactionSize size, ThreadId thread_id); - bool NotifyStoreExcl(uintptr_t addr, TransactionSize size, - ThreadId thread_id); - - static GlobalMonitor* Get(); - - private: - // Private constructor. Call {GlobalMonitor::Get()} to get the singleton. - GlobalMonitor() = default; - friend class base::LeakyObject<GlobalMonitor>; - - void Clear(); - - MonitorAccess access_state_ = MonitorAccess::Open; - uintptr_t tagged_addr_ = 0; - TransactionSize size_ = TransactionSize::None; - ThreadId thread_id_ = ThreadId::Invalid(); - }; -}; - -} // namespace internal -} // namespace v8 - -#endif // defined(USE_SIMULATOR) -#endif // V8_PPC_SIMULATOR_PPC_H_ |