5 #ifndef V8_ARM64_SIMULATOR_ARM64_H_
6 #define V8_ARM64_SIMULATOR_ARM64_H_
22 #define REGISTER_CODE_LIST(R) \
23 R(0) R(1) R(2) R(3) R(4) R(5) R(6) R(7) \
24 R(8) R(9) R(10) R(11) R(12) R(13) R(14) R(15) \
25 R(16) R(17) R(18) R(19) R(20) R(21) R(22) R(23) \
26 R(24) R(25) R(26) R(27) R(28) R(29) R(30) R(31)
31 #if !defined(USE_SIMULATOR)
35 #define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4) \
36 (entry(p0, p1, p2, p3, p4))
40 const byte* input_start,
41 const byte* input_end,
53 #define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7, p8) \
54 (FUNCTION_CAST<arm64_regexp_matcher>(entry)( \
55 p0, p1, p2, p3, p4, p5, p6, p7, NULL, p8))
67 return try_catch_address;
75 enum ReverseByteMode {
85 class SimSystemRegister {
89 SimSystemRegister() : value_(0), write_ignore_mask_(0xffffffff) { }
95 void SetRawValue(
uint32_t new_value) {
96 value_ = (value_ & write_ignore_mask_) | (new_value & ~write_ignore_mask_);
99 uint32_t Bits(
int msb,
int lsb)
const {
103 int32_t SignedBits(
int msb,
int lsb)
const {
107 void SetBits(
int msb,
int lsb,
uint32_t bits);
112 #define DEFINE_GETTER(Name, HighBit, LowBit, Func, Type) \
113 Type Name() const { return static_cast<Type>(Func(HighBit, LowBit)); } \
114 void Set##Name(Type bits) { \
115 SetBits(HighBit, LowBit, static_cast<Type>(bits)); \
117 #define DEFINE_WRITE_IGNORE_MASK(Name, Mask) \
118 static const uint32_t Name##WriteIgnoreMask = ~static_cast<uint32_t>(Mask);
120 #undef DEFINE_ZERO_BITS
128 : value_(value), write_ignore_mask_(write_ignore_mask) { }
136 class SimRegisterBase {
139 void Set(
T new_value) {
141 memcpy(&value_, &new_value,
sizeof(
T));
147 memcpy(&result, &value_,
sizeof(
T));
156 typedef SimRegisterBase SimRegister;
157 typedef SimRegisterBase SimFPRegister;
160 class Simulator :
public DecoderVisitor {
162 explicit Simulator(Decoder<DispatchingDecoderVisitor>* decoder,
163 Isolate* isolate =
NULL,
164 FILE* stream = stderr);
170 static void Initialize(Isolate* isolate);
179 void CallVoid(
byte* entry, CallArgument* args);
182 int64_t CallInt64(
byte* entry, CallArgument* args);
183 double CallDouble(
byte* entry, CallArgument* args);
188 int64_t CallJS(
byte* entry,
189 byte* function_entry,
194 int64_t CallRegExp(
byte* entry,
196 int64_t start_offset,
197 const byte* input_start,
198 const byte* input_end,
203 void* return_address,
213 explicit CallArgument(
T argument) {
215 DCHECK(
sizeof(argument) <=
sizeof(bits_));
216 memcpy(&bits_, &argument,
sizeof(argument));
220 explicit CallArgument(
double argument) {
221 DCHECK(
sizeof(argument) ==
sizeof(bits_));
222 memcpy(&bits_, &argument,
sizeof(argument));
226 explicit CallArgument(
float argument) {
232 DCHECK(
sizeof(kFP64SignallingNaN) ==
sizeof(bits_));
233 memcpy(&bits_, &kFP64SignallingNaN,
sizeof(kFP64SignallingNaN));
235 DCHECK(
sizeof(argument) <=
sizeof(bits_));
236 memcpy(&bits_, &argument,
sizeof(argument));
242 static CallArgument End() {
return CallArgument(); }
244 int64_t bits()
const {
return bits_; }
245 bool IsEnd()
const {
return type_ == NO_ARG; }
246 bool IsX()
const {
return type_ == X_ARG; }
247 bool IsD()
const {
return type_ == D_ARG; }
250 enum CallArgumentType { X_ARG, D_ARG, NO_ARG };
255 CallArgumentType type_;
257 CallArgument() { type_ = NO_ARG; }
264 bool GetValue(
const char* desc, int64_t* value);
266 bool PrintValue(
const char* desc);
280 static void* RedirectExternalReference(
void* external_function,
282 void DoRuntimeCall(Instruction* instr);
285 static const Instruction* kEndOfSimAddress;
286 void DecodeInstruction();
288 void RunFrom(Instruction* start);
291 template <
typename T>
292 void set_pc(
T new_pc) {
293 DCHECK(
sizeof(
T) ==
sizeof(pc_));
294 memcpy(&pc_, &new_pc,
sizeof(
T));
297 Instruction*
pc() {
return pc_; }
299 void increment_pc() {
301 pc_ = pc_->following();
304 pc_modified_ =
false;
307 virtual void Decode(Instruction* instr) {
308 decoder_->Decode(instr);
311 void ExecuteInstruction() {
320 #define DECLARE(A) void Visit##A(Instruction* instr);
324 bool IsZeroRegister(
unsigned code,
Reg31Mode r31mode)
const {
335 if (IsZeroRegister(code, r31mode)) {
338 return registers_[code].Get<
T>();
343 return reg<int32_t>(code, r31mode);
347 return reg<int64_t>(code, r31mode);
353 void set_reg(
unsigned code,
T value,
355 set_reg_no_log(code, value, r31mode);
356 LogRegister(code, r31mode);
360 void set_wreg(
unsigned code,
int32_t value,
362 set_reg(code, value, r31mode);
365 void set_xreg(
unsigned code, int64_t value,
367 set_reg(code, value, r31mode);
371 template <
typename T>
372 void set_reg_no_log(
unsigned code,
T value,
375 if (!IsZeroRegister(code, r31mode)) {
376 registers_[code].Set(value);
380 void set_wreg_no_log(
unsigned code,
int32_t value,
382 set_reg_no_log(code, value, r31mode);
385 void set_xreg_no_log(
unsigned code, int64_t value,
387 set_reg_no_log(code, value, r31mode);
392 void set_lr(
T value) {
398 void set_sp(
T value) {
413 T fpreg(
unsigned code)
const {
415 return fpregisters_[code].Get<
T>();
419 float sreg(
unsigned code)
const {
420 return fpreg<float>(code);
423 uint32_t sreg_bits(
unsigned code)
const {
424 return fpreg<uint32_t>(code);
427 double dreg(
unsigned code)
const {
428 return fpreg<double>(code);
431 uint64_t dreg_bits(
unsigned code)
const {
432 return fpreg<uint64_t>(code);
435 double fpreg(
unsigned size,
unsigned code)
const {
448 void set_fpreg(
unsigned code,
T value) {
449 set_fpreg_no_log(code, value);
452 LogFPRegister(code, kPrintSRegValue);
454 LogFPRegister(code, kPrintDRegValue);
459 void set_sreg(
unsigned code,
float value) {
460 set_fpreg(code, value);
463 void set_sreg_bits(
unsigned code,
uint32_t value) {
464 set_fpreg(code, value);
467 void set_dreg(
unsigned code,
double value) {
468 set_fpreg(code, value);
471 void set_dreg_bits(
unsigned code, uint64_t value) {
472 set_fpreg(code, value);
476 template <
typename T>
477 void set_fpreg_no_log(
unsigned code,
T value) {
480 fpregisters_[code].Set(value);
483 void set_sreg_no_log(
unsigned code,
float value) {
484 set_fpreg_no_log(code, value);
487 void set_dreg_no_log(
unsigned code,
double value) {
488 set_fpreg_no_log(code, value);
491 SimSystemRegister& nzcv() {
return nzcv_; }
492 SimSystemRegister& fpcr() {
return fpcr_; }
498 Instruction* location;
501 std::vector<Breakpoint> breakpoints_;
502 void SetBreakpoint(Instruction* breakpoint);
503 void ListBreakpoints();
504 void CheckBreakpoints();
512 void CheckBreakNext();
515 void PrintInstructionsAt(Instruction*
pc, uint64_t count);
518 void PrintRegisters();
519 void PrintFPRegisters();
520 void PrintSystemRegisters();
523 void LogSystemRegisters() {
524 if (log_parameters() &
LOG_SYS_REGS) PrintSystemRegisters();
526 void LogRegisters() {
527 if (log_parameters() &
LOG_REGS) PrintRegisters();
529 void LogFPRegisters() {
530 if (log_parameters() &
LOG_FP_REGS) PrintFPRegisters();
537 enum PrintFPRegisterSizes {
540 kPrintAllFPRegValues = kPrintDRegValue | kPrintSRegValue
545 void PrintFPRegister(
unsigned code,
546 PrintFPRegisterSizes sizes = kPrintAllFPRegValues);
551 if (log_parameters() &
LOG_REGS) PrintRegister(code, r31mode);
553 void LogFPRegister(
unsigned code,
554 PrintFPRegisterSizes sizes = kPrintAllFPRegValues) {
555 if (log_parameters() &
LOG_FP_REGS) PrintFPRegister(code, sizes);
558 if (log_parameters() &
LOG_SYS_REGS) PrintSystemRegister(
id);
562 void PrintRead(
uintptr_t address,
size_t size,
unsigned reg_code);
563 void PrintReadFP(
uintptr_t address,
size_t size,
unsigned reg_code);
564 void PrintWrite(
uintptr_t address,
size_t size,
unsigned reg_code);
565 void PrintWriteFP(
uintptr_t address,
size_t size,
unsigned reg_code);
568 void LogRead(
uintptr_t address,
size_t size,
unsigned reg_code) {
569 if (log_parameters() &
LOG_REGS) PrintRead(address,
size, reg_code);
571 void LogReadFP(
uintptr_t address,
size_t size,
unsigned reg_code) {
572 if (log_parameters() &
LOG_FP_REGS) PrintReadFP(address,
size, reg_code);
574 void LogWrite(
uintptr_t address,
size_t size,
unsigned reg_code) {
575 if (log_parameters() &
LOG_WRITE) PrintWrite(address,
size, reg_code);
577 void LogWriteFP(
uintptr_t address,
size_t size,
unsigned reg_code) {
578 if (log_parameters() &
LOG_WRITE) PrintWriteFP(address,
size, reg_code);
581 int log_parameters() {
return log_parameters_; }
582 void set_log_parameters(
int new_parameters) {
583 log_parameters_ = new_parameters;
586 PrintF(
"Run --debug-sim to dynamically turn on disassembler\n");
591 decoder_->InsertVisitorBefore(print_disasm_,
this);
593 decoder_->RemoveVisitor(print_disasm_);
597 static inline const char* WRegNameForCode(
unsigned code,
599 static inline const char* XRegNameForCode(
unsigned code,
601 static inline const char* SRegNameForCode(
unsigned code);
602 static inline const char* DRegNameForCode(
unsigned code);
603 static inline const char* VRegNameForCode(
unsigned code);
604 static inline int CodeFromName(
const char*
name);
609 SimSystemRegister&
flags = nzcv();
649 return !ConditionPassed(cond);
653 void AddSubHelper(Instruction* instr,
T op2);
655 T AddWithCarry(
bool set_flags,
660 void AddSubWithCarry(Instruction* instr);
662 void LogicalHelper(Instruction* instr,
T op2);
664 void ConditionalCompareHelper(Instruction* instr,
T op2);
665 void LoadStoreHelper(Instruction* instr,
668 void LoadStorePairHelper(Instruction* instr,
AddrMode addrmode);
669 uintptr_t LoadStoreAddress(
unsigned addr_reg, int64_t offset,
671 void LoadStoreWriteBack(
unsigned addr_reg,
677 template <
typename T,
typename A>
678 T MemoryRead(
A address) {
680 STATIC_ASSERT((
sizeof(value) == 1) || (
sizeof(value) == 2) ||
681 (
sizeof(value) == 4) || (
sizeof(value) == 8));
682 memcpy(&value,
reinterpret_cast<const void*
>(address),
sizeof(value));
687 template <
typename T,
typename A>
688 void MemoryWrite(
A address,
T value) {
689 STATIC_ASSERT((
sizeof(value) == 1) || (
sizeof(value) == 2) ||
690 (
sizeof(value) == 4) || (
sizeof(value) == 8));
691 memcpy(
reinterpret_cast<void*
>(address), &value,
sizeof(value));
694 template <
typename T>
695 T ShiftOperand(
T value,
698 template <
typename T>
699 T ExtendValue(
T value,
701 unsigned left_shift = 0);
702 template <
typename T>
703 void Extract(Instruction* instr);
704 template <
typename T>
705 void DataProcessing2Source(Instruction* instr);
706 template <
typename T>
707 void BitfieldHelper(Instruction* instr);
709 uint64_t ReverseBits(uint64_t value,
unsigned num_bits);
710 uint64_t ReverseBytes(uint64_t value, ReverseByteMode
mode);
712 template <
typename T>
713 T FPDefaultNaN()
const;
715 void FPCompare(
double val0,
double val1);
716 double FPRoundInt(
double value,
FPRounding round_mode);
717 double FPToDouble(
float value);
718 float FPToFloat(
double value,
FPRounding round_mode);
719 double FixedToDouble(int64_t src,
int fbits,
FPRounding round_mode);
720 double UFixedToDouble(uint64_t src,
int fbits,
FPRounding round_mode);
721 float FixedToFloat(int64_t src,
int fbits,
FPRounding round_mode);
722 float UFixedToFloat(uint64_t src,
int fbits,
FPRounding round_mode);
724 int64_t FPToInt64(
double value,
FPRounding rmode);
726 uint64_t FPToUInt64(
double value,
FPRounding rmode);
728 template <
typename T>
729 T FPAdd(
T op1,
T op2);
731 template <
typename T>
732 T FPDiv(
T op1,
T op2);
734 template <
typename T>
737 template <
typename T>
740 template <
typename T>
743 template <
typename T>
746 template <
typename T>
747 T FPMul(
T op1,
T op2);
749 template <
typename T>
750 T FPMulAdd(
T a,
T op1,
T op2);
752 template <
typename T>
755 template <
typename T>
756 T FPSub(
T op1,
T op2);
759 template <
typename T>
760 T FPProcessNaN(
T op);
762 bool FPProcessNaNs(Instruction* instr);
764 template <
typename T>
765 T FPProcessNaNs(
T op1,
T op2);
767 template <
typename T>
768 T FPProcessNaNs3(
T op1,
T op2,
T op3);
770 void CheckStackAlignment();
772 inline void CheckPCSComplianceAndRun();
777 static const uint64_t kCallerSavedRegisterCorruptionValue =
778 0xca11edc0de000000UL;
780 static const uint64_t kCallerSavedFPRegisterCorruptionValue =
781 0x7ff000007f801000UL;
783 static const uint64_t kDefaultCPURegisterCorruptionValue =
784 0x7ffbad007f8bad00UL;
786 void CorruptRegisters(CPURegList* list,
787 uint64_t value = kDefaultCPURegisterCorruptionValue);
788 void CorruptAllCallerSavedCPURegisters();
792 void DoPrintf(Instruction* instr);
798 PrintDisassembler* print_disasm_;
802 Instrument* instrument_;
813 SimSystemRegister nzcv_;
816 SimSystemRegister fpcr_;
825 void AssertSupportedFPCR() {
833 template <
typename T>
834 static int CalcNFlag(
T result) {
835 return (result >> (
sizeof(
T) * 8 - 1)) & 1;
838 static int CalcZFlag(uint64_t result) {
842 static const uint32_t kConditionFlagsMask = 0xf0000000;
846 static const size_t stack_protection_size_ =
KB;
850 Decoder<DispatchingDecoderVisitor>* decoder_;
851 Decoder<DispatchingDecoderVisitor>* disassembler_decoder_;
858 static const char* xreg_names[];
859 static const char* wreg_names[];
860 static const char* sreg_names[];
861 static const char* dreg_names[];
862 static const char* vreg_names[];
865 void set_last_debugger_input(
char* input) {
867 last_debugger_input_ = input;
869 char* last_debugger_input() {
return last_debugger_input_; }
870 char* last_debugger_input_;
873 void Init(FILE* stream);
882 #define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4) \
883 reinterpret_cast<Object*>(Simulator::current(Isolate::Current())->CallJS( \
884 FUNCTION_ADDR(entry), \
887 #define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7, p8) \
888 Simulator::current(Isolate::Current())->CallRegExp( \
890 p0, p1, p2, p3, p4, p5, p6, p7, NULL, p8)
900 return Simulator::current(isolate)->StackLimit();
904 Simulator* sim = Simulator::current(Isolate::Current());
905 return sim->PushAddress(try_catch_address);
909 Simulator::current(Isolate::Current())->PopAddress();
static void UnregisterCTryCatch()
static uintptr_t RegisterCTryCatch(uintptr_t try_catch_address)
static uintptr_t JsLimitFromCLimit(v8::internal::Isolate *isolate, uintptr_t c_limit)
#define SYSTEM_REGISTER_FIELDS_LIST(V_, M_)
enable harmony numeric enable harmony object literal extensions Optimize object size
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be expose gc extension under the specified name show built in functions in stack traces use random jit cookie to mask large constants minimum length for automatic enable preparsing CPU profiler sampling interval in microseconds trace out of bounds accesses to external arrays default size of stack region v8 is allowed to maximum length of function source code printed in a stack trace min size of a semi the new space consists of two semi spaces print one trace line following each garbage collection do not print trace line after scavenger collection print cumulative GC statistics in name
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long mode(MIPS only)") DEFINE_BOOL(enable_always_align_csp
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
#define DEFINE_GETTER(Name, HighBit, LowBit, Func)
#define DCHECK(condition)
void DeleteArray(T *array)
const unsigned kDRegSizeInBits
TypeImpl< ZoneTypeConfig > Type
kSerializedDataOffset Object
const unsigned kSRegSizeInBits
const unsigned kNumberOfFPRegisters
const unsigned kFramePointerRegCode
void PrintF(const char *format,...)
int(* arm64_regexp_matcher)(String *input, int64_t start_offset, const byte *input_start, const byte *input_end, int *output, int64_t output_size, Address stack_base, int64_t direct_call, void *return_address, Isolate *isolate)
int32_t signed_bitextract_32(int msb, int lsb, int32_t x)
STATIC_ASSERT(sizeof(CPURegister)==sizeof(Register))
const unsigned kNumberOfRegisters
bool IsAligned(T value, U alignment)
const unsigned kInstructionSize
const unsigned kLinkRegCode
uint32_t unsigned_bitextract_32(int msb, int lsb, uint32_t x)
Debugger support for the V8 JavaScript engine.
#define T(name, string, precedence)
#define PRINTF_METHOD_CHECKING