1 // Copyright 2012 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Declares a Simulator for ARM instructions if we are not generating a native 6 // ARM binary. This Simulator allows us to run and debug ARM code generation on 7 // regular desktop machines. 8 // V8 calls into generated code by using the GeneratedCode class, 9 // which will start execution in the Simulator or forwards to the real entry 10 // on a ARM HW platform. 11 12 #ifndef V8_EXECUTION_ARM_SIMULATOR_ARM_H_ 13 #define V8_EXECUTION_ARM_SIMULATOR_ARM_H_ 14 15 // globals.h defines USE_SIMULATOR. 16 #include "src/common/globals.h" 17 18 #if defined(USE_SIMULATOR) 19 // Running with a simulator. 20 21 #include "src/base/hashmap.h" 22 #include "src/base/lazy-instance.h" 23 #include "src/base/platform/mutex.h" 24 #include "src/codegen/arm/constants-arm.h" 25 #include "src/execution/simulator-base.h" 26 #include "src/utils/allocation.h" 27 #include "src/utils/boxed-float.h" 28 29 namespace v8 { 30 namespace internal { 31 32 class CachePage { 33 public: 34 static const int LINE_VALID = 0; 35 static const int LINE_INVALID = 1; 36 37 static const int kPageShift = 12; 38 static const int kPageSize = 1 << kPageShift; 39 static const int kPageMask = kPageSize - 1; 40 static const int kLineShift = 2; // The cache line is only 4 bytes right now. 41 static const int kLineLength = 1 << kLineShift; 42 static const int kLineMask = kLineLength - 1; 43 CachePage()44 CachePage() { memset(&validity_map_, LINE_INVALID, sizeof(validity_map_)); } 45 ValidityByte(int offset)46 char* ValidityByte(int offset) { 47 return &validity_map_[offset >> kLineShift]; 48 } 49 CachedData(int offset)50 char* CachedData(int offset) { return &data_[offset]; } 51 52 private: 53 char data_[kPageSize]; // The cached data. 54 static const int kValidityMapSize = kPageSize >> kLineShift; 55 char validity_map_[kValidityMapSize]; // One byte per line. 56 }; 57 58 class Simulator : public SimulatorBase { 59 public: 60 friend class ArmDebugger; 61 enum Register { 62 no_reg = -1, 63 r0 = 0, 64 r1, 65 r2, 66 r3, 67 r4, 68 r5, 69 r6, 70 r7, 71 r8, 72 r9, 73 r10, 74 r11, 75 r12, 76 r13, 77 r14, 78 r15, 79 num_registers, 80 sp = 13, 81 lr = 14, 82 pc = 15, 83 s0 = 0, 84 s1, 85 s2, 86 s3, 87 s4, 88 s5, 89 s6, 90 s7, 91 s8, 92 s9, 93 s10, 94 s11, 95 s12, 96 s13, 97 s14, 98 s15, 99 s16, 100 s17, 101 s18, 102 s19, 103 s20, 104 s21, 105 s22, 106 s23, 107 s24, 108 s25, 109 s26, 110 s27, 111 s28, 112 s29, 113 s30, 114 s31, 115 num_s_registers = 32, 116 d0 = 0, 117 d1, 118 d2, 119 d3, 120 d4, 121 d5, 122 d6, 123 d7, 124 d8, 125 d9, 126 d10, 127 d11, 128 d12, 129 d13, 130 d14, 131 d15, 132 d16, 133 d17, 134 d18, 135 d19, 136 d20, 137 d21, 138 d22, 139 d23, 140 d24, 141 d25, 142 d26, 143 d27, 144 d28, 145 d29, 146 d30, 147 d31, 148 num_d_registers = 32, 149 q0 = 0, 150 q1, 151 q2, 152 q3, 153 q4, 154 q5, 155 q6, 156 q7, 157 q8, 158 q9, 159 q10, 160 q11, 161 q12, 162 q13, 163 q14, 164 q15, 165 num_q_registers = 16 166 }; 167 168 explicit Simulator(Isolate* isolate); 169 ~Simulator(); 170 171 // The currently executing Simulator instance. Potentially there can be one 172 // for each native thread. 173 V8_EXPORT_PRIVATE static Simulator* current(v8::internal::Isolate* isolate); 174 175 // Accessors for register state. Reading the pc value adheres to the ARM 176 // architecture specification and is off by a 8 from the currently executing 177 // instruction. 178 void set_register(int reg, int32_t value); 179 V8_EXPORT_PRIVATE int32_t get_register(int reg) const; 180 double get_double_from_register_pair(int reg); 181 void set_register_pair_from_double(int reg, double* value); 182 void set_dw_register(int dreg, const int* dbl); 183 184 // Support for VFP. 185 void get_d_register(int dreg, uint64_t* value); 186 void set_d_register(int dreg, const uint64_t* value); 187 void get_d_register(int dreg, uint32_t* value); 188 void set_d_register(int dreg, const uint32_t* value); 189 // Support for NEON. 190 template <typename T, int SIZE = kSimd128Size> 191 void get_neon_register(int reg, T (&value)[SIZE / sizeof(T)]); 192 template <typename T, int SIZE = kSimd128Size> 193 void set_neon_register(int reg, const T (&value)[SIZE / sizeof(T)]); 194 195 void set_s_register(int reg, unsigned int value); 196 unsigned int get_s_register(int reg) const; 197 set_d_register_from_double(int dreg,const Float64 dbl)198 void set_d_register_from_double(int dreg, const Float64 dbl) { 199 SetVFPRegister<Float64, 2>(dreg, dbl); 200 } set_d_register_from_double(int dreg,const double dbl)201 void set_d_register_from_double(int dreg, const double dbl) { 202 SetVFPRegister<double, 2>(dreg, dbl); 203 } 204 get_double_from_d_register(int dreg)205 Float64 get_double_from_d_register(int dreg) { 206 return GetFromVFPRegister<Float64, 2>(dreg); 207 } 208 set_s_register_from_float(int sreg,const Float32 flt)209 void set_s_register_from_float(int sreg, const Float32 flt) { 210 SetVFPRegister<Float32, 1>(sreg, flt); 211 } set_s_register_from_float(int sreg,const float flt)212 void set_s_register_from_float(int sreg, const float flt) { 213 SetVFPRegister<float, 1>(sreg, flt); 214 } 215 get_float_from_s_register(int sreg)216 Float32 get_float_from_s_register(int sreg) { 217 return GetFromVFPRegister<Float32, 1>(sreg); 218 } 219 set_s_register_from_sinteger(int sreg,const int sint)220 void set_s_register_from_sinteger(int sreg, const int sint) { 221 SetVFPRegister<int, 1>(sreg, sint); 222 } 223 get_sinteger_from_s_register(int sreg)224 int get_sinteger_from_s_register(int sreg) { 225 return GetFromVFPRegister<int, 1>(sreg); 226 } 227 228 // Special case of set_register and get_register to access the raw PC value. 229 void set_pc(int32_t value); 230 V8_EXPORT_PRIVATE int32_t get_pc() const; 231 get_sp()232 Address get_sp() const { return static_cast<Address>(get_register(sp)); } 233 234 // Accessor to the internal simulator stack area. 235 uintptr_t StackLimit(uintptr_t c_limit) const; 236 237 // Executes ARM instructions until the PC reaches end_sim_pc. 238 void Execute(); 239 240 template <typename Return, typename... Args> Call(Address entry,Args...args)241 Return Call(Address entry, Args... args) { 242 return VariadicCall<Return>(this, &Simulator::CallImpl, entry, args...); 243 } 244 245 // Alternative: call a 2-argument double function. 246 template <typename Return> CallFP(Address entry,double d0,double d1)247 Return CallFP(Address entry, double d0, double d1) { 248 return ConvertReturn<Return>(CallFPImpl(entry, d0, d1)); 249 } 250 251 // Push an address onto the JS stack. 252 uintptr_t PushAddress(uintptr_t address); 253 254 // Pop an address from the JS stack. 255 uintptr_t PopAddress(); 256 257 // Debugger input. 258 void set_last_debugger_input(char* input); last_debugger_input()259 char* last_debugger_input() { return last_debugger_input_; } 260 261 // Redirection support. 262 static void SetRedirectInstruction(Instruction* instruction); 263 264 // ICache checking. 265 static bool ICacheMatch(void* one, void* two); 266 static void FlushICache(base::CustomMatcherHashMap* i_cache, void* start, 267 size_t size); 268 269 // Returns true if pc register contains one of the 'special_values' defined 270 // below (bad_lr, end_sim_pc). 271 bool has_bad_pc() const; 272 273 // EABI variant for double arguments in use. use_eabi_hardfloat()274 bool use_eabi_hardfloat() { 275 #if USE_EABI_HARDFLOAT 276 return true; 277 #else 278 return false; 279 #endif 280 } 281 282 private: 283 enum special_values { 284 // Known bad pc value to ensure that the simulator does not execute 285 // without being properly setup. 286 bad_lr = -1, 287 // A pc value used to signal the simulator to stop execution. Generally 288 // the lr is set to this value on transition from native C code to 289 // simulated execution, so that the simulator can "return" to the native 290 // C code. 291 end_sim_pc = -2 292 }; 293 294 V8_EXPORT_PRIVATE intptr_t CallImpl(Address entry, int argument_count, 295 const intptr_t* arguments); 296 intptr_t CallFPImpl(Address entry, double d0, double d1); 297 298 // Unsupported instructions use Format to print an error and stop execution. 299 void Format(Instruction* instr, const char* format); 300 301 // Checks if the current instruction should be executed based on its 302 // condition bits. 303 inline bool ConditionallyExecute(Instruction* instr); 304 305 // Helper functions to set the conditional flags in the architecture state. 306 void SetNZFlags(int32_t val); 307 void SetCFlag(bool val); 308 void SetVFlag(bool val); 309 bool CarryFrom(int32_t left, int32_t right, int32_t carry = 0); 310 bool BorrowFrom(int32_t left, int32_t right, int32_t carry = 1); 311 bool OverflowFrom(int32_t alu_out, int32_t left, int32_t right, 312 bool addition); 313 GetCarry()314 inline int GetCarry() { return c_flag_ ? 1 : 0; } 315 316 // Support for VFP. 317 void Compute_FPSCR_Flags(float val1, float val2); 318 void Compute_FPSCR_Flags(double val1, double val2); 319 void Copy_FPSCR_to_APSR(); 320 inline float canonicalizeNaN(float value); 321 inline double canonicalizeNaN(double value); 322 inline Float32 canonicalizeNaN(Float32 value); 323 inline Float64 canonicalizeNaN(Float64 value); 324 325 // Helper functions to decode common "addressing" modes 326 int32_t GetShiftRm(Instruction* instr, bool* carry_out); 327 int32_t GetImm(Instruction* instr, bool* carry_out); 328 int32_t ProcessPU(Instruction* instr, int num_regs, int operand_size, 329 intptr_t* start_address, intptr_t* end_address); 330 void HandleRList(Instruction* instr, bool load); 331 void HandleVList(Instruction* inst); 332 void SoftwareInterrupt(Instruction* instr); 333 void DebugAtNextPC(); 334 335 // Stop helper functions. 336 inline bool isWatchedStop(uint32_t bkpt_code); 337 inline bool isEnabledStop(uint32_t bkpt_code); 338 inline void EnableStop(uint32_t bkpt_code); 339 inline void DisableStop(uint32_t bkpt_code); 340 inline void IncreaseStopCounter(uint32_t bkpt_code); 341 void PrintStopInfo(uint32_t code); 342 343 // Read and write memory. 344 // The *Ex functions are exclusive access. The writes return the strex status: 345 // 0 if the write succeeds, and 1 if the write fails. 346 inline uint8_t ReadBU(int32_t addr); 347 inline int8_t ReadB(int32_t addr); 348 uint8_t ReadExBU(int32_t addr); 349 inline void WriteB(int32_t addr, uint8_t value); 350 inline void WriteB(int32_t addr, int8_t value); 351 int WriteExB(int32_t addr, uint8_t value); 352 353 inline uint16_t ReadHU(int32_t addr); 354 inline int16_t ReadH(int32_t addr); 355 uint16_t ReadExHU(int32_t addr); 356 // Note: Overloaded on the sign of the value. 357 inline void WriteH(int32_t addr, uint16_t value); 358 inline void WriteH(int32_t addr, int16_t value); 359 int WriteExH(int32_t addr, uint16_t value); 360 361 inline int ReadW(int32_t addr); 362 int ReadExW(int32_t addr); 363 inline void WriteW(int32_t addr, int value); 364 int WriteExW(int32_t addr, int value); 365 366 int32_t* ReadDW(int32_t addr); 367 void WriteDW(int32_t addr, int32_t value1, int32_t value2); 368 int32_t* ReadExDW(int32_t addr); 369 int WriteExDW(int32_t addr, int32_t value1, int32_t value2); 370 371 // Executing is handled based on the instruction type. 372 // Both type 0 and type 1 rolled into one. 373 void DecodeType01(Instruction* instr); 374 void DecodeType2(Instruction* instr); 375 void DecodeType3(Instruction* instr); 376 void DecodeType4(Instruction* instr); 377 void DecodeType5(Instruction* instr); 378 void DecodeType6(Instruction* instr); 379 void DecodeType7(Instruction* instr); 380 381 // CP15 coprocessor instructions. 382 void DecodeTypeCP15(Instruction* instr); 383 384 // Support for VFP. 385 void DecodeTypeVFP(Instruction* instr); 386 void DecodeType6CoprocessorIns(Instruction* instr); 387 void DecodeSpecialCondition(Instruction* instr); 388 389 void DecodeFloatingPointDataProcessing(Instruction* instr); 390 void DecodeUnconditional(Instruction* instr); 391 void DecodeAdvancedSIMDDataProcessing(Instruction* instr); 392 void DecodeMemoryHintsAndBarriers(Instruction* instr); 393 void DecodeAdvancedSIMDElementOrStructureLoadStore(Instruction* instr); 394 void DecodeAdvancedSIMDTwoOrThreeRegisters(Instruction* instr); 395 396 void DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(Instruction* instr); 397 void DecodeVCMP(Instruction* instr); 398 void DecodeVCVTBetweenDoubleAndSingle(Instruction* instr); 399 int32_t ConvertDoubleToInt(double val, bool unsigned_integer, 400 VFPRoundingMode mode); 401 void DecodeVCVTBetweenFloatingPointAndInteger(Instruction* instr); 402 403 // Executes one instruction. 404 void InstructionDecode(Instruction* instr); 405 406 // ICache. 407 static void CheckICache(base::CustomMatcherHashMap* i_cache, 408 Instruction* instr); 409 static void FlushOnePage(base::CustomMatcherHashMap* i_cache, intptr_t start, 410 int size); 411 static CachePage* GetCachePage(base::CustomMatcherHashMap* i_cache, 412 void* page); 413 414 // Handle arguments and return value for runtime FP functions. 415 void GetFpArgs(double* x, double* y, int32_t* z); 416 void SetFpResult(const double& result); 417 void TrashCallerSaveRegisters(); 418 419 template <class ReturnType, int register_size> 420 ReturnType GetFromVFPRegister(int reg_index); 421 422 template <class InputType, int register_size> 423 void SetVFPRegister(int reg_index, const InputType& value); 424 425 void SetSpecialRegister(SRegisterFieldMask reg_and_mask, uint32_t value); 426 uint32_t GetFromSpecialRegister(SRegister reg); 427 428 void CallInternal(Address entry); 429 430 // Architecture state. 431 // Saturating instructions require a Q flag to indicate saturation. 432 // There is currently no way to read the CPSR directly, and thus read the Q 433 // flag, so this is left unimplemented. 434 int32_t registers_[16]; 435 bool n_flag_; 436 bool z_flag_; 437 bool c_flag_; 438 bool v_flag_; 439 440 // VFP architecture state. 441 unsigned int vfp_registers_[num_d_registers * 2]; 442 bool n_flag_FPSCR_; 443 bool z_flag_FPSCR_; 444 bool c_flag_FPSCR_; 445 bool v_flag_FPSCR_; 446 447 // VFP rounding mode. See ARM DDI 0406B Page A2-29. 448 VFPRoundingMode FPSCR_rounding_mode_; 449 bool FPSCR_default_NaN_mode_; 450 451 // VFP FP exception flags architecture state. 452 bool inv_op_vfp_flag_; 453 bool div_zero_vfp_flag_; 454 bool overflow_vfp_flag_; 455 bool underflow_vfp_flag_; 456 bool inexact_vfp_flag_; 457 458 // Simulator support. 459 char* stack_; 460 bool pc_modified_; 461 int icount_; 462 463 // Debugger input. 464 char* last_debugger_input_; 465 466 // Registered breakpoints. 467 Instruction* break_pc_; 468 Instr break_instr_; 469 470 v8::internal::Isolate* isolate_; 471 472 // A stop is watched if its code is less than kNumOfWatchedStops. 473 // Only watched stops support enabling/disabling and the counter feature. 474 static const uint32_t kNumOfWatchedStops = 256; 475 476 // Breakpoint is disabled if bit 31 is set. 477 static const uint32_t kStopDisabledBit = 1 << 31; 478 479 // A stop is enabled, meaning the simulator will stop when meeting the 480 // instruction, if bit 31 of watched_stops_[code].count is unset. 481 // The value watched_stops_[code].count & ~(1 << 31) indicates how many times 482 // the breakpoint was hit or gone through. 483 struct StopCountAndDesc { 484 uint32_t count; 485 char* desc; 486 }; 487 StopCountAndDesc watched_stops_[kNumOfWatchedStops]; 488 489 // Synchronization primitives. See ARM DDI 0406C.b, A2.9. 490 enum class MonitorAccess { 491 Open, 492 Exclusive, 493 }; 494 495 enum class TransactionSize { 496 None = 0, 497 Byte = 1, 498 HalfWord = 2, 499 Word = 4, 500 DoubleWord = 8, 501 }; 502 503 // The least-significant bits of the address are ignored. The number of bits 504 // is implementation-defined, between 3 and 11. See ARM DDI 0406C.b, A3.4.3. 505 static const int32_t kExclusiveTaggedAddrMask = ~((1 << 11) - 1); 506 507 class LocalMonitor { 508 public: 509 LocalMonitor(); 510 511 // These functions manage the state machine for the local monitor, but do 512 // not actually perform loads and stores. NotifyStoreExcl only returns 513 // true if the exclusive store is allowed; the global monitor will still 514 // have to be checked to see whether the memory should be updated. 515 void NotifyLoad(int32_t addr); 516 void NotifyLoadExcl(int32_t addr, TransactionSize size); 517 void NotifyStore(int32_t addr); 518 bool NotifyStoreExcl(int32_t addr, TransactionSize size); 519 520 private: 521 void Clear(); 522 523 MonitorAccess access_state_; 524 int32_t tagged_addr_; 525 TransactionSize size_; 526 }; 527 528 class GlobalMonitor { 529 public: 530 class Processor { 531 public: 532 Processor(); 533 534 private: 535 friend class GlobalMonitor; 536 // These functions manage the state machine for the global monitor, but do 537 // not actually perform loads and stores. 538 void Clear_Locked(); 539 void NotifyLoadExcl_Locked(int32_t addr); 540 void NotifyStore_Locked(int32_t addr, bool is_requesting_processor); 541 bool NotifyStoreExcl_Locked(int32_t addr, bool is_requesting_processor); 542 543 MonitorAccess access_state_; 544 int32_t tagged_addr_; 545 Processor* next_; 546 Processor* prev_; 547 // A strex can fail due to background cache evictions. Rather than 548 // simulating this, we'll just occasionally introduce cases where an 549 // exclusive store fails. This will happen once after every 550 // kMaxFailureCounter exclusive stores. 551 static const int kMaxFailureCounter = 5; 552 int failure_counter_; 553 }; 554 555 // Exposed so it can be accessed by Simulator::{Read,Write}Ex*. 556 base::Mutex mutex; 557 558 void NotifyLoadExcl_Locked(int32_t addr, Processor* processor); 559 void NotifyStore_Locked(int32_t addr, Processor* processor); 560 bool NotifyStoreExcl_Locked(int32_t addr, Processor* processor); 561 562 // Called when the simulator is destroyed. 563 void RemoveProcessor(Processor* processor); 564 565 static GlobalMonitor* Get(); 566 567 private: 568 // Private constructor. Call {GlobalMonitor::Get()} to get the singleton. 569 GlobalMonitor() = default; 570 friend class base::LeakyObject<GlobalMonitor>; 571 572 bool IsProcessorInLinkedList_Locked(Processor* processor) const; 573 void PrependProcessor_Locked(Processor* processor); 574 575 Processor* head_ = nullptr; 576 }; 577 578 LocalMonitor local_monitor_; 579 GlobalMonitor::Processor global_monitor_processor_; 580 }; 581 582 } // namespace internal 583 } // namespace v8 584 585 #endif // defined(USE_SIMULATOR) 586 #endif // V8_EXECUTION_ARM_SIMULATOR_ARM_H_ 587