112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Copyright 2011 the V8 project authors. All rights reserved. 212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be 312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// found in the LICENSE file. 412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Declares a Simulator for MIPS instructions if we are not generating a native 712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// MIPS binary. This Simulator allows us to run and debug MIPS code generation 812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// on regular desktop machines. 912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// V8 calls into generated code by "calling" the CALL_GENERATED_CODE macro, 1012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// which will start execution in the Simulator or forwards to the real entry 1112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// on a MIPS HW platform. 1212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 1312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#ifndef V8_MIPS_SIMULATOR_MIPS_H_ 1412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#define V8_MIPS_SIMULATOR_MIPS_H_ 1512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 1612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#include "src/allocation.h" 1712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#include "src/mips64/constants-mips64.h" 1812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 1912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#if !defined(USE_SIMULATOR) 2012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Running without a simulator on a native mips platform. 2112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 2212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgnamespace v8 { 2312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgnamespace internal { 2412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 2512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// When running without a simulator we call the entry directly. 2612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4) \ 2712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org entry(p0, p1, p2, p3, p4) 2812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 2912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 3012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Call the generated regexp code directly. The code at the entry address 3112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// should act as a function matching the type arm_regexp_matcher. 3212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// The fifth (or ninth) argument is a dummy that reserves the space used for 3312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// the return address added by the ExitFrame in native calls. 3412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#ifdef MIPS_ABI_N64 3512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgtypedef int (*mips_regexp_matcher)(String* input, 3612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org int64_t start_offset, 3712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org const byte* input_start, 3812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org const byte* input_end, 3912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org int* output, 4012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org int64_t output_size, 4112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Address stack_base, 4212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org int64_t direct_call, 4312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org void* return_address, 4412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Isolate* isolate); 4512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 4612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7, p8) \ 4712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org (FUNCTION_CAST<mips_regexp_matcher>(entry)( \ 4812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org p0, p1, p2, p3, p4, p5, p6, p7, NULL, p8)) 4912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 5012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#else // O32 Abi. 5112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 5212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgtypedef int (*mips_regexp_matcher)(String* input, 5312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org int32_t start_offset, 5412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org const byte* input_start, 5512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org const byte* input_end, 5612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org void* return_address, 5712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org int* output, 5812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org int32_t output_size, 5912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Address stack_base, 6012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org int32_t direct_call, 6112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Isolate* isolate); 6212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 6312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7, p8) \ 6412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org (FUNCTION_CAST<mips_regexp_matcher>(entry)( \ 6512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org p0, p1, p2, p3, NULL, p4, p5, p6, p7, p8)) 6612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 6712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#endif // MIPS_ABI_N64 6812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 6912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 7012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// The stack limit beyond which we will throw stack overflow errors in 7112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// generated code. Because generated code on mips uses the C stack, we 7212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// just use the C stack limit. 7312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgclass SimulatorStack : public v8::internal::AllStatic { 7412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org public: 7512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org static inline uintptr_t JsLimitFromCLimit(Isolate* isolate, 7612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org uintptr_t c_limit) { 7712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org return c_limit; 7812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org } 7912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 8012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org static inline uintptr_t RegisterCTryCatch(uintptr_t try_catch_address) { 8112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org return try_catch_address; 8212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org } 8312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 8412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org static inline void UnregisterCTryCatch() { } 8512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}; 8612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 8712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org} } // namespace v8::internal 8812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 8912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Calculated the stack limit beyond which we will throw stack overflow errors. 9012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// This macro must be called from a C++ method. It relies on being able to take 9112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// the address of "this" to get a value on the current execution stack and then 9212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// calculates the stack limit based on that value. 9312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// NOTE: The check for overflow is not safe as there is no guarantee that the 9412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// running thread has its stack in all memory up to address 0x00000000. 9512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#define GENERATED_CODE_STACK_LIMIT(limit) \ 9612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org (reinterpret_cast<uintptr_t>(this) >= limit ? \ 9712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org reinterpret_cast<uintptr_t>(this) - limit : 0) 9812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 9912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#else // !defined(USE_SIMULATOR) 10012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Running with a simulator. 10112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 10212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#include "src/assembler.h" 10312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#include "src/hashmap.h" 10412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 10512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgnamespace v8 { 10612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgnamespace internal { 10712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 10812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// ----------------------------------------------------------------------------- 10912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Utility functions 11012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 11112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgclass CachePage { 11212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org public: 11312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org static const int LINE_VALID = 0; 11412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org static const int LINE_INVALID = 1; 11512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 11612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org static const int kPageShift = 12; 11712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org static const int kPageSize = 1 << kPageShift; 11812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org static const int kPageMask = kPageSize - 1; 11912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org static const int kLineShift = 2; // The cache line is only 4 bytes right now. 12012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org static const int kLineLength = 1 << kLineShift; 12112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org static const int kLineMask = kLineLength - 1; 12212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 12312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org CachePage() { 12412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org memset(&validity_map_, LINE_INVALID, sizeof(validity_map_)); 12512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org } 12612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 12712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org char* ValidityByte(int offset) { 12812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org return &validity_map_[offset >> kLineShift]; 12912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org } 13012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 13112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org char* CachedData(int offset) { 13212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org return &data_[offset]; 13312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org } 13412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 13512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org private: 13612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org char data_[kPageSize]; // The cached data. 13712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org static const int kValidityMapSize = kPageSize >> kLineShift; 13812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org char validity_map_[kValidityMapSize]; // One byte per line. 13912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}; 14012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 14112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgclass Simulator { 14212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org public: 14312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org friend class MipsDebugger; 14412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 14512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Registers are declared in order. See SMRL chapter 2. 14612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org enum Register { 14712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org no_reg = -1, 14812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org zero_reg = 0, 14912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org at, 15012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org v0, v1, 15112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org a0, a1, a2, a3, a4, a5, a6, a7, 15212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org t0, t1, t2, t3, 15312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org s0, s1, s2, s3, s4, s5, s6, s7, 15412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org t8, t9, 15512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org k0, k1, 15612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org gp, 15712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org sp, 15812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org s8, 15912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org ra, 16012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // LO, HI, and pc. 16112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org LO, 16212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org HI, 16312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org pc, // pc must be the last register. 16412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org kNumSimuRegisters, 16512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // aliases 16612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org fp = s8 16712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org }; 16812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 16912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Coprocessor registers. 17012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Generated code will always use doubles. So we will only use even registers. 17112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org enum FPURegister { 17212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, 17312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org f12, f13, f14, f15, // f12 and f14 are arguments FPURegisters. 17412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, 17512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org f26, f27, f28, f29, f30, f31, 17612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org kNumFPURegisters 17712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org }; 17812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 17912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org explicit Simulator(Isolate* isolate); 18012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org ~Simulator(); 18112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 18212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // The currently executing Simulator instance. Potentially there can be one 18312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // for each native thread. 18412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org static Simulator* current(v8::internal::Isolate* isolate); 18512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 18612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Accessors for register state. Reading the pc value adheres to the MIPS 18712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // architecture specification and is off by a 8 from the currently executing 18812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // instruction. 18912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org void set_register(int reg, int64_t value); 19012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org void set_register_word(int reg, int32_t value); 19112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org void set_dw_register(int dreg, const int* dbl); 19212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org int64_t get_register(int reg) const; 19312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org double get_double_from_register_pair(int reg); 19412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Same for FPURegisters. 19512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org void set_fpu_register(int fpureg, int64_t value); 19612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org void set_fpu_register_word(int fpureg, int32_t value); 19712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org void set_fpu_register_hi_word(int fpureg, int32_t value); 19812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org void set_fpu_register_float(int fpureg, float value); 19912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org void set_fpu_register_double(int fpureg, double value); 20012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org int64_t get_fpu_register(int fpureg) const; 20112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org int32_t get_fpu_register_word(int fpureg) const; 20212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org int32_t get_fpu_register_signed_word(int fpureg) const; 203a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org int32_t get_fpu_register_hi_word(int fpureg) const; 20412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org float get_fpu_register_float(int fpureg) const; 20512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org double get_fpu_register_double(int fpureg) const; 20612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org void set_fcsr_bit(uint32_t cc, bool value); 20712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org bool test_fcsr_bit(uint32_t cc); 20812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org bool set_fcsr_round_error(double original, double rounded); 20912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org bool set_fcsr_round64_error(double original, double rounded); 21012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 21112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Special case of set_register and get_register to access the raw PC value. 21212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org void set_pc(int64_t value); 21312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org int64_t get_pc() const; 21412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 21512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Address get_sp() { 21612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org return reinterpret_cast<Address>(static_cast<intptr_t>(get_register(sp))); 21712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org } 21812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 21912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Accessor to the internal simulator stack area. 22012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org uintptr_t StackLimit() const; 22112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 22212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Executes MIPS instructions until the PC reaches end_sim_pc. 22312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org void Execute(); 22412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 22512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Call on program start. 22612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org static void Initialize(Isolate* isolate); 22712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 22812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // V8 generally calls into generated JS code with 5 parameters and into 22912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // generated RegExp code with 7 parameters. This is a convenience function, 23012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // which sets up the simulator state and grabs the result on return. 23112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org int64_t Call(byte* entry, int argument_count, ...); 23212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Alternative: call a 2-argument double function. 23312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org double CallFP(byte* entry, double d0, double d1); 23412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 23512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Push an address onto the JS stack. 23612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org uintptr_t PushAddress(uintptr_t address); 23712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 23812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Pop an address from the JS stack. 23912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org uintptr_t PopAddress(); 24012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 24112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Debugger input. 24212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org void set_last_debugger_input(char* input); 24312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org char* last_debugger_input() { return last_debugger_input_; } 24412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 24512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // ICache checking. 24612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org static void FlushICache(v8::internal::HashMap* i_cache, void* start, 24712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org size_t size); 24812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 24912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Returns true if pc register contains one of the 'special_values' defined 25012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // below (bad_ra, end_sim_pc). 25112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org bool has_bad_pc() const; 25212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 25312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org private: 25412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org enum special_values { 25512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Known bad pc value to ensure that the simulator does not execute 25612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // without being properly setup. 25712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org bad_ra = -1, 25812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // A pc value used to signal the simulator to stop execution. Generally 25912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // the ra is set to this value on transition from native C code to 26012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // simulated execution, so that the simulator can "return" to the native 26112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // C code. 26212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org end_sim_pc = -2, 26312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Unpredictable value. 26412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Unpredictable = 0xbadbeaf 26512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org }; 26612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 26712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Unsupported instructions use Format to print an error and stop execution. 26812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org void Format(Instruction* instr, const char* format); 26912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 27012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Read and write memory. 27112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org inline uint32_t ReadBU(int64_t addr); 27212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org inline int32_t ReadB(int64_t addr); 27312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org inline void WriteB(int64_t addr, uint8_t value); 27412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org inline void WriteB(int64_t addr, int8_t value); 27512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 27612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org inline uint16_t ReadHU(int64_t addr, Instruction* instr); 27712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org inline int16_t ReadH(int64_t addr, Instruction* instr); 27812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Note: Overloaded on the sign of the value. 27912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org inline void WriteH(int64_t addr, uint16_t value, Instruction* instr); 28012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org inline void WriteH(int64_t addr, int16_t value, Instruction* instr); 28112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 28212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org inline uint32_t ReadWU(int64_t addr, Instruction* instr); 28312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org inline int32_t ReadW(int64_t addr, Instruction* instr); 28412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org inline void WriteW(int64_t addr, int32_t value, Instruction* instr); 28512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org inline int64_t Read2W(int64_t addr, Instruction* instr); 28612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org inline void Write2W(int64_t addr, int64_t value, Instruction* instr); 28712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 28812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org inline double ReadD(int64_t addr, Instruction* instr); 28912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org inline void WriteD(int64_t addr, double value, Instruction* instr); 29012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 29112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Helper for debugging memory access. 29212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org inline void DieOrDebug(); 29312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 29412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Helpers for data value tracing. 29512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org enum TraceType { 29612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org BYTE, 29712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org HALF, 29812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org WORD, 29912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org DWORD 30012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // DFLOAT - Floats may have printing issues due to paired lwc1's 30112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org }; 30212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 30312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org void TraceRegWr(int64_t value); 30412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org void TraceMemWr(int64_t addr, int64_t value, TraceType t); 30512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org void TraceMemRd(int64_t addr, int64_t value); 30612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 30712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Operations depending on endianness. 30812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Get Double Higher / Lower word. 30912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org inline int32_t GetDoubleHIW(double* addr); 31012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org inline int32_t GetDoubleLOW(double* addr); 31112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Set Double Higher / Lower word. 31212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org inline int32_t SetDoubleHIW(double* addr); 31312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org inline int32_t SetDoubleLOW(double* addr); 31412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 31512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Executing is handled based on the instruction type. 31612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org void DecodeTypeRegister(Instruction* instr); 31712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 31812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Helper function for DecodeTypeRegister. 31912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org void ConfigureTypeRegister(Instruction* instr, 32012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org int64_t* alu_out, 32112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org int64_t* i64hilo, 32212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org uint64_t* u64hilo, 32312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org int64_t* next_pc, 32412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org int64_t* return_addr_reg, 32512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org bool* do_interrupt, 32612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org int64_t* result128H, 32712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org int64_t* result128L); 32812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 32912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org void DecodeTypeImmediate(Instruction* instr); 33012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org void DecodeTypeJump(Instruction* instr); 33112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 33212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Used for breakpoints and traps. 33312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org void SoftwareInterrupt(Instruction* instr); 33412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 33512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Stop helper functions. 33612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org bool IsWatchpoint(uint64_t code); 33712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org void PrintWatchpoint(uint64_t code); 33812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org void HandleStop(uint64_t code, Instruction* instr); 33912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org bool IsStopInstruction(Instruction* instr); 34012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org bool IsEnabledStop(uint64_t code); 34112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org void EnableStop(uint64_t code); 34212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org void DisableStop(uint64_t code); 34312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org void IncreaseStopCounter(uint64_t code); 34412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org void PrintStopInfo(uint64_t code); 34512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 34612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 34712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Executes one instruction. 34812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org void InstructionDecode(Instruction* instr); 34912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Execute one instruction placed in a branch delay slot. 35012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org void BranchDelayInstructionDecode(Instruction* instr) { 35112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org if (instr->InstructionBits() == nopInstr) { 35212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Short-cut generic nop instructions. They are always valid and they 35312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // never change the simulator state. 35412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org return; 35512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org } 35612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 35712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org if (instr->IsForbiddenInBranchDelay()) { 35812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org V8_Fatal(__FILE__, __LINE__, 35912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "Eror:Unexpected %i opcode in a branch delay slot.", 36012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org instr->OpcodeValue()); 36112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org } 36212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org InstructionDecode(instr); 36312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org } 36412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 36512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // ICache. 36612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org static void CheckICache(v8::internal::HashMap* i_cache, Instruction* instr); 36712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org static void FlushOnePage(v8::internal::HashMap* i_cache, intptr_t start, 36812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org int size); 36912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org static CachePage* GetCachePage(v8::internal::HashMap* i_cache, void* page); 37012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 37112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org enum Exception { 37212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org none, 37312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org kIntegerOverflow, 37412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org kIntegerUnderflow, 37512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org kDivideByZero, 37612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org kNumExceptions 37712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org }; 37812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org int16_t exceptions[kNumExceptions]; 37912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 38012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Exceptions. 38112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org void SignalExceptions(); 38212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 38312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Runtime call support. 38412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org static void* RedirectExternalReference(void* external_function, 38512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org ExternalReference::Type type); 38612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 38712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Handle arguments and return value for runtime FP functions. 38812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org void GetFpArgs(double* x, double* y, int32_t* z); 38912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org void SetFpResult(const double& result); 39012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 39112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org void CallInternal(byte* entry); 39212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 39312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Architecture state. 39412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Registers. 39512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org int64_t registers_[kNumSimuRegisters]; 39612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Coprocessor Registers. 39712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org int64_t FPUregisters_[kNumFPURegisters]; 39812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // FPU control register. 39912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org uint32_t FCSR_; 40012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 40112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Simulator support. 40212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Allocate 1MB for stack. 40312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org size_t stack_size_; 40412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org char* stack_; 40512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org bool pc_modified_; 40612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org int64_t icount_; 40712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org int break_count_; 40812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org EmbeddedVector<char, 128> trace_buf_; 40912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 41012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Debugger input. 41112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org char* last_debugger_input_; 41212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 41312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Icache simulation. 41412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org v8::internal::HashMap* i_cache_; 41512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 41612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org v8::internal::Isolate* isolate_; 41712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 41812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Registered breakpoints. 41912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Instruction* break_pc_; 42012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Instr break_instr_; 42112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 42212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // Stop is disabled if bit 31 is set. 42312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org static const uint32_t kStopDisabledBit = 1 << 31; 42412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 42512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // A stop is enabled, meaning the simulator will stop when meeting the 42612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // instruction, if bit 31 of watched_stops_[code].count is unset. 42712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // The value watched_stops_[code].count & ~(1 << 31) indicates how many times 42812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // the breakpoint was hit or gone through. 42912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org struct StopCountAndDesc { 43012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org uint32_t count; 43112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org char* desc; 43212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org }; 43312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org StopCountAndDesc watched_stops_[kMaxStopCode + 1]; 43412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}; 43512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 43612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 43712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// When running with the simulator transition into simulated execution at this 43812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// point. 43912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4) \ 44012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org reinterpret_cast<Object*>(Simulator::current(Isolate::Current())->Call( \ 44112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org FUNCTION_ADDR(entry), 5, p0, p1, p2, p3, p4)) 44212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 44312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#ifdef MIPS_ABI_N64 44412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7, p8) \ 44512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Simulator::current(Isolate::Current())->Call( \ 44612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org entry, 10, p0, p1, p2, p3, p4, p5, p6, p7, NULL, p8) 44712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#else // Must be O32 Abi. 44812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7, p8) \ 44912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Simulator::current(Isolate::Current())->Call( \ 45012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org entry, 10, p0, p1, p2, p3, NULL, p4, p5, p6, p7, p8) 45112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#endif // MIPS_ABI_N64 45212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 45312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 45412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// The simulator has its own stack. Thus it has a different stack limit from 45512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// the C-based native code. Setting the c_limit to indicate a very small 45612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// stack cause stack overflow errors, since the simulator ignores the input. 45712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// This is unlikely to be an issue in practice, though it might cause testing 45812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// trouble down the line. 45912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgclass SimulatorStack : public v8::internal::AllStatic { 46012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org public: 46112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org static inline uintptr_t JsLimitFromCLimit(Isolate* isolate, 46212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org uintptr_t c_limit) { 46312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org return Simulator::current(isolate)->StackLimit(); 46412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org } 46512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 46612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org static inline uintptr_t RegisterCTryCatch(uintptr_t try_catch_address) { 46712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Simulator* sim = Simulator::current(Isolate::Current()); 46812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org return sim->PushAddress(try_catch_address); 46912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org } 47012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 47112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org static inline void UnregisterCTryCatch() { 47212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Simulator::current(Isolate::Current())->PopAddress(); 47312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org } 47412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}; 47512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 47612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org} } // namespace v8::internal 47712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 47812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#endif // !defined(USE_SIMULATOR) 47912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#endif // V8_MIPS_SIMULATOR_MIPS_H_ 480