Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(125)

Side by Side Diff: src/mips/simulator-mips.h

Issue 6759025: Version 3.2.6 (Closed) Base URL: https://v8.googlecode.com/svn/trunk
Patch Set: Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/mips/register-allocator-mips-inl.h ('k') | src/mips/simulator-mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 19 matching lines...) Expand all
30 // MIPS binary. This Simulator allows us to run and debug MIPS code generation 30 // MIPS binary. This Simulator allows us to run and debug MIPS code generation
31 // on regular desktop machines. 31 // on regular desktop machines.
32 // V8 calls into generated code by "calling" the CALL_GENERATED_CODE macro, 32 // V8 calls into generated code by "calling" the CALL_GENERATED_CODE macro,
33 // which will start execution in the Simulator or forwards to the real entry 33 // which will start execution in the Simulator or forwards to the real entry
34 // on a MIPS HW platform. 34 // on a MIPS HW platform.
35 35
36 #ifndef V8_MIPS_SIMULATOR_MIPS_H_ 36 #ifndef V8_MIPS_SIMULATOR_MIPS_H_
37 #define V8_MIPS_SIMULATOR_MIPS_H_ 37 #define V8_MIPS_SIMULATOR_MIPS_H_
38 38
39 #include "allocation.h" 39 #include "allocation.h"
40 #include "constants-mips.h"
40 41
41 #if defined(__mips) && !defined(USE_SIMULATOR) 42 #if !defined(USE_SIMULATOR)
43 // Running without a simulator on a native mips platform.
44
45 namespace v8 {
46 namespace internal {
42 47
43 // When running without a simulator we call the entry directly. 48 // When running without a simulator we call the entry directly.
44 #define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4) \ 49 #define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4) \
45 entry(p0, p1, p2, p3, p4); 50 entry(p0, p1, p2, p3, p4)
51
52 typedef int (*mips_regexp_matcher)(String*, int, const byte*, const byte*,
53 void*, int*, Address, int, Isolate*);
54
55 // Call the generated regexp code directly. The code at the entry address
56 // should act as a function matching the type arm_regexp_matcher.
57 // The fifth argument is a dummy that reserves the space used for
58 // the return address added by the ExitFrame in native calls.
59 #define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7) \
60 (FUNCTION_CAST<mips_regexp_matcher>(entry)( \
61 p0, p1, p2, p3, NULL, p4, p5, p6, p7))
62
63 #define TRY_CATCH_FROM_ADDRESS(try_catch_address) \
64 reinterpret_cast<TryCatch*>(try_catch_address)
46 65
47 // The stack limit beyond which we will throw stack overflow errors in 66 // The stack limit beyond which we will throw stack overflow errors in
48 // generated code. Because generated code on mips uses the C stack, we 67 // generated code. Because generated code on mips uses the C stack, we
49 // just use the C stack limit. 68 // just use the C stack limit.
50 class SimulatorStack : public v8::internal::AllStatic { 69 class SimulatorStack : public v8::internal::AllStatic {
51 public: 70 public:
52 static inline uintptr_t JsLimitFromCLimit(uintptr_t c_limit) { 71 static inline uintptr_t JsLimitFromCLimit(uintptr_t c_limit) {
53 return c_limit; 72 return c_limit;
54 } 73 }
55 74
56 static inline uintptr_t RegisterCTryCatch(uintptr_t try_catch_address) { 75 static inline uintptr_t RegisterCTryCatch(uintptr_t try_catch_address) {
57 return try_catch_address; 76 return try_catch_address;
58 } 77 }
59 78
60 static inline void UnregisterCTryCatch() { } 79 static inline void UnregisterCTryCatch() { }
61 }; 80 };
62 81
82 } } // namespace v8::internal
83
63 // Calculated the stack limit beyond which we will throw stack overflow errors. 84 // Calculated the stack limit beyond which we will throw stack overflow errors.
64 // This macro must be called from a C++ method. It relies on being able to take 85 // This macro must be called from a C++ method. It relies on being able to take
65 // the address of "this" to get a value on the current execution stack and then 86 // the address of "this" to get a value on the current execution stack and then
66 // calculates the stack limit based on that value. 87 // calculates the stack limit based on that value.
67 // NOTE: The check for overflow is not safe as there is no guarantee that the 88 // NOTE: The check for overflow is not safe as there is no guarantee that the
68 // running thread has its stack in all memory up to address 0x00000000. 89 // running thread has its stack in all memory up to address 0x00000000.
69 #define GENERATED_CODE_STACK_LIMIT(limit) \ 90 #define GENERATED_CODE_STACK_LIMIT(limit) \
70 (reinterpret_cast<uintptr_t>(this) >= limit ? \ 91 (reinterpret_cast<uintptr_t>(this) >= limit ? \
71 reinterpret_cast<uintptr_t>(this) - limit : 0) 92 reinterpret_cast<uintptr_t>(this) - limit : 0)
72 93
73 // Call the generated regexp code directly. The entry function pointer should 94 #else // !defined(USE_SIMULATOR)
74 // expect seven int/pointer sized arguments and return an int. 95 // Running with a simulator.
75 #define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6) \
76 entry(p0, p1, p2, p3, p4, p5, p6)
77 96
78 #define TRY_CATCH_FROM_ADDRESS(try_catch_address) \ 97 #include "hashmap.h"
79 reinterpret_cast<TryCatch*>(try_catch_address)
80 98
99 namespace v8 {
100 namespace internal {
81 101
82 #else // #if !defined(__mips) || defined(USE_SIMULATOR) 102 // -----------------------------------------------------------------------------
103 // Utility functions
83 104
84 // When running with the simulator transition into simulated execution at this 105 class CachePage {
85 // point. 106 public:
86 #define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4) \ 107 static const int LINE_VALID = 0;
87 reinterpret_cast<Object*>(\ 108 static const int LINE_INVALID = 1;
88 assembler::mips::Simulator::current()->Call(FUNCTION_ADDR(entry), 5, \
89 p0, p1, p2, p3, p4))
90 109
91 #define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6) \ 110 static const int kPageShift = 12;
92 assembler::mips::Simulator::current()->Call(\ 111 static const int kPageSize = 1 << kPageShift;
93 FUNCTION_ADDR(entry), 7, p0, p1, p2, p3, p4, p5, p6) 112 static const int kPageMask = kPageSize - 1;
113 static const int kLineShift = 2; // The cache line is only 4 bytes right now.
114 static const int kLineLength = 1 << kLineShift;
115 static const int kLineMask = kLineLength - 1;
94 116
95 #define TRY_CATCH_FROM_ADDRESS(try_catch_address) \ 117 CachePage() {
96 try_catch_address == NULL ? \ 118 memset(&validity_map_, LINE_INVALID, sizeof(validity_map_));
97 NULL : *(reinterpret_cast<TryCatch**>(try_catch_address)) 119 }
98 120
121 char* ValidityByte(int offset) {
122 return &validity_map_[offset >> kLineShift];
123 }
99 124
100 namespace assembler { 125 char* CachedData(int offset) {
101 namespace mips { 126 return &data_[offset];
127 }
128
129 private:
130 char data_[kPageSize]; // The cached data.
131 static const int kValidityMapSize = kPageSize >> kLineShift;
132 char validity_map_[kValidityMapSize]; // One byte per line.
133 };
102 134
103 class Simulator { 135 class Simulator {
104 public: 136 public:
105 friend class Debugger; 137 friend class MipsDebugger;
106 138
107 // Registers are declared in order. See SMRL chapter 2. 139 // Registers are declared in order. See SMRL chapter 2.
108 enum Register { 140 enum Register {
109 no_reg = -1, 141 no_reg = -1,
110 zero_reg = 0, 142 zero_reg = 0,
111 at, 143 at,
112 v0, v1, 144 v0, v1,
113 a0, a1, a2, a3, 145 a0, a1, a2, a3,
114 t0, t1, t2, t3, t4, t5, t6, t7, 146 t0, t1, t2, t3, t4, t5, t6, t7,
115 s0, s1, s2, s3, s4, s5, s6, s7, 147 s0, s1, s2, s3, s4, s5, s6, s7,
(...skipping 20 matching lines...) Expand all
136 f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, 168 f16, f17, f18, f19, f20, f21, f22, f23, f24, f25,
137 f26, f27, f28, f29, f30, f31, 169 f26, f27, f28, f29, f30, f31,
138 kNumFPURegisters 170 kNumFPURegisters
139 }; 171 };
140 172
141 Simulator(); 173 Simulator();
142 ~Simulator(); 174 ~Simulator();
143 175
144 // The currently executing Simulator instance. Potentially there can be one 176 // The currently executing Simulator instance. Potentially there can be one
145 // for each native thread. 177 // for each native thread.
146 static Simulator* current(); 178 static Simulator* current(v8::internal::Isolate* isolate);
147 179
148 // Accessors for register state. Reading the pc value adheres to the MIPS 180 // Accessors for register state. Reading the pc value adheres to the MIPS
149 // architecture specification and is off by a 8 from the currently executing 181 // architecture specification and is off by a 8 from the currently executing
150 // instruction. 182 // instruction.
151 void set_register(int reg, int32_t value); 183 void set_register(int reg, int32_t value);
152 int32_t get_register(int reg) const; 184 int32_t get_register(int reg) const;
153 // Same for FPURegisters 185 // Same for FPURegisters
154 void set_fpu_register(int fpureg, int32_t value); 186 void set_fpu_register(int fpureg, int32_t value);
187 void set_fpu_register_float(int fpureg, float value);
155 void set_fpu_register_double(int fpureg, double value); 188 void set_fpu_register_double(int fpureg, double value);
156 int32_t get_fpu_register(int fpureg) const; 189 int32_t get_fpu_register(int fpureg) const;
190 int64_t get_fpu_register_long(int fpureg) const;
191 float get_fpu_register_float(int fpureg) const;
157 double get_fpu_register_double(int fpureg) const; 192 double get_fpu_register_double(int fpureg) const;
193 void set_fcsr_bit(uint32_t cc, bool value);
194 bool test_fcsr_bit(uint32_t cc);
195 bool set_fcsr_round_error(double original, double rounded);
158 196
159 // Special case of set_register and get_register to access the raw PC value. 197 // Special case of set_register and get_register to access the raw PC value.
160 void set_pc(int32_t value); 198 void set_pc(int32_t value);
161 int32_t get_pc() const; 199 int32_t get_pc() const;
162 200
163 // Accessor to the internal simulator stack area. 201 // Accessor to the internal simulator stack area.
164 uintptr_t StackLimit() const; 202 uintptr_t StackLimit() const;
165 203
166 // Executes MIPS instructions until the PC reaches end_sim_pc. 204 // Executes MIPS instructions until the PC reaches end_sim_pc.
167 void Execute(); 205 void Execute();
168 206
169 // Call on program start. 207 // Call on program start.
170 static void Initialize(); 208 static void Initialize();
171 209
172 // V8 generally calls into generated JS code with 5 parameters and into 210 // V8 generally calls into generated JS code with 5 parameters and into
173 // generated RegExp code with 7 parameters. This is a convenience function, 211 // generated RegExp code with 7 parameters. This is a convenience function,
174 // which sets up the simulator state and grabs the result on return. 212 // which sets up the simulator state and grabs the result on return.
175 int32_t Call(byte_* entry, int argument_count, ...); 213 int32_t Call(byte* entry, int argument_count, ...);
176 214
177 // Push an address onto the JS stack. 215 // Push an address onto the JS stack.
178 uintptr_t PushAddress(uintptr_t address); 216 uintptr_t PushAddress(uintptr_t address);
179 217
180 // Pop an address from the JS stack. 218 // Pop an address from the JS stack.
181 uintptr_t PopAddress(); 219 uintptr_t PopAddress();
182 220
221 // ICache checking.
222 static void FlushICache(v8::internal::HashMap* i_cache, void* start,
223 size_t size);
224
225 // Returns true if pc register contains one of the 'special_values' defined
226 // below (bad_ra, end_sim_pc).
227 bool has_bad_pc() const;
228
183 private: 229 private:
184 enum special_values { 230 enum special_values {
185 // Known bad pc value to ensure that the simulator does not execute 231 // Known bad pc value to ensure that the simulator does not execute
186 // without being properly setup. 232 // without being properly setup.
187 bad_ra = -1, 233 bad_ra = -1,
188 // A pc value used to signal the simulator to stop execution. Generally 234 // A pc value used to signal the simulator to stop execution. Generally
189 // the ra is set to this value on transition from native C code to 235 // the ra is set to this value on transition from native C code to
190 // simulated execution, so that the simulator can "return" to the native 236 // simulated execution, so that the simulator can "return" to the native
191 // C code. 237 // C code.
192 end_sim_pc = -2, 238 end_sim_pc = -2,
(...skipping 23 matching lines...) Expand all
216 inline void WriteD(int32_t addr, double value, Instruction* instr); 262 inline void WriteD(int32_t addr, double value, Instruction* instr);
217 263
218 // Operations depending on endianness. 264 // Operations depending on endianness.
219 // Get Double Higher / Lower word. 265 // Get Double Higher / Lower word.
220 inline int32_t GetDoubleHIW(double* addr); 266 inline int32_t GetDoubleHIW(double* addr);
221 inline int32_t GetDoubleLOW(double* addr); 267 inline int32_t GetDoubleLOW(double* addr);
222 // Set Double Higher / Lower word. 268 // Set Double Higher / Lower word.
223 inline int32_t SetDoubleHIW(double* addr); 269 inline int32_t SetDoubleHIW(double* addr);
224 inline int32_t SetDoubleLOW(double* addr); 270 inline int32_t SetDoubleLOW(double* addr);
225 271
226
227 // Executing is handled based on the instruction type. 272 // Executing is handled based on the instruction type.
228 void DecodeTypeRegister(Instruction* instr); 273 void DecodeTypeRegister(Instruction* instr);
274
275 // Helper function for DecodeTypeRegister.
276 void ConfigureTypeRegister(Instruction* instr,
277 int32_t& alu_out,
278 int64_t& i64hilo,
279 uint64_t& u64hilo,
280 int32_t& next_pc,
281 bool& do_interrupt);
282
229 void DecodeTypeImmediate(Instruction* instr); 283 void DecodeTypeImmediate(Instruction* instr);
230 void DecodeTypeJump(Instruction* instr); 284 void DecodeTypeJump(Instruction* instr);
231 285
232 // Used for breakpoints and traps. 286 // Used for breakpoints and traps.
233 void SoftwareInterrupt(Instruction* instr); 287 void SoftwareInterrupt(Instruction* instr);
234 288
235 // Executes one instruction. 289 // Executes one instruction.
236 void InstructionDecode(Instruction* instr); 290 void InstructionDecode(Instruction* instr);
237 // Execute one instruction placed in a branch delay slot. 291 // Execute one instruction placed in a branch delay slot.
238 void BranchDelayInstructionDecode(Instruction* instr) { 292 void BranchDelayInstructionDecode(Instruction* instr) {
239 if (instr->IsForbiddenInBranchDelay()) { 293 if (instr->IsForbiddenInBranchDelay()) {
240 V8_Fatal(__FILE__, __LINE__, 294 V8_Fatal(__FILE__, __LINE__,
241 "Eror:Unexpected %i opcode in a branch delay slot.", 295 "Eror:Unexpected %i opcode in a branch delay slot.",
242 instr->OpcodeField()); 296 instr->OpcodeValue());
243 } 297 }
244 InstructionDecode(instr); 298 InstructionDecode(instr);
245 } 299 }
246 300
301 // ICache.
302 static void CheckICache(v8::internal::HashMap* i_cache, Instruction* instr);
303 static void FlushOnePage(v8::internal::HashMap* i_cache, intptr_t start,
304 int size);
305 static CachePage* GetCachePage(v8::internal::HashMap* i_cache, void* page);
306
307
247 enum Exception { 308 enum Exception {
248 none, 309 none,
249 kIntegerOverflow, 310 kIntegerOverflow,
250 kIntegerUnderflow, 311 kIntegerUnderflow,
251 kDivideByZero, 312 kDivideByZero,
252 kNumExceptions 313 kNumExceptions
253 }; 314 };
254 int16_t exceptions[kNumExceptions]; 315 int16_t exceptions[kNumExceptions];
255 316
256 // Exceptions. 317 // Exceptions.
257 void SignalExceptions(); 318 void SignalExceptions();
258 319
259 // Runtime call support. 320 // Runtime call support.
260 static void* RedirectExternalReference(void* external_function, 321 static void* RedirectExternalReference(void* external_function,
261 bool fp_return); 322 ExternalReference::Type type);
262 323
263 // Used for real time calls that takes two double values as arguments and 324 // Used for real time calls that takes two double values as arguments and
264 // returns a double. 325 // returns a double.
265 void SetFpResult(double result); 326 void SetFpResult(double result);
266 327
267 // Architecture state. 328 // Architecture state.
268 // Registers. 329 // Registers.
269 int32_t registers_[kNumSimuRegisters]; 330 int32_t registers_[kNumSimuRegisters];
270 // Coprocessor Registers. 331 // Coprocessor Registers.
271 int32_t FPUregisters_[kNumFPURegisters]; 332 int32_t FPUregisters_[kNumFPURegisters];
333 // FPU control register.
334 uint32_t FCSR_;
272 335
273 // Simulator support. 336 // Simulator support.
274 char* stack_; 337 char* stack_;
338 size_t stack_size_;
275 bool pc_modified_; 339 bool pc_modified_;
276 int icount_; 340 int icount_;
277 static bool initialized_; 341 int break_count_;
342
343 // Icache simulation
344 v8::internal::HashMap* i_cache_;
278 345
279 // Registered breakpoints. 346 // Registered breakpoints.
280 Instruction* break_pc_; 347 Instruction* break_pc_;
281 Instr break_instr_; 348 Instr break_instr_;
349
350 v8::internal::Isolate* isolate_;
282 }; 351 };
283 352
284 } } // namespace assembler::mips 353
354 // When running with the simulator transition into simulated execution at this
355 // point.
356 #define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4) \
357 reinterpret_cast<Object*>(Simulator::current(Isolate::Current())->Call( \
358 FUNCTION_ADDR(entry), 5, p0, p1, p2, p3, p4))
359
360 #define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7) \
361 Simulator::current(Isolate::Current())->Call( \
362 entry, 9, p0, p1, p2, p3, NULL, p4, p5, p6, p7)
363
364 #define TRY_CATCH_FROM_ADDRESS(try_catch_address) \
365 try_catch_address == NULL ? \
366 NULL : *(reinterpret_cast<TryCatch**>(try_catch_address))
285 367
286 368
287 // The simulator has its own stack. Thus it has a different stack limit from 369 // The simulator has its own stack. Thus it has a different stack limit from
288 // the C-based native code. Setting the c_limit to indicate a very small 370 // the C-based native code. Setting the c_limit to indicate a very small
289 // stack cause stack overflow errors, since the simulator ignores the input. 371 // stack cause stack overflow errors, since the simulator ignores the input.
290 // This is unlikely to be an issue in practice, though it might cause testing 372 // This is unlikely to be an issue in practice, though it might cause testing
291 // trouble down the line. 373 // trouble down the line.
292 class SimulatorStack : public v8::internal::AllStatic { 374 class SimulatorStack : public v8::internal::AllStatic {
293 public: 375 public:
294 static inline uintptr_t JsLimitFromCLimit(uintptr_t c_limit) { 376 static inline uintptr_t JsLimitFromCLimit(uintptr_t c_limit) {
295 return assembler::mips::Simulator::current()->StackLimit(); 377 return Simulator::current(Isolate::Current())->StackLimit();
296 } 378 }
297 379
298 static inline uintptr_t RegisterCTryCatch(uintptr_t try_catch_address) { 380 static inline uintptr_t RegisterCTryCatch(uintptr_t try_catch_address) {
299 assembler::mips::Simulator* sim = assembler::mips::Simulator::current(); 381 Simulator* sim = Simulator::current(Isolate::Current());
300 return sim->PushAddress(try_catch_address); 382 return sim->PushAddress(try_catch_address);
301 } 383 }
302 384
303 static inline void UnregisterCTryCatch() { 385 static inline void UnregisterCTryCatch() {
304 assembler::mips::Simulator::current()->PopAddress(); 386 Simulator::current(Isolate::Current())->PopAddress();
305 } 387 }
306 }; 388 };
307 389
308 #endif // !defined(__mips) || defined(USE_SIMULATOR) 390 } } // namespace v8::internal
309 391
392 #endif // !defined(USE_SIMULATOR)
310 #endif // V8_MIPS_SIMULATOR_MIPS_H_ 393 #endif // V8_MIPS_SIMULATOR_MIPS_H_
311 394
OLDNEW
« no previous file with comments | « src/mips/register-allocator-mips-inl.h ('k') | src/mips/simulator-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698