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