v8  3.25.30(node0.11.13)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
test-utils-arm64.h
Go to the documentation of this file.
1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 #ifndef V8_ARM64_TEST_UTILS_ARM64_H_
29 #define V8_ARM64_TEST_UTILS_ARM64_H_
30 
31 #include "v8.h"
32 
33 #include "macro-assembler.h"
35 #include "arm64/utils-arm64.h"
36 #include "cctest.h"
37 
38 
39 using namespace v8::internal;
40 
41 
42 // RegisterDump: Object allowing integer, floating point and flags registers
43 // to be saved to itself for future reference.
44 class RegisterDump {
45  public:
46  RegisterDump() : completed_(false) {}
47 
48  // The Dump method generates code to store a snapshot of the register values.
49  // It needs to be able to use the stack temporarily, and requires that the
50  // current stack pointer is csp, and is properly aligned.
51  //
52  // The dumping code is generated though the given MacroAssembler. No registers
53  // are corrupted in the process, but the stack is used briefly. The flags will
54  // be corrupted during this call.
55  void Dump(MacroAssembler* assm);
56 
57  // Register accessors.
58  inline int32_t wreg(unsigned code) const {
59  if (code == kSPRegInternalCode) {
60  return wspreg();
61  }
62  ASSERT(RegAliasesMatch(code));
63  return dump_.w_[code];
64  }
65 
66  inline int64_t xreg(unsigned code) const {
67  if (code == kSPRegInternalCode) {
68  return spreg();
69  }
70  ASSERT(RegAliasesMatch(code));
71  return dump_.x_[code];
72  }
73 
74  // FPRegister accessors.
75  inline uint32_t sreg_bits(unsigned code) const {
76  ASSERT(FPRegAliasesMatch(code));
77  return dump_.s_[code];
78  }
79 
80  inline float sreg(unsigned code) const {
81  return rawbits_to_float(sreg_bits(code));
82  }
83 
84  inline uint64_t dreg_bits(unsigned code) const {
85  ASSERT(FPRegAliasesMatch(code));
86  return dump_.d_[code];
87  }
88 
89  inline double dreg(unsigned code) const {
90  return rawbits_to_double(dreg_bits(code));
91  }
92 
93  // Stack pointer accessors.
94  inline int64_t spreg() const {
95  ASSERT(SPRegAliasesMatch());
96  return dump_.sp_;
97  }
98 
99  inline int64_t wspreg() const {
100  ASSERT(SPRegAliasesMatch());
101  return dump_.wsp_;
102  }
103 
104  // Flags accessors.
105  inline uint64_t flags_nzcv() const {
106  ASSERT(IsComplete());
107  ASSERT((dump_.flags_ & ~Flags_mask) == 0);
108  return dump_.flags_ & Flags_mask;
109  }
110 
111  inline bool IsComplete() const {
112  return completed_;
113  }
114 
115  private:
116  // Indicate whether the dump operation has been completed.
117  bool completed_;
118 
119  // Check that the lower 32 bits of x<code> exactly match the 32 bits of
120  // w<code>. A failure of this test most likely represents a failure in the
121  // ::Dump method, or a failure in the simulator.
122  bool RegAliasesMatch(unsigned code) const {
123  ASSERT(IsComplete());
124  ASSERT(code < kNumberOfRegisters);
125  return ((dump_.x_[code] & kWRegMask) == dump_.w_[code]);
126  }
127 
128  // As RegAliasesMatch, but for the stack pointer.
129  bool SPRegAliasesMatch() const {
130  ASSERT(IsComplete());
131  return ((dump_.sp_ & kWRegMask) == dump_.wsp_);
132  }
133 
134  // As RegAliasesMatch, but for floating-point registers.
135  bool FPRegAliasesMatch(unsigned code) const {
136  ASSERT(IsComplete());
138  return (dump_.d_[code] & kSRegMask) == dump_.s_[code];
139  }
140 
141  // Store all the dumped elements in a simple struct so the implementation can
142  // use offsetof to quickly find the correct field.
143  struct dump_t {
144  // Core registers.
145  uint64_t x_[kNumberOfRegisters];
146  uint32_t w_[kNumberOfRegisters];
147 
148  // Floating-point registers, as raw bits.
149  uint64_t d_[kNumberOfFPRegisters];
150  uint32_t s_[kNumberOfFPRegisters];
151 
152  // The stack pointer.
153  uint64_t sp_;
154  uint64_t wsp_;
155 
156  // NZCV flags, stored in bits 28 to 31.
157  // bit[31] : Negative
158  // bit[30] : Zero
159  // bit[29] : Carry
160  // bit[28] : oVerflow
161  uint64_t flags_;
162  } dump_;
163 
164  static dump_t for_sizeof();
165  STATIC_ASSERT(sizeof(for_sizeof().d_[0]) == kDRegSize);
166  STATIC_ASSERT(sizeof(for_sizeof().s_[0]) == kSRegSize);
167  STATIC_ASSERT(sizeof(for_sizeof().d_[0]) == kXRegSize);
168  STATIC_ASSERT(sizeof(for_sizeof().s_[0]) == kWRegSize);
169  STATIC_ASSERT(sizeof(for_sizeof().x_[0]) == kXRegSize);
170  STATIC_ASSERT(sizeof(for_sizeof().w_[0]) == kWRegSize);
171 };
172 
173 // Some of these methods don't use the RegisterDump argument, but they have to
174 // accept them so that they can overload those that take register arguments.
175 bool Equal32(uint32_t expected, const RegisterDump*, uint32_t result);
176 bool Equal64(uint64_t expected, const RegisterDump*, uint64_t result);
177 
178 bool EqualFP32(float expected, const RegisterDump*, float result);
179 bool EqualFP64(double expected, const RegisterDump*, double result);
180 
181 bool Equal32(uint32_t expected, const RegisterDump* core, const Register& reg);
182 bool Equal64(uint64_t expected, const RegisterDump* core, const Register& reg);
183 
184 bool EqualFP32(float expected, const RegisterDump* core,
185  const FPRegister& fpreg);
186 bool EqualFP64(double expected, const RegisterDump* core,
187  const FPRegister& fpreg);
188 
189 bool Equal64(const Register& reg0, const RegisterDump* core,
190  const Register& reg1);
191 
192 bool EqualNzcv(uint32_t expected, uint32_t result);
193 
194 bool EqualRegisters(const RegisterDump* a, const RegisterDump* b);
195 
196 // Populate the w, x and r arrays with registers from the 'allowed' mask. The
197 // r array will be populated with <reg_size>-sized registers,
198 //
199 // This allows for tests which use large, parameterized blocks of registers
200 // (such as the push and pop tests), but where certain registers must be
201 // avoided as they are used for other purposes.
202 //
203 // Any of w, x, or r can be NULL if they are not required.
204 //
205 // The return value is a RegList indicating which registers were allocated.
207  int reg_size, int reg_count, RegList allowed);
208 
209 // As PopulateRegisterArray, but for floating-point registers.
211  int reg_size, int reg_count, RegList allowed);
212 
213 // Ovewrite the contents of the specified registers. This enables tests to
214 // check that register contents are written in cases where it's likely that the
215 // correct outcome could already be stored in the register.
216 //
217 // This always overwrites X-sized registers. If tests are operating on W
218 // registers, a subsequent write into an aliased W register should clear the
219 // top word anyway, so clobbering the full X registers should make tests more
220 // rigorous.
221 void Clobber(MacroAssembler* masm, RegList reg_list,
222  uint64_t const value = 0xfedcba9876543210UL);
223 
224 // As Clobber, but for FP registers.
225 void ClobberFP(MacroAssembler* masm, RegList reg_list,
226  double const value = kFP64SignallingNaN);
227 
228 // As Clobber, but for a CPURegList with either FP or integer registers. When
229 // using this method, the clobber value is always the default for the basic
230 // Clobber or ClobberFP functions.
231 void Clobber(MacroAssembler* masm, CPURegList reg_list);
232 
233 #endif // V8_ARM64_TEST_UTILS_ARM64_H_
const unsigned kWRegSize
int64_t xreg(unsigned code) const
float sreg(unsigned code) const
const int64_t kWRegMask
int int32_t
Definition: unicode.cc:47
uint32_t RegList
Definition: frames.h:41
void Clobber(MacroAssembler *masm, RegList reg_list, uint64_t const value=0xfedcba9876543210UL)
uint64_t dreg_bits(unsigned code) const
bool EqualNzcv(uint32_t expected, uint32_t result)
#define ASSERT(condition)
Definition: checks.h:329
RegList PopulateFPRegisterArray(FPRegister *s, FPRegister *d, FPRegister *v, int reg_size, int reg_count, RegList allowed)
STATIC_ASSERT(sizeof(CPURegister)==sizeof(Register))
double dreg(unsigned code) const
bool Equal32(uint32_t expected, const RegisterDump *, uint32_t result)
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization extra verbose compilation tracing generate extra code(assertions) for debugging") DEFINE_bool(code_comments
const unsigned kSPRegInternalCode
bool EqualFP64(double expected, const RegisterDump *, double result)
bool Equal64(uint64_t expected, const RegisterDump *, uint64_t result)
const unsigned kNumberOfFPRegisters
const unsigned kSRegSize
bool EqualFP32(float expected, const RegisterDump *, float result)
bool EqualRegisters(const RegisterDump *a, const RegisterDump *b)
bool IsComplete() const
int64_t wspreg() const
const unsigned kXRegSize
const unsigned kNumberOfRegisters
uint32_t sreg_bits(unsigned code) const
const unsigned kDRegSize
const int64_t kSRegMask
uint64_t flags_nzcv() const
void ClobberFP(MacroAssembler *masm, RegList reg_list, double const value=kFP64SignallingNaN)
int32_t wreg(unsigned code) const
RegList PopulateRegisterArray(Register *w, Register *x, Register *r, int reg_size, int reg_count, RegList allowed)
int64_t spreg() const