18b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch// Copyright 2011 the V8 project authors. All rights reserved.
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met:
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions of source code must retain the above copyright
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       notice, this list of conditions and the following disclaimer.
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions in binary form must reproduce the above
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       copyright notice, this list of conditions and the following
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       disclaimer in the documentation and/or other materials provided
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       with the distribution.
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Neither the name of Google Inc. nor the names of its
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       contributors may be used to endorse or promote products derived
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       from this software without specific prior written permission.
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Declares a Simulator for ARM instructions if we are not generating a native
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ARM binary. This Simulator allows us to run and debug ARM code generation on
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// regular desktop machines.
32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// V8 calls into generated code by "calling" the CALL_GENERATED_CODE macro,
33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// which will start execution in the Simulator or forwards to the real entry
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// on a ARM HW platform.
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_ARM_SIMULATOR_ARM_H_
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_ARM_SIMULATOR_ARM_H_
38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "allocation.h"
40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
415913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck#if !defined(USE_SIMULATOR)
425913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck// Running without a simulator on a native arm platform.
435913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck
445913587db4c6bab03d97bfe44b06289fd6d7270dJohn Recknamespace v8 {
455913587db4c6bab03d97bfe44b06289fd6d7270dJohn Recknamespace internal {
46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// When running without a simulator we call the entry directly.
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4) \
49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  (entry(p0, p1, p2, p3, p4))
50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
51e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochtypedef int (*arm_regexp_matcher)(String*, int, const byte*, const byte*,
5244f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                  void*, int*, Address, int, Isolate*);
53e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
54e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
55e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// Call the generated regexp code directly. The code at the entry address
56e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// should act as a function matching the type arm_regexp_matcher.
57e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// The fifth argument is a dummy that reserves the space used for
58e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// the return address added by the ExitFrame in native calls.
5944f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7) \
6044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  (FUNCTION_CAST<arm_regexp_matcher>(entry)(                              \
6144f0eee88ff00398ff7f715fab053374d808c90dSteve Block      p0, p1, p2, p3, NULL, p4, p5, p6, p7))
625913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck
635913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck#define TRY_CATCH_FROM_ADDRESS(try_catch_address) \
6444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  reinterpret_cast<TryCatch*>(try_catch_address)
655913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck
66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The stack limit beyond which we will throw stack overflow errors in
67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// generated code. Because generated code on arm uses the C stack, we
68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// just use the C stack limit.
69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass SimulatorStack : public v8::internal::AllStatic {
70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
71257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  static inline uintptr_t JsLimitFromCLimit(v8::internal::Isolate* isolate,
72257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                            uintptr_t c_limit) {
73257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    USE(isolate);
74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return c_limit;
75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
76d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
77d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  static inline uintptr_t RegisterCTryCatch(uintptr_t try_catch_address) {
78d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    return try_catch_address;
79d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
80d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
81d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  static inline void UnregisterCTryCatch() { }
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
845913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck} }  // namespace v8::internal
85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
865913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck#else  // !defined(USE_SIMULATOR)
875913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck// Running with a simulator.
88d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "constants-arm.h"
906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#include "hashmap.h"
911e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block#include "assembler.h"
92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
931e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blocknamespace v8 {
941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blocknamespace internal {
95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
966ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass CachePage {
976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public:
986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int LINE_VALID = 0;
996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int LINE_INVALID = 1;
1006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kPageShift = 12;
1026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kPageSize = 1 << kPageShift;
1036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kPageMask = kPageSize - 1;
1046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kLineShift = 2;  // The cache line is only 4 bytes right now.
1056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kLineLength = 1 << kLineShift;
1066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kLineMask = kLineLength - 1;
1076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CachePage() {
1096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    memset(&validity_map_, LINE_INVALID, sizeof(validity_map_));
1106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
1116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  char* ValidityByte(int offset) {
1136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return &validity_map_[offset >> kLineShift];
1146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
1156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  char* CachedData(int offset) {
1176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return &data_[offset];
1186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
1196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private:
1216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  char data_[kPageSize];   // The cached data.
1226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kValidityMapSize = kPageSize >> kLineShift;
1236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  char validity_map_[kValidityMapSize];  // One byte per line.
1246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block};
1256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Simulator {
128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
12944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  friend class ArmDebugger;
130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  enum Register {
131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    no_reg = -1,
132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    r0 = 0, r1, r2, r3, r4, r5, r6, r7,
133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    r8, r9, r10, r11, r12, r13, r14, r15,
134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    num_registers,
135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    sp = 13,
136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    lr = 14,
137d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    pc = 15,
138d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    s0 = 0, s1, s2, s3, s4, s5, s6, s7,
139d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    s8, s9, s10, s11, s12, s13, s14, s15,
140d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    s16, s17, s18, s19, s20, s21, s22, s23,
141d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    s24, s25, s26, s27, s28, s29, s30, s31,
142d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    num_s_registers = 32,
143d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    d0 = 0, d1, d2, d3, d4, d5, d6, d7,
144d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    d8, d9, d10, d11, d12, d13, d14, d15,
145d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    num_d_registers = 16
146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  };
147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
148257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  explicit Simulator(Isolate* isolate);
149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ~Simulator();
150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The currently executing Simulator instance. Potentially there can be one
152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // for each native thread.
15344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static Simulator* current(v8::internal::Isolate* isolate);
154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Accessors for register state. Reading the pc value adheres to the ARM
156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // architecture specification and is off by a 8 from the currently executing
157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // instruction.
158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void set_register(int reg, int32_t value);
159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int32_t get_register(int reg) const;
1608b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  double get_double_from_register_pair(int reg);
16125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  void set_dw_register(int dreg, const int* dbl);
162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
163d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Support for VFP.
164d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  void set_s_register(int reg, unsigned int value);
165d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  unsigned int get_s_register(int reg) const;
166d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  void set_d_register_from_double(int dreg, const double& dbl);
167d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  double get_double_from_d_register(int dreg);
168d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  void set_s_register_from_float(int sreg, const float dbl);
169d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  float get_float_from_s_register(int sreg);
170d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  void set_s_register_from_sinteger(int reg, const int value);
171d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  int get_sinteger_from_s_register(int reg);
172d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Special case of set_register and get_register to access the raw PC value.
174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void set_pc(int32_t value);
175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int32_t get_pc() const;
176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Accessor to the internal simulator stack area.
178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  uintptr_t StackLimit() const;
179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Executes ARM instructions until the PC reaches end_sim_pc.
181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Execute();
182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Call on program start.
184257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  static void Initialize(Isolate* isolate);
185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // V8 generally calls into generated JS code with 5 parameters and into
187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // generated RegExp code with 7 parameters. This is a convenience function,
188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // which sets up the simulator state and grabs the result on return.
189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int32_t Call(byte* entry, int argument_count, ...);
190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
191d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Push an address onto the JS stack.
192d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  uintptr_t PushAddress(uintptr_t address);
193d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
194d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Pop an address from the JS stack.
195d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  uintptr_t PopAddress();
196d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
1973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Debugger input.
1983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void set_last_debugger_input(char* input);
1993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  char* last_debugger_input() { return last_debugger_input_; }
2003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // ICache checking.
20244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static void FlushICache(v8::internal::HashMap* i_cache, void* start,
20344f0eee88ff00398ff7f715fab053374d808c90dSteve Block                          size_t size);
2046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
205b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Returns true if pc register contains one of the 'special_values' defined
206b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // below (bad_lr, end_sim_pc).
207b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool has_bad_pc() const;
208b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
209257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // EABI variant for double arguments in use.
210257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  bool use_eabi_hardfloat() {
211257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#if USE_EABI_HARDFLOAT
212257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return true;
213257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#else
214257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return false;
215257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#endif
216257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
217257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  enum special_values {
220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Known bad pc value to ensure that the simulator does not execute
221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // without being properly setup.
222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    bad_lr = -1,
223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // A pc value used to signal the simulator to stop execution.  Generally
224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // the lr is set to this value on transition from native C code to
225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // simulated execution, so that the simulator can "return" to the native
226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // C code.
227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    end_sim_pc = -2
228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  };
229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Unsupported instructions use Format to print an error and stop execution.
2311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void Format(Instruction* instr, const char* format);
232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Checks if the current instruction should be executed based on its
234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // condition bits.
2351e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  bool ConditionallyExecute(Instruction* instr);
236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Helper functions to set the conditional flags in the architecture state.
238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SetNZFlags(int32_t val);
239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SetCFlag(bool val);
240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SetVFlag(bool val);
241257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  bool CarryFrom(int32_t left, int32_t right, int32_t carry = 0);
242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool BorrowFrom(int32_t left, int32_t right);
243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool OverflowFrom(int32_t alu_out,
244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                    int32_t left,
245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                    int32_t right,
246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                    bool addition);
247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
248257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  inline int GetCarry() {
249257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return c_flag_ ? 1 : 0;
250257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  };
251257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
252d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Support for VFP.
253d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  void Compute_FPSCR_Flags(double val1, double val2);
254d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  void Copy_FPSCR_to_APSR();
255d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Helper functions to decode common "addressing" modes
2571e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  int32_t GetShiftRm(Instruction* instr, bool* carry_out);
2581e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  int32_t GetImm(Instruction* instr, bool* carry_out);
2598b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  void ProcessPUW(Instruction* instr,
2608b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch                  int num_regs,
2618b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch                  int operand_size,
2628b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch                  intptr_t* start_address,
2638b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch                  intptr_t* end_address);
2641e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void HandleRList(Instruction* instr, bool load);
2658b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  void HandleVList(Instruction* inst);
2661e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void SoftwareInterrupt(Instruction* instr);
267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2683e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  // Stop helper functions.
2691e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  inline bool isStopInstruction(Instruction* instr);
2703e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  inline bool isWatchedStop(uint32_t bkpt_code);
2713e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  inline bool isEnabledStop(uint32_t bkpt_code);
2723e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  inline void EnableStop(uint32_t bkpt_code);
2733e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  inline void DisableStop(uint32_t bkpt_code);
2743e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  inline void IncreaseStopCounter(uint32_t bkpt_code);
2753e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  void PrintStopInfo(uint32_t code);
2763e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu
277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Read and write memory.
278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline uint8_t ReadBU(int32_t addr);
279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline int8_t ReadB(int32_t addr);
280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void WriteB(int32_t addr, uint8_t value);
281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void WriteB(int32_t addr, int8_t value);
282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2831e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  inline uint16_t ReadHU(int32_t addr, Instruction* instr);
2841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  inline int16_t ReadH(int32_t addr, Instruction* instr);
285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Note: Overloaded on the sign of the value.
2861e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  inline void WriteH(int32_t addr, uint16_t value, Instruction* instr);
2871e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  inline void WriteH(int32_t addr, int16_t value, Instruction* instr);
288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2891e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  inline int ReadW(int32_t addr, Instruction* instr);
2901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  inline void WriteW(int32_t addr, int value, Instruction* instr);
291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
29225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  int32_t* ReadDW(int32_t addr);
29325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  void WriteDW(int32_t addr, int32_t value1, int32_t value2);
29425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Executing is handled based on the instruction type.
2961e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Both type 0 and type 1 rolled into one.
2971e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void DecodeType01(Instruction* instr);
2981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void DecodeType2(Instruction* instr);
2991e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void DecodeType3(Instruction* instr);
3001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void DecodeType4(Instruction* instr);
3011e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void DecodeType5(Instruction* instr);
3021e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void DecodeType6(Instruction* instr);
3031e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void DecodeType7(Instruction* instr);
304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
305d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Support for VFP.
3061e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void DecodeTypeVFP(Instruction* instr);
3071e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void DecodeType6CoprocessorIns(Instruction* instr);
308d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
3091e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(Instruction* instr);
3101e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void DecodeVCMP(Instruction* instr);
3111e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void DecodeVCVTBetweenDoubleAndSingle(Instruction* instr);
3121e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void DecodeVCVTBetweenFloatingPointAndInteger(Instruction* instr);
3136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Executes one instruction.
3151e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void InstructionDecode(Instruction* instr);
316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // ICache.
31844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static void CheckICache(v8::internal::HashMap* i_cache, Instruction* instr);
31944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static void FlushOnePage(v8::internal::HashMap* i_cache, intptr_t start,
32044f0eee88ff00398ff7f715fab053374d808c90dSteve Block                           int size);
32144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static CachePage* GetCachePage(v8::internal::HashMap* i_cache, void* page);
3226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Runtime call support.
3241e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  static void* RedirectExternalReference(
3251e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      void* external_function,
3261e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      v8::internal::ExternalReference::Type type);
327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
328257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // For use in calls that take double value arguments.
329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void GetFpArgs(double* x, double* y);
330257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void GetFpArgs(double* x);
331257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void GetFpArgs(double* x, int32_t* y);
332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SetFpResult(const double& result);
333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void TrashCallerSaveRegisters();
334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
335d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Architecture state.
33650ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen  // Saturating instructions require a Q flag to indicate saturation.
33750ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen  // There is currently no way to read the CPSR directly, and thus read the Q
33850ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen  // flag, so this is left unimplemented.
339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int32_t registers_[16];
340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool n_flag_;
341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool z_flag_;
342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool c_flag_;
343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool v_flag_;
344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
345d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // VFP architecture state.
346d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  unsigned int vfp_register[num_s_registers];
347d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  bool n_flag_FPSCR_;
348d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  bool z_flag_FPSCR_;
349d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  bool c_flag_FPSCR_;
350d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  bool v_flag_FPSCR_;
351d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
35290bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner  // VFP rounding mode. See ARM DDI 0406B Page A2-29.
3531e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  VFPRoundingMode FPSCR_rounding_mode_;
35490bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner
355d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // VFP FP exception flags architecture state.
356d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  bool inv_op_vfp_flag_;
357d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  bool div_zero_vfp_flag_;
358d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  bool overflow_vfp_flag_;
359d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  bool underflow_vfp_flag_;
360d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  bool inexact_vfp_flag_;
361d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
362d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Simulator support.
363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  char* stack_;
364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool pc_modified_;
365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int icount_;
366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Debugger input.
3683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  char* last_debugger_input_;
3693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Icache simulation
37144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  v8::internal::HashMap* i_cache_;
3726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
373d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Registered breakpoints.
3741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  Instruction* break_pc_;
3751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  Instr break_instr_;
3763e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu
37744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  v8::internal::Isolate* isolate_;
37844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
3793e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  // A stop is watched if its code is less than kNumOfWatchedStops.
3803e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  // Only watched stops support enabling/disabling and the counter feature.
3813e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  static const uint32_t kNumOfWatchedStops = 256;
3823e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu
3833e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  // Breakpoint is disabled if bit 31 is set.
3843e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  static const uint32_t kStopDisabledBit = 1 << 31;
3853e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu
3863e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  // A stop is enabled, meaning the simulator will stop when meeting the
3873e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  // instruction, if bit 31 of watched_stops[code].count is unset.
3883e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  // The value watched_stops[code].count & ~(1 << 31) indicates how many times
3893e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  // the breakpoint was hit or gone through.
3901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  struct StopCountAndDesc {
3913e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu    uint32_t count;
3923e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu    char* desc;
3933e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  };
3941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  StopCountAndDesc watched_stops[kNumOfWatchedStops];
395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3975913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck
3985913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck// When running with the simulator transition into simulated execution at this
3995913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck// point.
4005913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck#define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4) \
40144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  reinterpret_cast<Object*>(Simulator::current(Isolate::Current())->Call( \
4025913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      FUNCTION_ADDR(entry), 5, p0, p1, p2, p3, p4))
4035913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck
40444f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7) \
40544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Simulator::current(Isolate::Current())->Call( \
40644f0eee88ff00398ff7f715fab053374d808c90dSteve Block      entry, 9, p0, p1, p2, p3, NULL, p4, p5, p6, p7)
4075913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck
40844f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define TRY_CATCH_FROM_ADDRESS(try_catch_address)                              \
40944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  try_catch_address == NULL ?                                                  \
41044f0eee88ff00398ff7f715fab053374d808c90dSteve Block      NULL : *(reinterpret_cast<TryCatch**>(try_catch_address))
4115913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck
4125913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck
413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The simulator has its own stack. Thus it has a different stack limit from
414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// the C-based native code.  Setting the c_limit to indicate a very small
415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// stack cause stack overflow errors, since the simulator ignores the input.
416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// This is unlikely to be an issue in practice, though it might cause testing
417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// trouble down the line.
418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass SimulatorStack : public v8::internal::AllStatic {
419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
420257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  static inline uintptr_t JsLimitFromCLimit(v8::internal::Isolate* isolate,
421257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                            uintptr_t c_limit) {
422257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return Simulator::current(isolate)->StackLimit();
423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
424d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
425d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  static inline uintptr_t RegisterCTryCatch(uintptr_t try_catch_address) {
42644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Simulator* sim = Simulator::current(Isolate::Current());
427d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    return sim->PushAddress(try_catch_address);
428d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
429d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
430d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  static inline void UnregisterCTryCatch() {
43144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Simulator::current(Isolate::Current())->PopAddress();
432d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4355913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck} }  // namespace v8::internal
436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4375913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck#endif  // !defined(USE_SIMULATOR)
438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif  // V8_ARM_SIMULATOR_ARM_H_
439