1958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Copyright 2014 the V8 project authors. All rights reserved. 2958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Use of this source code is governed by a BSD-style license that can be 3958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// found in the LICENSE file. 4958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 5958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 6958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Declares a Simulator for PPC instructions if we are not generating a native 7958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// PPC binary. This Simulator allows us to run and debug PPC code generation on 8958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// regular desktop machines. 9958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// V8 calls into generated code by "calling" the CALL_GENERATED_CODE macro, 10958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// which will start execution in the Simulator or forwards to the real entry 11958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// on a PPC HW platform. 12958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 13958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#ifndef V8_PPC_SIMULATOR_PPC_H_ 14958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define V8_PPC_SIMULATOR_PPC_H_ 15958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 16958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/allocation.h" 17958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 18958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if !defined(USE_SIMULATOR) 19958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Running without a simulator on a native ppc platform. 20958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 21958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace v8 { 22958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace internal { 23958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 24958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// When running without a simulator we call the entry directly. 25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define CALL_GENERATED_CODE(isolate, entry, p0, p1, p2, p3, p4) \ 26958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier (entry(p0, p1, p2, p3, p4)) 27958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 28958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertypedef int (*ppc_regexp_matcher)(String*, int, const byte*, const byte*, int*, 29958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int, Address, int, void*, Isolate*); 30958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 31958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 32958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Call the generated regexp code directly. The code at the entry address 33958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// should act as a function matching the type ppc_regexp_matcher. 34958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// The ninth argument is a dummy that reserves the space used for 35958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// the return address added by the ExitFrame in native calls. 36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define CALL_GENERATED_REGEXP_CODE(isolate, entry, p0, p1, p2, p3, p4, p5, p6, \ 37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch p7, p8) \ 38014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (FUNCTION_CAST<ppc_regexp_matcher>(entry)(p0, p1, p2, p3, p4, p5, p6, p7, \ 39958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier NULL, p8)) 40958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 41958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// The stack limit beyond which we will throw stack overflow errors in 42958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// generated code. Because generated code on ppc uses the C stack, we 43958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// just use the C stack limit. 44958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass SimulatorStack : public v8::internal::AllStatic { 45958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public: 46958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static inline uintptr_t JsLimitFromCLimit(v8::internal::Isolate* isolate, 47958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t c_limit) { 48958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier USE(isolate); 49958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return c_limit; 50958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 51958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 52014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static inline uintptr_t RegisterCTryCatch(v8::internal::Isolate* isolate, 53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uintptr_t try_catch_address) { 54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch USE(isolate); 55958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return try_catch_address; 56958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 57958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static inline void UnregisterCTryCatch(v8::internal::Isolate* isolate) { 59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch USE(isolate); 60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 61958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}; 62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 64958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 65958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#else // !defined(USE_SIMULATOR) 66958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Running with a simulator. 67958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 68958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/assembler.h" 6921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch#include "src/base/hashmap.h" 70958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/ppc/constants-ppc.h" 71958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 72958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace v8 { 73958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace internal { 74958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 75958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass CachePage { 76958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public: 77958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static const int LINE_VALID = 0; 78958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static const int LINE_INVALID = 1; 79958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 80958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static const int kPageShift = 12; 81958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static const int kPageSize = 1 << kPageShift; 82958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static const int kPageMask = kPageSize - 1; 83958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static const int kLineShift = 2; // The cache line is only 4 bytes right now. 84958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static const int kLineLength = 1 << kLineShift; 85958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static const int kLineMask = kLineLength - 1; 86958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 87958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CachePage() { memset(&validity_map_, LINE_INVALID, sizeof(validity_map_)); } 88958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 89958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier char* ValidityByte(int offset) { 90958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return &validity_map_[offset >> kLineShift]; 91958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 92958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 93958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier char* CachedData(int offset) { return &data_[offset]; } 94958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 95958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private: 96958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier char data_[kPageSize]; // The cached data. 97958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static const int kValidityMapSize = kPageSize >> kLineShift; 98958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier char validity_map_[kValidityMapSize]; // One byte per line. 99958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}; 100958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 101958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 102958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass Simulator { 103958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public: 104958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier friend class PPCDebugger; 105958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier enum Register { 106958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier no_reg = -1, 107958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier r0 = 0, 108958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier sp, 109958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier r2, 110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier r3, 111958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier r4, 112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier r5, 113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier r6, 114958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier r7, 115958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier r8, 116958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier r9, 117958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier r10, 118958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier r11, 119958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier r12, 120958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier r13, 121958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier r14, 122958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier r15, 123958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier r16, 124958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier r17, 125958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier r18, 126958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier r19, 127958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier r20, 128958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier r21, 129958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier r22, 130958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier r23, 131958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier r24, 132958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier r25, 133958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier r26, 134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier r27, 135958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier r28, 136958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier r29, 137958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier r30, 138958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier fp, 139958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier kNumGPRs = 32, 140958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier d0 = 0, 141958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier d1, 142958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier d2, 143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier d3, 144958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier d4, 145958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier d5, 146958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier d6, 147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier d7, 148958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier d8, 149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier d9, 150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier d10, 151958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier d11, 152958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier d12, 153958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier d13, 154958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier d14, 155958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier d15, 156958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier d16, 157958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier d17, 158958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier d18, 159958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier d19, 160958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier d20, 161958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier d21, 162958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier d22, 163958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier d23, 164958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier d24, 165958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier d25, 166958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier d26, 167958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier d27, 168958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier d28, 169958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier d29, 170958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier d30, 171958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier d31, 172958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier kNumFPRs = 32 173958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier }; 174958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 175958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier explicit Simulator(Isolate* isolate); 176958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ~Simulator(); 177958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 178958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // The currently executing Simulator instance. Potentially there can be one 179958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // for each native thread. 180958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static Simulator* current(v8::internal::Isolate* isolate); 181958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 182958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Accessors for register state. 183958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void set_register(int reg, intptr_t value); 184958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t get_register(int reg) const; 185958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double get_double_from_register_pair(int reg); 186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void set_d_register_from_double(int dreg, const double dbl) { 187958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(dreg >= 0 && dreg < kNumFPRs); 188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch *bit_cast<double*>(&fp_registers_[dreg]) = dbl; 189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch double get_double_from_d_register(int dreg) { 191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(dreg >= 0 && dreg < kNumFPRs); 192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return *bit_cast<double*>(&fp_registers_[dreg]); 193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void set_d_register(int dreg, int64_t value) { 195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(dreg >= 0 && dreg < kNumFPRs); 196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch fp_registers_[dreg] = value; 197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int64_t get_d_register(int dreg) { 199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(dreg >= 0 && dreg < kNumFPRs); 200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return fp_registers_[dreg]; 201958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 202958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 203958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Special case of set_register and get_register to access the raw PC value. 204958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void set_pc(intptr_t value); 205958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t get_pc() const; 206958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Address get_sp() const { 208958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return reinterpret_cast<Address>(static_cast<intptr_t>(get_register(sp))); 209958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 210958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 211958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Accessor to the internal simulator stack area. 212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uintptr_t StackLimit(uintptr_t c_limit) const; 213958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 214958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Executes PPC instructions until the PC reaches end_sim_pc. 215958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void Execute(); 216958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 217958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Call on program start. 218958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static void Initialize(Isolate* isolate); 219958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 22021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch static void TearDown(base::HashMap* i_cache, Redirection* first); 221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 222958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // V8 generally calls into generated JS code with 5 parameters and into 223958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // generated RegExp code with 7 parameters. This is a convenience function, 224958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // which sets up the simulator state and grabs the result on return. 225958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t Call(byte* entry, int argument_count, ...); 226958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Alternative: call a 2-argument double function. 227958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void CallFP(byte* entry, double d0, double d1); 228958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t CallFPReturnsInt(byte* entry, double d0, double d1); 229958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double CallFPReturnsDouble(byte* entry, double d0, double d1); 230958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 231958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Push an address onto the JS stack. 232958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t PushAddress(uintptr_t address); 233958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 234958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Pop an address from the JS stack. 235958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t PopAddress(); 236958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 237958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Debugger input. 238958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void set_last_debugger_input(char* input); 239958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier char* last_debugger_input() { return last_debugger_input_; } 240958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 241958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // ICache checking. 24221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch static void FlushICache(base::HashMap* i_cache, void* start, size_t size); 243958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 244958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Returns true if pc register contains one of the 'special_values' defined 245958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // below (bad_lr, end_sim_pc). 246958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool has_bad_pc() const; 247958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 248958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private: 249958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier enum special_values { 250958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Known bad pc value to ensure that the simulator does not execute 251958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // without being properly setup. 252958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bad_lr = -1, 253958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // A pc value used to signal the simulator to stop execution. Generally 254958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // the lr is set to this value on transition from native C code to 255958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // simulated execution, so that the simulator can "return" to the native 256958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // C code. 257958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier end_sim_pc = -2 258958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier }; 259958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch enum BCType { BC_OFFSET, BC_LINK_REG, BC_CTR_REG }; 261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 262958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Unsupported instructions use Format to print an error and stop execution. 263958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void Format(Instruction* instr, const char* format); 264958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 265958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Helper functions to set the conditional flags in the architecture state. 266958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool CarryFrom(int32_t left, int32_t right, int32_t carry = 0); 267958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool BorrowFrom(int32_t left, int32_t right); 268958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool OverflowFrom(int32_t alu_out, int32_t left, int32_t right, 269958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool addition); 270958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 271958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Helper functions to decode common "addressing" modes 272958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t GetShiftRm(Instruction* instr, bool* carry_out); 273958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t GetImm(Instruction* instr, bool* carry_out); 274958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void ProcessPUW(Instruction* instr, int num_regs, int operand_size, 275958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t* start_address, intptr_t* end_address); 276958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void HandleRList(Instruction* instr, bool load); 277958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void HandleVList(Instruction* inst); 278958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void SoftwareInterrupt(Instruction* instr); 279958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 280958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Stop helper functions. 281958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline bool isStopInstruction(Instruction* instr); 282958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline bool isWatchedStop(uint32_t bkpt_code); 283958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline bool isEnabledStop(uint32_t bkpt_code); 284958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline void EnableStop(uint32_t bkpt_code); 285958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline void DisableStop(uint32_t bkpt_code); 286958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline void IncreaseStopCounter(uint32_t bkpt_code); 287958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void PrintStopInfo(uint32_t code); 288958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 289958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Read and write memory. 290958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline uint8_t ReadBU(intptr_t addr); 291958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline int8_t ReadB(intptr_t addr); 292958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline void WriteB(intptr_t addr, uint8_t value); 293958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline void WriteB(intptr_t addr, int8_t value); 294958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 295958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline uint16_t ReadHU(intptr_t addr, Instruction* instr); 296958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline int16_t ReadH(intptr_t addr, Instruction* instr); 297958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Note: Overloaded on the sign of the value. 298958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline void WriteH(intptr_t addr, uint16_t value, Instruction* instr); 299958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline void WriteH(intptr_t addr, int16_t value, Instruction* instr); 300958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 301958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline uint32_t ReadWU(intptr_t addr, Instruction* instr); 302958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline int32_t ReadW(intptr_t addr, Instruction* instr); 303958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline void WriteW(intptr_t addr, uint32_t value, Instruction* instr); 304958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline void WriteW(intptr_t addr, int32_t value, Instruction* instr); 305958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 306958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t* ReadDW(intptr_t addr); 307958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void WriteDW(intptr_t addr, int64_t value); 308958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 309958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void Trace(Instruction* instr); 310958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void SetCR0(intptr_t result, bool setSO = false); 311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void ExecuteBranchConditional(Instruction* instr, BCType type); 312958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void ExecuteExt1(Instruction* instr); 313958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool ExecuteExt2_10bit(Instruction* instr); 314958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool ExecuteExt2_9bit_part1(Instruction* instr); 315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool ExecuteExt2_9bit_part2(Instruction* instr); 316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void ExecuteExt2_5bit(Instruction* instr); 317958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void ExecuteExt2(Instruction* instr); 318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void ExecuteExt3(Instruction* instr); 319958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void ExecuteExt4(Instruction* instr); 320958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if V8_TARGET_ARCH_PPC64 321958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void ExecuteExt5(Instruction* instr); 322958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 323958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void ExecuteGeneric(Instruction* instr); 324958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void SetFPSCR(int bit) { fp_condition_reg_ |= (1 << (31 - bit)); } 326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void ClearFPSCR(int bit) { fp_condition_reg_ &= ~(1 << (31 - bit)); } 327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 328958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Executes one instruction. 329958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void ExecuteInstruction(Instruction* instr); 330958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 331958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // ICache. 33221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch static void CheckICache(base::HashMap* i_cache, Instruction* instr); 33321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch static void FlushOnePage(base::HashMap* i_cache, intptr_t start, int size); 33421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch static CachePage* GetCachePage(base::HashMap* i_cache, void* page); 335958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 336958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Runtime call support. 337958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static void* RedirectExternalReference( 338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate, void* external_function, 339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch v8::internal::ExternalReference::Type type); 340958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 341958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Handle arguments and return value for runtime FP functions. 342958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void GetFpArgs(double* x, double* y, intptr_t* z); 343958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void SetFpResult(const double& result); 344958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void TrashCallerSaveRegisters(); 345958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 346958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void CallInternal(byte* entry); 347958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 348958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Architecture state. 349958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Saturating instructions require a Q flag to indicate saturation. 350958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // There is currently no way to read the CPSR directly, and thus read the Q 351958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // flag, so this is left unimplemented. 352958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t registers_[kNumGPRs]; 353958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t condition_reg_; 354958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t fp_condition_reg_; 355958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t special_reg_lr_; 356958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t special_reg_pc_; 357958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier intptr_t special_reg_ctr_; 358958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t special_reg_xer_; 359958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int64_t fp_registers_[kNumFPRs]; 361958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 362958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Simulator support. 363958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier char* stack_; 364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const size_t stack_protection_size_ = 256 * kPointerSize; 365958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool pc_modified_; 366958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int icount_; 367958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 368958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Debugger input. 369958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier char* last_debugger_input_; 370958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 371958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Icache simulation 37221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch base::HashMap* i_cache_; 373958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 374958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Registered breakpoints. 375958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Instruction* break_pc_; 376958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Instr break_instr_; 377958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 378958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier v8::internal::Isolate* isolate_; 379958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 380958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // A stop is watched if its code is less than kNumOfWatchedStops. 381958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Only watched stops support enabling/disabling and the counter feature. 382958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static const uint32_t kNumOfWatchedStops = 256; 383958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 384958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Breakpoint is disabled if bit 31 is set. 385958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static const uint32_t kStopDisabledBit = 1 << 31; 386958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 387958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // A stop is enabled, meaning the simulator will stop when meeting the 388958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // instruction, if bit 31 of watched_stops_[code].count is unset. 389958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // The value watched_stops_[code].count & ~(1 << 31) indicates how many times 390958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // the breakpoint was hit or gone through. 391958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier struct StopCountAndDesc { 392958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t count; 393958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier char* desc; 394958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier }; 395958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier StopCountAndDesc watched_stops_[kNumOfWatchedStops]; 396958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}; 397958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 398958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 399958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// When running with the simulator transition into simulated execution at this 400958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// point. 401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define CALL_GENERATED_CODE(isolate, entry, p0, p1, p2, p3, p4) \ 402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch reinterpret_cast<Object*>(Simulator::current(isolate)->Call( \ 403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FUNCTION_ADDR(entry), 5, (intptr_t)p0, (intptr_t)p1, (intptr_t)p2, \ 404958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier (intptr_t)p3, (intptr_t)p4)) 405958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define CALL_GENERATED_REGEXP_CODE(isolate, entry, p0, p1, p2, p3, p4, p5, p6, \ 407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch p7, p8) \ 408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Simulator::current(isolate)->Call(entry, 10, (intptr_t)p0, (intptr_t)p1, \ 409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (intptr_t)p2, (intptr_t)p3, (intptr_t)p4, \ 410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (intptr_t)p5, (intptr_t)p6, (intptr_t)p7, \ 411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (intptr_t)NULL, (intptr_t)p8) 412958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 413958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 414958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// The simulator has its own stack. Thus it has a different stack limit from 415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// the C-based native code. The JS-based limit normally points near the end of 416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// the simulator stack. When the C-based limit is exhausted we reflect that by 417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// lowering the JS-based limit as well, to make stack checks trigger. 418958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass SimulatorStack : public v8::internal::AllStatic { 419958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public: 420958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static inline uintptr_t JsLimitFromCLimit(v8::internal::Isolate* isolate, 421958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uintptr_t c_limit) { 422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Simulator::current(isolate)->StackLimit(c_limit); 423958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 424958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static inline uintptr_t RegisterCTryCatch(v8::internal::Isolate* isolate, 426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uintptr_t try_catch_address) { 427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Simulator* sim = Simulator::current(isolate); 428958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return sim->PushAddress(try_catch_address); 429958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 430958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static inline void UnregisterCTryCatch(v8::internal::Isolate* isolate) { 432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Simulator::current(isolate)->PopAddress(); 433958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 434958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}; 435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 437958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 438958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif // !defined(USE_SIMULATOR) 439958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif // V8_PPC_SIMULATOR_PPC_H_ 440