OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 }; | 73 }; |
74 | 74 |
75 } } // namespace v8::internal | 75 } } // namespace v8::internal |
76 | 76 |
77 #else // !defined(USE_SIMULATOR) | 77 #else // !defined(USE_SIMULATOR) |
78 // Running with a simulator. | 78 // Running with a simulator. |
79 | 79 |
80 #include "constants-arm.h" | 80 #include "constants-arm.h" |
81 #include "hashmap.h" | 81 #include "hashmap.h" |
82 | 82 |
83 namespace assembler { | 83 namespace v8 { |
84 namespace arm { | 84 namespace internal { |
85 | 85 |
86 class CachePage { | 86 class CachePage { |
87 public: | 87 public: |
88 static const int LINE_VALID = 0; | 88 static const int LINE_VALID = 0; |
89 static const int LINE_INVALID = 1; | 89 static const int LINE_INVALID = 1; |
90 | 90 |
91 static const int kPageShift = 12; | 91 static const int kPageShift = 12; |
92 static const int kPageSize = 1 << kPageShift; | 92 static const int kPageSize = 1 << kPageShift; |
93 static const int kPageMask = kPageSize - 1; | 93 static const int kPageMask = kPageSize - 1; |
94 static const int kLineShift = 2; // The cache line is only 4 bytes right now. | 94 static const int kLineShift = 2; // The cache line is only 4 bytes right now. |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 // without being properly setup. | 196 // without being properly setup. |
197 bad_lr = -1, | 197 bad_lr = -1, |
198 // A pc value used to signal the simulator to stop execution. Generally | 198 // A pc value used to signal the simulator to stop execution. Generally |
199 // the lr is set to this value on transition from native C code to | 199 // the lr is set to this value on transition from native C code to |
200 // simulated execution, so that the simulator can "return" to the native | 200 // simulated execution, so that the simulator can "return" to the native |
201 // C code. | 201 // C code. |
202 end_sim_pc = -2 | 202 end_sim_pc = -2 |
203 }; | 203 }; |
204 | 204 |
205 // Unsupported instructions use Format to print an error and stop execution. | 205 // Unsupported instructions use Format to print an error and stop execution. |
206 void Format(Instr* instr, const char* format); | 206 void Format(Instruction* instr, const char* format); |
207 | 207 |
208 // Checks if the current instruction should be executed based on its | 208 // Checks if the current instruction should be executed based on its |
209 // condition bits. | 209 // condition bits. |
210 bool ConditionallyExecute(Instr* instr); | 210 bool ConditionallyExecute(Instruction* instr); |
211 | 211 |
212 // Helper functions to set the conditional flags in the architecture state. | 212 // Helper functions to set the conditional flags in the architecture state. |
213 void SetNZFlags(int32_t val); | 213 void SetNZFlags(int32_t val); |
214 void SetCFlag(bool val); | 214 void SetCFlag(bool val); |
215 void SetVFlag(bool val); | 215 void SetVFlag(bool val); |
216 bool CarryFrom(int32_t left, int32_t right); | 216 bool CarryFrom(int32_t left, int32_t right); |
217 bool BorrowFrom(int32_t left, int32_t right); | 217 bool BorrowFrom(int32_t left, int32_t right); |
218 bool OverflowFrom(int32_t alu_out, | 218 bool OverflowFrom(int32_t alu_out, |
219 int32_t left, | 219 int32_t left, |
220 int32_t right, | 220 int32_t right, |
221 bool addition); | 221 bool addition); |
222 | 222 |
223 // Support for VFP. | 223 // Support for VFP. |
224 void Compute_FPSCR_Flags(double val1, double val2); | 224 void Compute_FPSCR_Flags(double val1, double val2); |
225 void Copy_FPSCR_to_APSR(); | 225 void Copy_FPSCR_to_APSR(); |
226 | 226 |
227 // Helper functions to decode common "addressing" modes | 227 // Helper functions to decode common "addressing" modes |
228 int32_t GetShiftRm(Instr* instr, bool* carry_out); | 228 int32_t GetShiftRm(Instruction* instr, bool* carry_out); |
229 int32_t GetImm(Instr* instr, bool* carry_out); | 229 int32_t GetImm(Instruction* instr, bool* carry_out); |
230 void HandleRList(Instr* instr, bool load); | 230 void HandleRList(Instruction* instr, bool load); |
231 void SoftwareInterrupt(Instr* instr); | 231 void SoftwareInterrupt(Instruction* instr); |
232 | 232 |
233 // Stop helper functions. | 233 // Stop helper functions. |
234 inline bool isStopInstruction(Instr* instr); | 234 inline bool isStopInstruction(Instruction* instr); |
235 inline bool isWatchedStop(uint32_t bkpt_code); | 235 inline bool isWatchedStop(uint32_t bkpt_code); |
236 inline bool isEnabledStop(uint32_t bkpt_code); | 236 inline bool isEnabledStop(uint32_t bkpt_code); |
237 inline void EnableStop(uint32_t bkpt_code); | 237 inline void EnableStop(uint32_t bkpt_code); |
238 inline void DisableStop(uint32_t bkpt_code); | 238 inline void DisableStop(uint32_t bkpt_code); |
239 inline void IncreaseStopCounter(uint32_t bkpt_code); | 239 inline void IncreaseStopCounter(uint32_t bkpt_code); |
240 void PrintStopInfo(uint32_t code); | 240 void PrintStopInfo(uint32_t code); |
241 | 241 |
242 // Read and write memory. | 242 // Read and write memory. |
243 inline uint8_t ReadBU(int32_t addr); | 243 inline uint8_t ReadBU(int32_t addr); |
244 inline int8_t ReadB(int32_t addr); | 244 inline int8_t ReadB(int32_t addr); |
245 inline void WriteB(int32_t addr, uint8_t value); | 245 inline void WriteB(int32_t addr, uint8_t value); |
246 inline void WriteB(int32_t addr, int8_t value); | 246 inline void WriteB(int32_t addr, int8_t value); |
247 | 247 |
248 inline uint16_t ReadHU(int32_t addr, Instr* instr); | 248 inline uint16_t ReadHU(int32_t addr, Instruction* instr); |
249 inline int16_t ReadH(int32_t addr, Instr* instr); | 249 inline int16_t ReadH(int32_t addr, Instruction* instr); |
250 // Note: Overloaded on the sign of the value. | 250 // Note: Overloaded on the sign of the value. |
251 inline void WriteH(int32_t addr, uint16_t value, Instr* instr); | 251 inline void WriteH(int32_t addr, uint16_t value, Instruction* instr); |
252 inline void WriteH(int32_t addr, int16_t value, Instr* instr); | 252 inline void WriteH(int32_t addr, int16_t value, Instruction* instr); |
253 | 253 |
254 inline int ReadW(int32_t addr, Instr* instr); | 254 inline int ReadW(int32_t addr, Instruction* instr); |
255 inline void WriteW(int32_t addr, int value, Instr* instr); | 255 inline void WriteW(int32_t addr, int value, Instruction* instr); |
256 | 256 |
257 int32_t* ReadDW(int32_t addr); | 257 int32_t* ReadDW(int32_t addr); |
258 void WriteDW(int32_t addr, int32_t value1, int32_t value2); | 258 void WriteDW(int32_t addr, int32_t value1, int32_t value2); |
259 | 259 |
260 // Executing is handled based on the instruction type. | 260 // Executing is handled based on the instruction type. |
261 void DecodeType01(Instr* instr); // both type 0 and type 1 rolled into one | 261 // Both type 0 and type 1 rolled into one. |
262 void DecodeType2(Instr* instr); | 262 void DecodeType01(Instruction* instr); |
263 void DecodeType3(Instr* instr); | 263 void DecodeType2(Instruction* instr); |
264 void DecodeType4(Instr* instr); | 264 void DecodeType3(Instruction* instr); |
265 void DecodeType5(Instr* instr); | 265 void DecodeType4(Instruction* instr); |
266 void DecodeType6(Instr* instr); | 266 void DecodeType5(Instruction* instr); |
267 void DecodeType7(Instr* instr); | 267 void DecodeType6(Instruction* instr); |
| 268 void DecodeType7(Instruction* instr); |
268 | 269 |
269 // Support for VFP. | 270 // Support for VFP. |
270 void DecodeTypeVFP(Instr* instr); | 271 void DecodeTypeVFP(Instruction* instr); |
271 void DecodeType6CoprocessorIns(Instr* instr); | 272 void DecodeType6CoprocessorIns(Instruction* instr); |
272 | 273 |
273 void DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(Instr* instr); | 274 void DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(Instruction* instr); |
274 void DecodeVCMP(Instr* instr); | 275 void DecodeVCMP(Instruction* instr); |
275 void DecodeVCVTBetweenDoubleAndSingle(Instr* instr); | 276 void DecodeVCVTBetweenDoubleAndSingle(Instruction* instr); |
276 void DecodeVCVTBetweenFloatingPointAndInteger(Instr* instr); | 277 void DecodeVCVTBetweenFloatingPointAndInteger(Instruction* instr); |
277 | 278 |
278 // Executes one instruction. | 279 // Executes one instruction. |
279 void InstructionDecode(Instr* instr); | 280 void InstructionDecode(Instruction* instr); |
280 | 281 |
281 // ICache. | 282 // ICache. |
282 static void CheckICache(Instr* instr); | 283 static void CheckICache(Instruction* instr); |
283 static void FlushOnePage(intptr_t start, int size); | 284 static void FlushOnePage(intptr_t start, int size); |
284 static CachePage* GetCachePage(void* page); | 285 static CachePage* GetCachePage(void* page); |
285 | 286 |
286 // Runtime call support. | 287 // Runtime call support. |
287 static void* RedirectExternalReference(void* external_function, | 288 static void* RedirectExternalReference(void* external_function, |
288 bool fp_return); | 289 bool fp_return); |
289 | 290 |
290 // For use in calls that take two double values, constructed from r0, r1, r2 | 291 // For use in calls that take two double values, constructed from r0, r1, r2 |
291 // and r3. | 292 // and r3. |
292 void GetFpArgs(double* x, double* y); | 293 void GetFpArgs(double* x, double* y); |
(...skipping 30 matching lines...) Expand all Loading... |
323 // Simulator support. | 324 // Simulator support. |
324 char* stack_; | 325 char* stack_; |
325 bool pc_modified_; | 326 bool pc_modified_; |
326 int icount_; | 327 int icount_; |
327 static bool initialized_; | 328 static bool initialized_; |
328 | 329 |
329 // Icache simulation | 330 // Icache simulation |
330 static v8::internal::HashMap* i_cache_; | 331 static v8::internal::HashMap* i_cache_; |
331 | 332 |
332 // Registered breakpoints. | 333 // Registered breakpoints. |
333 Instr* break_pc_; | 334 Instruction* break_pc_; |
334 instr_t break_instr_; | 335 Instr break_instr_; |
335 | 336 |
336 // A stop is watched if its code is less than kNumOfWatchedStops. | 337 // A stop is watched if its code is less than kNumOfWatchedStops. |
337 // Only watched stops support enabling/disabling and the counter feature. | 338 // Only watched stops support enabling/disabling and the counter feature. |
338 static const uint32_t kNumOfWatchedStops = 256; | 339 static const uint32_t kNumOfWatchedStops = 256; |
339 | 340 |
340 // Breakpoint is disabled if bit 31 is set. | 341 // Breakpoint is disabled if bit 31 is set. |
341 static const uint32_t kStopDisabledBit = 1 << 31; | 342 static const uint32_t kStopDisabledBit = 1 << 31; |
342 | 343 |
343 // A stop is enabled, meaning the simulator will stop when meeting the | 344 // A stop is enabled, meaning the simulator will stop when meeting the |
344 // instruction, if bit 31 of watched_stops[code].count is unset. | 345 // instruction, if bit 31 of watched_stops[code].count is unset. |
345 // The value watched_stops[code].count & ~(1 << 31) indicates how many times | 346 // The value watched_stops[code].count & ~(1 << 31) indicates how many times |
346 // the breakpoint was hit or gone through. | 347 // the breakpoint was hit or gone through. |
347 struct StopCoundAndDesc { | 348 struct StopCountAndDesc { |
348 uint32_t count; | 349 uint32_t count; |
349 char* desc; | 350 char* desc; |
350 }; | 351 }; |
351 StopCoundAndDesc watched_stops[kNumOfWatchedStops]; | 352 StopCountAndDesc watched_stops[kNumOfWatchedStops]; |
352 }; | 353 }; |
353 | 354 |
354 } } // namespace assembler::arm | |
355 | |
356 | |
357 namespace v8 { | |
358 namespace internal { | |
359 | 355 |
360 // When running with the simulator transition into simulated execution at this | 356 // When running with the simulator transition into simulated execution at this |
361 // point. | 357 // point. |
362 #define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4) \ | 358 #define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4) \ |
363 reinterpret_cast<Object*>(assembler::arm::Simulator::current()->Call( \ | 359 reinterpret_cast<Object*>(Simulator::current()->Call( \ |
364 FUNCTION_ADDR(entry), 5, p0, p1, p2, p3, p4)) | 360 FUNCTION_ADDR(entry), 5, p0, p1, p2, p3, p4)) |
365 | 361 |
366 #define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6) \ | 362 #define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6) \ |
367 assembler::arm::Simulator::current()->Call( \ | 363 Simulator::current()->Call( \ |
368 FUNCTION_ADDR(entry), 7, p0, p1, p2, p3, p4, p5, p6) | 364 FUNCTION_ADDR(entry), 7, p0, p1, p2, p3, p4, p5, p6) |
369 | 365 |
370 #define TRY_CATCH_FROM_ADDRESS(try_catch_address) \ | 366 #define TRY_CATCH_FROM_ADDRESS(try_catch_address) \ |
371 try_catch_address == \ | 367 try_catch_address == \ |
372 NULL ? NULL : *(reinterpret_cast<TryCatch**>(try_catch_address)) | 368 NULL ? NULL : *(reinterpret_cast<TryCatch**>(try_catch_address)) |
373 | 369 |
374 | 370 |
375 // The simulator has its own stack. Thus it has a different stack limit from | 371 // The simulator has its own stack. Thus it has a different stack limit from |
376 // the C-based native code. Setting the c_limit to indicate a very small | 372 // the C-based native code. Setting the c_limit to indicate a very small |
377 // stack cause stack overflow errors, since the simulator ignores the input. | 373 // stack cause stack overflow errors, since the simulator ignores the input. |
378 // This is unlikely to be an issue in practice, though it might cause testing | 374 // This is unlikely to be an issue in practice, though it might cause testing |
379 // trouble down the line. | 375 // trouble down the line. |
380 class SimulatorStack : public v8::internal::AllStatic { | 376 class SimulatorStack : public v8::internal::AllStatic { |
381 public: | 377 public: |
382 static inline uintptr_t JsLimitFromCLimit(uintptr_t c_limit) { | 378 static inline uintptr_t JsLimitFromCLimit(uintptr_t c_limit) { |
383 return assembler::arm::Simulator::current()->StackLimit(); | 379 return Simulator::current()->StackLimit(); |
384 } | 380 } |
385 | 381 |
386 static inline uintptr_t RegisterCTryCatch(uintptr_t try_catch_address) { | 382 static inline uintptr_t RegisterCTryCatch(uintptr_t try_catch_address) { |
387 assembler::arm::Simulator* sim = assembler::arm::Simulator::current(); | 383 Simulator* sim = Simulator::current(); |
388 return sim->PushAddress(try_catch_address); | 384 return sim->PushAddress(try_catch_address); |
389 } | 385 } |
390 | 386 |
391 static inline void UnregisterCTryCatch() { | 387 static inline void UnregisterCTryCatch() { |
392 assembler::arm::Simulator::current()->PopAddress(); | 388 Simulator::current()->PopAddress(); |
393 } | 389 } |
394 }; | 390 }; |
395 | 391 |
396 } } // namespace v8::internal | 392 } } // namespace v8::internal |
397 | 393 |
398 #endif // !defined(USE_SIMULATOR) | 394 #endif // !defined(USE_SIMULATOR) |
399 #endif // V8_ARM_SIMULATOR_ARM_H_ | 395 #endif // V8_ARM_SIMULATOR_ARM_H_ |
OLD | NEW |