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