12 #ifndef V8_ARM_SIMULATOR_ARM_H_ 13 #define V8_ARM_SIMULATOR_ARM_H_ 15 #include "src/allocation.h" 16 #include "src/base/lazy-instance.h" 17 #include "src/base/platform/mutex.h" 18 #include "src/boxed-float.h" 20 #if defined(USE_SIMULATOR) 23 #include "src/arm/constants-arm.h" 24 #include "src/assembler.h" 25 #include "src/base/hashmap.h" 26 #include "src/simulator-base.h" 33 static const int LINE_VALID = 0;
34 static const int LINE_INVALID = 1;
36 static const int kPageShift = 12;
37 static const int kPageSize = 1 << kPageShift;
38 static const int kPageMask = kPageSize - 1;
39 static const int kLineShift = 2;
40 static const int kLineLength = 1 << kLineShift;
41 static const int kLineMask = kLineLength - 1;
44 memset(&validity_map_, LINE_INVALID,
sizeof(validity_map_));
47 char* ValidityByte(
int offset) {
48 return &validity_map_[offset >> kLineShift];
51 char* CachedData(
int offset) {
52 return &data_[offset];
56 char data_[kPageSize];
57 static const int kValidityMapSize = kPageSize >> kLineShift;
58 char validity_map_[kValidityMapSize];
61 class Simulator :
public SimulatorBase {
63 friend class ArmDebugger;
66 r0 = 0, r1, r2, r3, r4, r5, r6, r7,
67 r8, r9, r10, r11, r12, r13, r14, r15,
72 s0 = 0, s1, s2, s3, s4, s5, s6, s7,
73 s8, s9, s10, s11, s12, s13, s14, s15,
74 s16, s17, s18, s19, s20, s21, s22, s23,
75 s24, s25, s26, s27, s28, s29, s30, s31,
77 d0 = 0, d1, d2, d3, d4, d5, d6, d7,
78 d8, d9, d10, d11, d12, d13, d14, d15,
79 d16, d17, d18, d19, d20, d21, d22, d23,
80 d24, d25, d26, d27, d28, d29, d30, d31,
82 q0 = 0, q1, q2, q3, q4, q5, q6, q7,
83 q8, q9, q10, q11, q12, q13, q14, q15,
87 explicit Simulator(Isolate* isolate);
97 void set_register(
int reg, int32_t value);
98 int32_t get_register(
int reg)
const;
99 double get_double_from_register_pair(
int reg);
100 void set_register_pair_from_double(
int reg,
double* value);
101 void set_dw_register(
int dreg,
const int* dbl);
104 void get_d_register(
int dreg, uint64_t* value);
105 void set_d_register(
int dreg,
const uint64_t* value);
106 void get_d_register(
int dreg,
uint32_t* value);
107 void set_d_register(
int dreg,
const uint32_t* value);
109 template <
typename T,
int SIZE = kSimd128Size>
110 void get_neon_register(
int reg, T (&value)[SIZE /
sizeof(T)]);
111 template <
typename T,
int SIZE = kSimd128Size>
112 void set_neon_register(
int reg,
const T (&value)[SIZE /
sizeof(T)]);
114 void set_s_register(
int reg,
unsigned int value);
115 unsigned int get_s_register(
int reg)
const;
117 void set_d_register_from_double(
int dreg,
const Float64 dbl) {
118 SetVFPRegister<Float64, 2>(dreg, dbl);
120 void set_d_register_from_double(
int dreg,
const double dbl) {
121 SetVFPRegister<double, 2>(dreg, dbl);
124 Float64 get_double_from_d_register(
int dreg) {
125 return GetFromVFPRegister<Float64, 2>(dreg);
128 void set_s_register_from_float(
int sreg,
const Float32 flt) {
129 SetVFPRegister<Float32, 1>(sreg, flt);
131 void set_s_register_from_float(
int sreg,
const float flt) {
132 SetVFPRegister<float, 1>(sreg, flt);
135 Float32 get_float_from_s_register(
int sreg) {
136 return GetFromVFPRegister<Float32, 1>(sreg);
139 void set_s_register_from_sinteger(
int sreg,
const int sint) {
140 SetVFPRegister<int, 1>(sreg, sint);
143 int get_sinteger_from_s_register(
int sreg) {
144 return GetFromVFPRegister<int, 1>(sreg);
148 void set_pc(int32_t value);
149 int32_t get_pc()
const;
151 Address get_sp()
const {
return static_cast<Address
>(get_register(sp)); }
159 template <
typename Return,
typename... Args>
160 Return Call(Address entry, Args... args) {
161 return VariadicCall<Return>(
this, &Simulator::CallImpl, entry, args...);
165 template <
typename Return>
166 Return CallFP(Address entry,
double d0,
double d1) {
167 return ConvertReturn<Return>(CallFPImpl(entry, d0, d1));
177 void set_last_debugger_input(
char* input);
178 char* last_debugger_input() {
return last_debugger_input_; }
181 static void SetRedirectInstruction(Instruction* instruction);
184 static bool ICacheMatch(
void* one,
void* two);
185 static void FlushICache(base::CustomMatcherHashMap* i_cache,
void* start,
190 bool has_bad_pc()
const;
193 bool use_eabi_hardfloat() {
194 #if USE_EABI_HARDFLOAT 202 enum special_values {
213 V8_EXPORT_PRIVATE intptr_t CallImpl(Address entry,
int argument_count,
214 const intptr_t* arguments);
215 intptr_t CallFPImpl(Address entry,
double d0,
double d1);
218 void Format(Instruction* instr,
const char* format);
222 inline bool ConditionallyExecute(Instruction* instr);
225 void SetNZFlags(int32_t val);
226 void SetCFlag(
bool val);
227 void SetVFlag(
bool val);
228 bool CarryFrom(int32_t left, int32_t right, int32_t carry = 0);
229 bool BorrowFrom(int32_t left, int32_t right, int32_t carry = 1);
230 bool OverflowFrom(int32_t alu_out,
235 inline int GetCarry() {
236 return c_flag_ ? 1 : 0;
240 void Compute_FPSCR_Flags(
float val1,
float val2);
241 void Compute_FPSCR_Flags(
double val1,
double val2);
242 void Copy_FPSCR_to_APSR();
243 inline float canonicalizeNaN(
float value);
244 inline double canonicalizeNaN(
double value);
245 inline Float32 canonicalizeNaN(Float32 value);
246 inline Float64 canonicalizeNaN(Float64 value);
249 int32_t GetShiftRm(Instruction* instr,
bool* carry_out);
250 int32_t GetImm(Instruction* instr,
bool* carry_out);
251 int32_t ProcessPU(Instruction* instr,
254 intptr_t* start_address,
255 intptr_t* end_address);
256 void HandleRList(Instruction* instr,
bool load);
257 void HandleVList(Instruction* inst);
258 void SoftwareInterrupt(Instruction* instr);
261 inline bool isStopInstruction(Instruction* instr);
262 inline bool isWatchedStop(
uint32_t bkpt_code);
263 inline bool isEnabledStop(
uint32_t bkpt_code);
264 inline void EnableStop(
uint32_t bkpt_code);
265 inline void DisableStop(
uint32_t bkpt_code);
266 inline void IncreaseStopCounter(
uint32_t bkpt_code);
272 inline uint8_t ReadBU(int32_t addr);
273 inline int8_t ReadB(int32_t addr);
274 uint8_t ReadExBU(int32_t addr);
275 inline void WriteB(int32_t addr, uint8_t value);
276 inline void WriteB(int32_t addr, int8_t value);
277 int WriteExB(int32_t addr, uint8_t value);
279 inline uint16_t ReadHU(int32_t addr);
280 inline int16_t ReadH(int32_t addr);
281 uint16_t ReadExHU(int32_t addr);
283 inline void WriteH(int32_t addr, uint16_t value);
284 inline void WriteH(int32_t addr, int16_t value);
285 int WriteExH(int32_t addr, uint16_t value);
287 inline int ReadW(int32_t addr);
288 int ReadExW(int32_t addr);
289 inline void WriteW(int32_t addr,
int value);
290 int WriteExW(int32_t addr,
int value);
292 int32_t* ReadDW(int32_t addr);
293 void WriteDW(int32_t addr, int32_t value1, int32_t value2);
294 int32_t* ReadExDW(int32_t addr);
295 int WriteExDW(int32_t addr, int32_t value1, int32_t value2);
299 void DecodeType01(Instruction* instr);
300 void DecodeType2(Instruction* instr);
301 void DecodeType3(Instruction* instr);
302 void DecodeType4(Instruction* instr);
303 void DecodeType5(Instruction* instr);
304 void DecodeType6(Instruction* instr);
305 void DecodeType7(Instruction* instr);
308 void DecodeTypeCP15(Instruction* instr);
311 void DecodeTypeVFP(Instruction* instr);
312 void DecodeType6CoprocessorIns(Instruction* instr);
313 void DecodeSpecialCondition(Instruction* instr);
315 void DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(Instruction* instr);
316 void DecodeVCMP(Instruction* instr);
317 void DecodeVCVTBetweenDoubleAndSingle(Instruction* instr);
318 int32_t ConvertDoubleToInt(
double val,
bool unsigned_integer,
319 VFPRoundingMode mode);
320 void DecodeVCVTBetweenFloatingPointAndInteger(Instruction* instr);
323 void InstructionDecode(Instruction* instr);
326 static void CheckICache(base::CustomMatcherHashMap* i_cache,
328 static void FlushOnePage(base::CustomMatcherHashMap* i_cache, intptr_t start,
330 static CachePage* GetCachePage(base::CustomMatcherHashMap* i_cache,
334 void GetFpArgs(
double* x,
double* y, int32_t* z);
335 void SetFpResult(
const double& result);
336 void TrashCallerSaveRegisters();
338 template<
class ReturnType,
int register_size>
339 ReturnType GetFromVFPRegister(
int reg_index);
341 template<
class InputType,
int register_size>
342 void SetVFPRegister(
int reg_index,
const InputType& value);
344 void SetSpecialRegister(SRegisterFieldMask reg_and_mask,
uint32_t value);
345 uint32_t GetFromSpecialRegister(SRegister reg);
347 void CallInternal(Address entry);
353 int32_t registers_[16];
360 unsigned int vfp_registers_[num_d_registers * 2];
367 VFPRoundingMode FPSCR_rounding_mode_;
368 bool FPSCR_default_NaN_mode_;
371 bool inv_op_vfp_flag_;
372 bool div_zero_vfp_flag_;
373 bool overflow_vfp_flag_;
374 bool underflow_vfp_flag_;
375 bool inexact_vfp_flag_;
383 char* last_debugger_input_;
386 Instruction* break_pc_;
393 static const uint32_t kNumOfWatchedStops = 256;
396 static const uint32_t kStopDisabledBit = 1 << 31;
402 struct StopCountAndDesc {
406 StopCountAndDesc watched_stops_[kNumOfWatchedStops];
409 enum class MonitorAccess {
414 enum class TransactionSize {
424 static const int32_t kExclusiveTaggedAddrMask = ~((1 << 11) - 1);
434 void NotifyLoad(int32_t addr);
435 void NotifyLoadExcl(int32_t addr, TransactionSize size);
436 void NotifyStore(int32_t addr);
437 bool NotifyStoreExcl(int32_t addr, TransactionSize size);
442 MonitorAccess access_state_;
443 int32_t tagged_addr_;
444 TransactionSize size_;
447 class GlobalMonitor {
456 friend class GlobalMonitor;
460 void NotifyLoadExcl_Locked(int32_t addr);
461 void NotifyStore_Locked(int32_t addr,
bool is_requesting_processor);
462 bool NotifyStoreExcl_Locked(int32_t addr,
bool is_requesting_processor);
464 MonitorAccess access_state_;
465 int32_t tagged_addr_;
472 static const int kMaxFailureCounter = 5;
473 int failure_counter_;
479 void NotifyLoadExcl_Locked(int32_t addr, Processor* processor);
480 void NotifyStore_Locked(int32_t addr, Processor* processor);
481 bool NotifyStoreExcl_Locked(int32_t addr, Processor* processor);
484 void RemoveProcessor(Processor* processor);
487 bool IsProcessorInLinkedList_Locked(Processor* processor)
const;
488 void PrependProcessor_Locked(Processor* processor);
493 LocalMonitor local_monitor_;
494 GlobalMonitor::Processor global_monitor_processor_;
495 static base::LazyInstance<GlobalMonitor>::type global_monitor_;
501 #endif // defined(USE_SIMULATOR) 502 #endif // V8_ARM_SIMULATOR_ARM_H_