183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org// Copyright 2011 the V8 project authors. All rights reserved. 25c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Redistribution and use in source and binary forms, with or without 35c838251403b0be9a882540f1922577abba4c872ager@chromium.org// modification, are permitted provided that the following conditions are 45c838251403b0be9a882540f1922577abba4c872ager@chromium.org// met: 55c838251403b0be9a882540f1922577abba4c872ager@chromium.org// 65c838251403b0be9a882540f1922577abba4c872ager@chromium.org// * Redistributions of source code must retain the above copyright 75c838251403b0be9a882540f1922577abba4c872ager@chromium.org// notice, this list of conditions and the following disclaimer. 85c838251403b0be9a882540f1922577abba4c872ager@chromium.org// * Redistributions in binary form must reproduce the above 95c838251403b0be9a882540f1922577abba4c872ager@chromium.org// copyright notice, this list of conditions and the following 105c838251403b0be9a882540f1922577abba4c872ager@chromium.org// disclaimer in the documentation and/or other materials provided 115c838251403b0be9a882540f1922577abba4c872ager@chromium.org// with the distribution. 125c838251403b0be9a882540f1922577abba4c872ager@chromium.org// * Neither the name of Google Inc. nor the names of its 135c838251403b0be9a882540f1922577abba4c872ager@chromium.org// contributors may be used to endorse or promote products derived 145c838251403b0be9a882540f1922577abba4c872ager@chromium.org// from this software without specific prior written permission. 155c838251403b0be9a882540f1922577abba4c872ager@chromium.org// 165c838251403b0be9a882540f1922577abba4c872ager@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 175c838251403b0be9a882540f1922577abba4c872ager@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 185c838251403b0be9a882540f1922577abba4c872ager@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 195c838251403b0be9a882540f1922577abba4c872ager@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 205c838251403b0be9a882540f1922577abba4c872ager@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 215c838251403b0be9a882540f1922577abba4c872ager@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 225c838251403b0be9a882540f1922577abba4c872ager@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 235c838251403b0be9a882540f1922577abba4c872ager@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 245c838251403b0be9a882540f1922577abba4c872ager@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 255c838251403b0be9a882540f1922577abba4c872ager@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 265c838251403b0be9a882540f1922577abba4c872ager@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 275c838251403b0be9a882540f1922577abba4c872ager@chromium.org 285c838251403b0be9a882540f1922577abba4c872ager@chromium.org 295c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Declares a Simulator for MIPS instructions if we are not generating a native 305c838251403b0be9a882540f1922577abba4c872ager@chromium.org// MIPS binary. This Simulator allows us to run and debug MIPS code generation 315c838251403b0be9a882540f1922577abba4c872ager@chromium.org// on regular desktop machines. 325c838251403b0be9a882540f1922577abba4c872ager@chromium.org// V8 calls into generated code by "calling" the CALL_GENERATED_CODE macro, 335c838251403b0be9a882540f1922577abba4c872ager@chromium.org// which will start execution in the Simulator or forwards to the real entry 345c838251403b0be9a882540f1922577abba4c872ager@chromium.org// on a MIPS HW platform. 355c838251403b0be9a882540f1922577abba4c872ager@chromium.org 365c838251403b0be9a882540f1922577abba4c872ager@chromium.org#ifndef V8_MIPS_SIMULATOR_MIPS_H_ 375c838251403b0be9a882540f1922577abba4c872ager@chromium.org#define V8_MIPS_SIMULATOR_MIPS_H_ 385c838251403b0be9a882540f1922577abba4c872ager@chromium.org 395c838251403b0be9a882540f1922577abba4c872ager@chromium.org#include "allocation.h" 407516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#include "constants-mips.h" 415c838251403b0be9a882540f1922577abba4c872ager@chromium.org 427516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#if !defined(USE_SIMULATOR) 437516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// Running without a simulator on a native mips platform. 447516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 457516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgnamespace v8 { 467516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgnamespace internal { 475c838251403b0be9a882540f1922577abba4c872ager@chromium.org 485c838251403b0be9a882540f1922577abba4c872ager@chromium.org// When running without a simulator we call the entry directly. 495c838251403b0be9a882540f1922577abba4c872ager@chromium.org#define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4) \ 507516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org entry(p0, p1, p2, p3, p4) 517516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 527516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgtypedef int (*mips_regexp_matcher)(String*, int, const byte*, const byte*, 53777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org void*, int*, int, Address, int, Isolate*); 5483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 557516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 567516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// Call the generated regexp code directly. The code at the entry address 577516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// should act as a function matching the type arm_regexp_matcher. 587516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// The fifth argument is a dummy that reserves the space used for 597516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// the return address added by the ExitFrame in native calls. 60777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7, p8) \ 6140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org (FUNCTION_CAST<mips_regexp_matcher>(entry)( \ 62777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org p0, p1, p2, p3, NULL, p4, p5, p6, p7, p8)) 637516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 647516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#define TRY_CATCH_FROM_ADDRESS(try_catch_address) \ 657516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org reinterpret_cast<TryCatch*>(try_catch_address) 665c838251403b0be9a882540f1922577abba4c872ager@chromium.org 675c838251403b0be9a882540f1922577abba4c872ager@chromium.org// The stack limit beyond which we will throw stack overflow errors in 685c838251403b0be9a882540f1922577abba4c872ager@chromium.org// generated code. Because generated code on mips uses the C stack, we 695c838251403b0be9a882540f1922577abba4c872ager@chromium.org// just use the C stack limit. 705c838251403b0be9a882540f1922577abba4c872ager@chromium.orgclass SimulatorStack : public v8::internal::AllStatic { 715c838251403b0be9a882540f1922577abba4c872ager@chromium.org public: 721c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org static inline uintptr_t JsLimitFromCLimit(Isolate* isolate, 731c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org uintptr_t c_limit) { 745c838251403b0be9a882540f1922577abba4c872ager@chromium.org return c_limit; 755c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 765c838251403b0be9a882540f1922577abba4c872ager@chromium.org 775c838251403b0be9a882540f1922577abba4c872ager@chromium.org static inline uintptr_t RegisterCTryCatch(uintptr_t try_catch_address) { 785c838251403b0be9a882540f1922577abba4c872ager@chromium.org return try_catch_address; 795c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 805c838251403b0be9a882540f1922577abba4c872ager@chromium.org 815c838251403b0be9a882540f1922577abba4c872ager@chromium.org static inline void UnregisterCTryCatch() { } 825c838251403b0be9a882540f1922577abba4c872ager@chromium.org}; 835c838251403b0be9a882540f1922577abba4c872ager@chromium.org 847516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} } // namespace v8::internal 857516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 865c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Calculated the stack limit beyond which we will throw stack overflow errors. 875c838251403b0be9a882540f1922577abba4c872ager@chromium.org// This macro must be called from a C++ method. It relies on being able to take 885c838251403b0be9a882540f1922577abba4c872ager@chromium.org// the address of "this" to get a value on the current execution stack and then 895c838251403b0be9a882540f1922577abba4c872ager@chromium.org// calculates the stack limit based on that value. 905c838251403b0be9a882540f1922577abba4c872ager@chromium.org// NOTE: The check for overflow is not safe as there is no guarantee that the 915c838251403b0be9a882540f1922577abba4c872ager@chromium.org// running thread has its stack in all memory up to address 0x00000000. 925c838251403b0be9a882540f1922577abba4c872ager@chromium.org#define GENERATED_CODE_STACK_LIMIT(limit) \ 935c838251403b0be9a882540f1922577abba4c872ager@chromium.org (reinterpret_cast<uintptr_t>(this) >= limit ? \ 945c838251403b0be9a882540f1922577abba4c872ager@chromium.org reinterpret_cast<uintptr_t>(this) - limit : 0) 955c838251403b0be9a882540f1922577abba4c872ager@chromium.org 967516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#else // !defined(USE_SIMULATOR) 977516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// Running with a simulator. 985c838251403b0be9a882540f1922577abba4c872ager@chromium.org 997516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#include "hashmap.h" 10083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org#include "assembler.h" 1015c838251403b0be9a882540f1922577abba4c872ager@chromium.org 1027516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgnamespace v8 { 1037516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgnamespace internal { 1045c838251403b0be9a882540f1922577abba4c872ager@chromium.org 1057516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// ----------------------------------------------------------------------------- 1067516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// Utility functions 1075c838251403b0be9a882540f1922577abba4c872ager@chromium.org 1087516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgclass CachePage { 1097516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org public: 1107516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static const int LINE_VALID = 0; 1117516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static const int LINE_INVALID = 1; 1127516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 1137516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static const int kPageShift = 12; 1147516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static const int kPageSize = 1 << kPageShift; 1157516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static const int kPageMask = kPageSize - 1; 1167516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static const int kLineShift = 2; // The cache line is only 4 bytes right now. 1177516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static const int kLineLength = 1 << kLineShift; 1187516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static const int kLineMask = kLineLength - 1; 1197516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 1207516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org CachePage() { 1217516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org memset(&validity_map_, LINE_INVALID, sizeof(validity_map_)); 1227516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 1235c838251403b0be9a882540f1922577abba4c872ager@chromium.org 1247516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org char* ValidityByte(int offset) { 1257516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return &validity_map_[offset >> kLineShift]; 1267516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 1275c838251403b0be9a882540f1922577abba4c872ager@chromium.org 1287516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org char* CachedData(int offset) { 1297516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return &data_[offset]; 1307516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 1315c838251403b0be9a882540f1922577abba4c872ager@chromium.org 1327516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org private: 1337516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org char data_[kPageSize]; // The cached data. 1347516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static const int kValidityMapSize = kPageSize >> kLineShift; 1357516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org char validity_map_[kValidityMapSize]; // One byte per line. 1367516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org}; 1375c838251403b0be9a882540f1922577abba4c872ager@chromium.org 1385c838251403b0be9a882540f1922577abba4c872ager@chromium.orgclass Simulator { 1395c838251403b0be9a882540f1922577abba4c872ager@chromium.org public: 1407516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org friend class MipsDebugger; 1415c838251403b0be9a882540f1922577abba4c872ager@chromium.org 1425c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Registers are declared in order. See SMRL chapter 2. 1435c838251403b0be9a882540f1922577abba4c872ager@chromium.org enum Register { 1445c838251403b0be9a882540f1922577abba4c872ager@chromium.org no_reg = -1, 1455c838251403b0be9a882540f1922577abba4c872ager@chromium.org zero_reg = 0, 1465c838251403b0be9a882540f1922577abba4c872ager@chromium.org at, 1475c838251403b0be9a882540f1922577abba4c872ager@chromium.org v0, v1, 1485c838251403b0be9a882540f1922577abba4c872ager@chromium.org a0, a1, a2, a3, 1495c838251403b0be9a882540f1922577abba4c872ager@chromium.org t0, t1, t2, t3, t4, t5, t6, t7, 1505c838251403b0be9a882540f1922577abba4c872ager@chromium.org s0, s1, s2, s3, s4, s5, s6, s7, 1515c838251403b0be9a882540f1922577abba4c872ager@chromium.org t8, t9, 1525c838251403b0be9a882540f1922577abba4c872ager@chromium.org k0, k1, 1535c838251403b0be9a882540f1922577abba4c872ager@chromium.org gp, 1545c838251403b0be9a882540f1922577abba4c872ager@chromium.org sp, 1555c838251403b0be9a882540f1922577abba4c872ager@chromium.org s8, 1565c838251403b0be9a882540f1922577abba4c872ager@chromium.org ra, 15783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // LO, HI, and pc. 1585c838251403b0be9a882540f1922577abba4c872ager@chromium.org LO, 1595c838251403b0be9a882540f1922577abba4c872ager@chromium.org HI, 1605c838251403b0be9a882540f1922577abba4c872ager@chromium.org pc, // pc must be the last register. 1615c838251403b0be9a882540f1922577abba4c872ager@chromium.org kNumSimuRegisters, 1625c838251403b0be9a882540f1922577abba4c872ager@chromium.org // aliases 1635c838251403b0be9a882540f1922577abba4c872ager@chromium.org fp = s8 1645c838251403b0be9a882540f1922577abba4c872ager@chromium.org }; 1655c838251403b0be9a882540f1922577abba4c872ager@chromium.org 1665c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Coprocessor registers. 1675c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Generated code will always use doubles. So we will only use even registers. 1685c838251403b0be9a882540f1922577abba4c872ager@chromium.org enum FPURegister { 1695c838251403b0be9a882540f1922577abba4c872ager@chromium.org f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, 17083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org f12, f13, f14, f15, // f12 and f14 are arguments FPURegisters. 1715c838251403b0be9a882540f1922577abba4c872ager@chromium.org f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, 1725c838251403b0be9a882540f1922577abba4c872ager@chromium.org f26, f27, f28, f29, f30, f31, 1735c838251403b0be9a882540f1922577abba4c872ager@chromium.org kNumFPURegisters 1745c838251403b0be9a882540f1922577abba4c872ager@chromium.org }; 1755c838251403b0be9a882540f1922577abba4c872ager@chromium.org 1761c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org explicit Simulator(Isolate* isolate); 1775c838251403b0be9a882540f1922577abba4c872ager@chromium.org ~Simulator(); 1785c838251403b0be9a882540f1922577abba4c872ager@chromium.org 1795c838251403b0be9a882540f1922577abba4c872ager@chromium.org // The currently executing Simulator instance. Potentially there can be one 1805c838251403b0be9a882540f1922577abba4c872ager@chromium.org // for each native thread. 1817516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static Simulator* current(v8::internal::Isolate* isolate); 1825c838251403b0be9a882540f1922577abba4c872ager@chromium.org 1835c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Accessors for register state. Reading the pc value adheres to the MIPS 1845c838251403b0be9a882540f1922577abba4c872ager@chromium.org // architecture specification and is off by a 8 from the currently executing 1855c838251403b0be9a882540f1922577abba4c872ager@chromium.org // instruction. 1865c838251403b0be9a882540f1922577abba4c872ager@chromium.org void set_register(int reg, int32_t value); 18783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org void set_dw_register(int dreg, const int* dbl); 1885c838251403b0be9a882540f1922577abba4c872ager@chromium.org int32_t get_register(int reg) const; 18983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org double get_double_from_register_pair(int reg); 19083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Same for FPURegisters. 1915c838251403b0be9a882540f1922577abba4c872ager@chromium.org void set_fpu_register(int fpureg, int32_t value); 1927516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void set_fpu_register_float(int fpureg, float value); 1935c838251403b0be9a882540f1922577abba4c872ager@chromium.org void set_fpu_register_double(int fpureg, double value); 1945c838251403b0be9a882540f1922577abba4c872ager@chromium.org int32_t get_fpu_register(int fpureg) const; 1957516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org int64_t get_fpu_register_long(int fpureg) const; 1967516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org float get_fpu_register_float(int fpureg) const; 1975c838251403b0be9a882540f1922577abba4c872ager@chromium.org double get_fpu_register_double(int fpureg) const; 1987516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void set_fcsr_bit(uint32_t cc, bool value); 1997516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org bool test_fcsr_bit(uint32_t cc); 2007516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org bool set_fcsr_round_error(double original, double rounded); 2015c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2025c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Special case of set_register and get_register to access the raw PC value. 2035c838251403b0be9a882540f1922577abba4c872ager@chromium.org void set_pc(int32_t value); 2045c838251403b0be9a882540f1922577abba4c872ager@chromium.org int32_t get_pc() const; 2055c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2065c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Accessor to the internal simulator stack area. 2075c838251403b0be9a882540f1922577abba4c872ager@chromium.org uintptr_t StackLimit() const; 2085c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2095c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Executes MIPS instructions until the PC reaches end_sim_pc. 2105c838251403b0be9a882540f1922577abba4c872ager@chromium.org void Execute(); 2115c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2125c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Call on program start. 2131c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org static void Initialize(Isolate* isolate); 2145c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2155c838251403b0be9a882540f1922577abba4c872ager@chromium.org // V8 generally calls into generated JS code with 5 parameters and into 2165c838251403b0be9a882540f1922577abba4c872ager@chromium.org // generated RegExp code with 7 parameters. This is a convenience function, 2175c838251403b0be9a882540f1922577abba4c872ager@chromium.org // which sets up the simulator state and grabs the result on return. 2187516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org int32_t Call(byte* entry, int argument_count, ...); 21983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org // Alternative: call a 2-argument double function. 22083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org double CallFP(byte* entry, double d0, double d1); 2215c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2225c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Push an address onto the JS stack. 2235c838251403b0be9a882540f1922577abba4c872ager@chromium.org uintptr_t PushAddress(uintptr_t address); 2245c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2255c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Pop an address from the JS stack. 2265c838251403b0be9a882540f1922577abba4c872ager@chromium.org uintptr_t PopAddress(); 2275c838251403b0be9a882540f1922577abba4c872ager@chromium.org 228c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // Debugger input. 229c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org void set_last_debugger_input(char* input); 230c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org char* last_debugger_input() { return last_debugger_input_; } 231c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org 2327516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // ICache checking. 2337516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static void FlushICache(v8::internal::HashMap* i_cache, void* start, 2347516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org size_t size); 2357516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 2367516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Returns true if pc register contains one of the 'special_values' defined 2377516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // below (bad_ra, end_sim_pc). 2387516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org bool has_bad_pc() const; 2397516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 2405c838251403b0be9a882540f1922577abba4c872ager@chromium.org private: 2415c838251403b0be9a882540f1922577abba4c872ager@chromium.org enum special_values { 2425c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Known bad pc value to ensure that the simulator does not execute 2435c838251403b0be9a882540f1922577abba4c872ager@chromium.org // without being properly setup. 2445c838251403b0be9a882540f1922577abba4c872ager@chromium.org bad_ra = -1, 2455c838251403b0be9a882540f1922577abba4c872ager@chromium.org // A pc value used to signal the simulator to stop execution. Generally 2465c838251403b0be9a882540f1922577abba4c872ager@chromium.org // the ra is set to this value on transition from native C code to 2475c838251403b0be9a882540f1922577abba4c872ager@chromium.org // simulated execution, so that the simulator can "return" to the native 2485c838251403b0be9a882540f1922577abba4c872ager@chromium.org // C code. 2495c838251403b0be9a882540f1922577abba4c872ager@chromium.org end_sim_pc = -2, 2505c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Unpredictable value. 2515c838251403b0be9a882540f1922577abba4c872ager@chromium.org Unpredictable = 0xbadbeaf 2525c838251403b0be9a882540f1922577abba4c872ager@chromium.org }; 2535c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2545c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Unsupported instructions use Format to print an error and stop execution. 2555c838251403b0be9a882540f1922577abba4c872ager@chromium.org void Format(Instruction* instr, const char* format); 2565c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2575c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Read and write memory. 2585c838251403b0be9a882540f1922577abba4c872ager@chromium.org inline uint32_t ReadBU(int32_t addr); 2595c838251403b0be9a882540f1922577abba4c872ager@chromium.org inline int32_t ReadB(int32_t addr); 2605c838251403b0be9a882540f1922577abba4c872ager@chromium.org inline void WriteB(int32_t addr, uint8_t value); 2615c838251403b0be9a882540f1922577abba4c872ager@chromium.org inline void WriteB(int32_t addr, int8_t value); 2625c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2635c838251403b0be9a882540f1922577abba4c872ager@chromium.org inline uint16_t ReadHU(int32_t addr, Instruction* instr); 2645c838251403b0be9a882540f1922577abba4c872ager@chromium.org inline int16_t ReadH(int32_t addr, Instruction* instr); 2655c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Note: Overloaded on the sign of the value. 2665c838251403b0be9a882540f1922577abba4c872ager@chromium.org inline void WriteH(int32_t addr, uint16_t value, Instruction* instr); 2675c838251403b0be9a882540f1922577abba4c872ager@chromium.org inline void WriteH(int32_t addr, int16_t value, Instruction* instr); 2685c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2695c838251403b0be9a882540f1922577abba4c872ager@chromium.org inline int ReadW(int32_t addr, Instruction* instr); 2705c838251403b0be9a882540f1922577abba4c872ager@chromium.org inline void WriteW(int32_t addr, int value, Instruction* instr); 2715c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2725c838251403b0be9a882540f1922577abba4c872ager@chromium.org inline double ReadD(int32_t addr, Instruction* instr); 2735c838251403b0be9a882540f1922577abba4c872ager@chromium.org inline void WriteD(int32_t addr, double value, Instruction* instr); 2745c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2755c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Operations depending on endianness. 2765c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Get Double Higher / Lower word. 2775c838251403b0be9a882540f1922577abba4c872ager@chromium.org inline int32_t GetDoubleHIW(double* addr); 2785c838251403b0be9a882540f1922577abba4c872ager@chromium.org inline int32_t GetDoubleLOW(double* addr); 2795c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Set Double Higher / Lower word. 2805c838251403b0be9a882540f1922577abba4c872ager@chromium.org inline int32_t SetDoubleHIW(double* addr); 2815c838251403b0be9a882540f1922577abba4c872ager@chromium.org inline int32_t SetDoubleLOW(double* addr); 2825c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2835c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Executing is handled based on the instruction type. 2845c838251403b0be9a882540f1922577abba4c872ager@chromium.org void DecodeTypeRegister(Instruction* instr); 2857516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 2867516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Helper function for DecodeTypeRegister. 2877516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void ConfigureTypeRegister(Instruction* instr, 2887516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org int32_t& alu_out, 2897516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org int64_t& i64hilo, 2907516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org uint64_t& u64hilo, 2917516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org int32_t& next_pc, 292f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org int32_t& return_addr_reg, 2937516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org bool& do_interrupt); 2947516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 2955c838251403b0be9a882540f1922577abba4c872ager@chromium.org void DecodeTypeImmediate(Instruction* instr); 2965c838251403b0be9a882540f1922577abba4c872ager@chromium.org void DecodeTypeJump(Instruction* instr); 2975c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2985c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Used for breakpoints and traps. 2995c838251403b0be9a882540f1922577abba4c872ager@chromium.org void SoftwareInterrupt(Instruction* instr); 3005c838251403b0be9a882540f1922577abba4c872ager@chromium.org 301c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org // Stop helper functions. 302c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org bool IsWatchpoint(uint32_t code); 303c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org void PrintWatchpoint(uint32_t code); 304c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org void HandleStop(uint32_t code, Instruction* instr); 305c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org bool IsStopInstruction(Instruction* instr); 306c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org bool IsEnabledStop(uint32_t code); 307c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org void EnableStop(uint32_t code); 308c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org void DisableStop(uint32_t code); 309c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org void IncreaseStopCounter(uint32_t code); 310c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org void PrintStopInfo(uint32_t code); 311c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org 312c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org 3135c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Executes one instruction. 3145c838251403b0be9a882540f1922577abba4c872ager@chromium.org void InstructionDecode(Instruction* instr); 3155c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Execute one instruction placed in a branch delay slot. 3165c838251403b0be9a882540f1922577abba4c872ager@chromium.org void BranchDelayInstructionDecode(Instruction* instr) { 3176ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org if (instr->InstructionBits() == nopInstr) { 3186ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org // Short-cut generic nop instructions. They are always valid and they 3196ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org // never change the simulator state. 3206ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org return; 3216ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org } 3226ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org 3235c838251403b0be9a882540f1922577abba4c872ager@chromium.org if (instr->IsForbiddenInBranchDelay()) { 3245c838251403b0be9a882540f1922577abba4c872ager@chromium.org V8_Fatal(__FILE__, __LINE__, 3255c838251403b0be9a882540f1922577abba4c872ager@chromium.org "Eror:Unexpected %i opcode in a branch delay slot.", 3267516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org instr->OpcodeValue()); 3275c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 3285c838251403b0be9a882540f1922577abba4c872ager@chromium.org InstructionDecode(instr); 3295c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 3305c838251403b0be9a882540f1922577abba4c872ager@chromium.org 3317516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // ICache. 3327516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static void CheckICache(v8::internal::HashMap* i_cache, Instruction* instr); 3337516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static void FlushOnePage(v8::internal::HashMap* i_cache, intptr_t start, 3347516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org int size); 3357516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org static CachePage* GetCachePage(v8::internal::HashMap* i_cache, void* page); 3367516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 3375c838251403b0be9a882540f1922577abba4c872ager@chromium.org enum Exception { 3385c838251403b0be9a882540f1922577abba4c872ager@chromium.org none, 3395c838251403b0be9a882540f1922577abba4c872ager@chromium.org kIntegerOverflow, 3405c838251403b0be9a882540f1922577abba4c872ager@chromium.org kIntegerUnderflow, 3415c838251403b0be9a882540f1922577abba4c872ager@chromium.org kDivideByZero, 3425c838251403b0be9a882540f1922577abba4c872ager@chromium.org kNumExceptions 3435c838251403b0be9a882540f1922577abba4c872ager@chromium.org }; 3445c838251403b0be9a882540f1922577abba4c872ager@chromium.org int16_t exceptions[kNumExceptions]; 3455c838251403b0be9a882540f1922577abba4c872ager@chromium.org 3465c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Exceptions. 3475c838251403b0be9a882540f1922577abba4c872ager@chromium.org void SignalExceptions(); 3485c838251403b0be9a882540f1922577abba4c872ager@chromium.org 3495c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Runtime call support. 3505c838251403b0be9a882540f1922577abba4c872ager@chromium.org static void* RedirectExternalReference(void* external_function, 3517516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org ExternalReference::Type type); 3525c838251403b0be9a882540f1922577abba4c872ager@chromium.org 353e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Handle arguments and return value for runtime FP functions. 354e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org void GetFpArgs(double* x, double* y, int32_t* z); 35540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org void SetFpResult(const double& result); 35640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 35783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org void CallInternal(byte* entry); 3585c838251403b0be9a882540f1922577abba4c872ager@chromium.org 3595c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Architecture state. 3605c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Registers. 3615c838251403b0be9a882540f1922577abba4c872ager@chromium.org int32_t registers_[kNumSimuRegisters]; 3625c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Coprocessor Registers. 3635c838251403b0be9a882540f1922577abba4c872ager@chromium.org int32_t FPUregisters_[kNumFPURegisters]; 3647516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // FPU control register. 3657516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org uint32_t FCSR_; 3665c838251403b0be9a882540f1922577abba4c872ager@chromium.org 3675c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Simulator support. 36883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Allocate 1MB for stack. 36983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org static const size_t stack_size_ = 1 * 1024*1024; 3705c838251403b0be9a882540f1922577abba4c872ager@chromium.org char* stack_; 3715c838251403b0be9a882540f1922577abba4c872ager@chromium.org bool pc_modified_; 3725c838251403b0be9a882540f1922577abba4c872ager@chromium.org int icount_; 3737516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org int break_count_; 3747516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 375c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // Debugger input. 376c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org char* last_debugger_input_; 377c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org 37883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Icache simulation. 3797516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org v8::internal::HashMap* i_cache_; 3805c838251403b0be9a882540f1922577abba4c872ager@chromium.org 38183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org v8::internal::Isolate* isolate_; 38283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 3835c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Registered breakpoints. 3845c838251403b0be9a882540f1922577abba4c872ager@chromium.org Instruction* break_pc_; 3855c838251403b0be9a882540f1922577abba4c872ager@chromium.org Instr break_instr_; 386c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org 387c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org // Stop is disabled if bit 31 is set. 388c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org static const uint32_t kStopDisabledBit = 1 << 31; 389c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org 390c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org // A stop is enabled, meaning the simulator will stop when meeting the 391f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // instruction, if bit 31 of watched_stops_[code].count is unset. 392f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // The value watched_stops_[code].count & ~(1 << 31) indicates how many times 393c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org // the breakpoint was hit or gone through. 394c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org struct StopCountAndDesc { 395c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org uint32_t count; 396c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org char* desc; 397c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org }; 398f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org StopCountAndDesc watched_stops_[kMaxStopCode + 1]; 3995c838251403b0be9a882540f1922577abba4c872ager@chromium.org}; 4005c838251403b0be9a882540f1922577abba4c872ager@chromium.org 4017516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 4027516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// When running with the simulator transition into simulated execution at this 4037516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// point. 4047516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4) \ 40583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org reinterpret_cast<Object*>(Simulator::current(Isolate::Current())->Call( \ 4067516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org FUNCTION_ADDR(entry), 5, p0, p1, p2, p3, p4)) 4077516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 408777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7, p8) \ 40983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Simulator::current(Isolate::Current())->Call( \ 410777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org entry, 10, p0, p1, p2, p3, NULL, p4, p5, p6, p7, p8) 4117516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 41283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org#define TRY_CATCH_FROM_ADDRESS(try_catch_address) \ 41383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org try_catch_address == NULL ? \ 4147516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org NULL : *(reinterpret_cast<TryCatch**>(try_catch_address)) 4155c838251403b0be9a882540f1922577abba4c872ager@chromium.org 4165c838251403b0be9a882540f1922577abba4c872ager@chromium.org 4175c838251403b0be9a882540f1922577abba4c872ager@chromium.org// The simulator has its own stack. Thus it has a different stack limit from 4185c838251403b0be9a882540f1922577abba4c872ager@chromium.org// the C-based native code. Setting the c_limit to indicate a very small 4195c838251403b0be9a882540f1922577abba4c872ager@chromium.org// stack cause stack overflow errors, since the simulator ignores the input. 4205c838251403b0be9a882540f1922577abba4c872ager@chromium.org// This is unlikely to be an issue in practice, though it might cause testing 4215c838251403b0be9a882540f1922577abba4c872ager@chromium.org// trouble down the line. 4225c838251403b0be9a882540f1922577abba4c872ager@chromium.orgclass SimulatorStack : public v8::internal::AllStatic { 4235c838251403b0be9a882540f1922577abba4c872ager@chromium.org public: 4241c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org static inline uintptr_t JsLimitFromCLimit(Isolate* isolate, 4251c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org uintptr_t c_limit) { 4261c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org return Simulator::current(isolate)->StackLimit(); 4275c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 4285c838251403b0be9a882540f1922577abba4c872ager@chromium.org 4295c838251403b0be9a882540f1922577abba4c872ager@chromium.org static inline uintptr_t RegisterCTryCatch(uintptr_t try_catch_address) { 4307516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Simulator* sim = Simulator::current(Isolate::Current()); 4315c838251403b0be9a882540f1922577abba4c872ager@chromium.org return sim->PushAddress(try_catch_address); 4325c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 4335c838251403b0be9a882540f1922577abba4c872ager@chromium.org 4345c838251403b0be9a882540f1922577abba4c872ager@chromium.org static inline void UnregisterCTryCatch() { 4357516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Simulator::current(Isolate::Current())->PopAddress(); 4365c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 4375c838251403b0be9a882540f1922577abba4c872ager@chromium.org}; 4385c838251403b0be9a882540f1922577abba4c872ager@chromium.org 4397516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} } // namespace v8::internal 4405c838251403b0be9a882540f1922577abba4c872ager@chromium.org 4417516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#endif // !defined(USE_SIMULATOR) 4425c838251403b0be9a882540f1922577abba4c872ager@chromium.org#endif // V8_MIPS_SIMULATOR_MIPS_H_ 443