1f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// Copyright 2013 the V8 project authors. All rights reserved. 23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be 33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file. 4f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 5fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org#ifndef V8_ARM64_SIMULATOR_ARM64_H_ 6fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org#define V8_ARM64_SIMULATOR_ARM64_H_ 7f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 8f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org#include <stdarg.h> 9f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org#include <vector> 10f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h" 12f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 13196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/allocation.h" 14196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/arm64/assembler-arm64.h" 15196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/arm64/decoder-arm64.h" 16196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/arm64/disasm-arm64.h" 17196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/arm64/instrument-arm64.h" 184b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/assembler.h" 194b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/globals.h" 204b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/utils.h" 21f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 22f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org#define REGISTER_CODE_LIST(R) \ 23f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgR(0) R(1) R(2) R(3) R(4) R(5) R(6) R(7) \ 24f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgR(8) R(9) R(10) R(11) R(12) R(13) R(14) R(15) \ 25f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgR(16) R(17) R(18) R(19) R(20) R(21) R(22) R(23) \ 26f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgR(24) R(25) R(26) R(27) R(28) R(29) R(30) R(31) 27f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 28f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgnamespace v8 { 29f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgnamespace internal { 30f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 31f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org#if !defined(USE_SIMULATOR) 32f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 33fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org// Running without a simulator on a native ARM64 platform. 34f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// When running without a simulator we call the entry directly. 35f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org#define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4) \ 36f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org (entry(p0, p1, p2, p3, p4)) 37f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 38fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.orgtypedef int (*arm64_regexp_matcher)(String* input, 39fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org int64_t start_offset, 40fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org const byte* input_start, 41fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org const byte* input_end, 42fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org int* output, 43fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org int64_t output_size, 44fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org Address stack_base, 45fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org int64_t direct_call, 46fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org void* return_address, 47fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org Isolate* isolate); 48f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 49f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// Call the generated regexp code directly. The code at the entry address 50fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org// should act as a function matching the type arm64_regexp_matcher. 51f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// The ninth argument is a dummy that reserves the space used for 52f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// the return address added by the ExitFrame in native calls. 53f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7, p8) \ 54fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org (FUNCTION_CAST<arm64_regexp_matcher>(entry)( \ 55f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org p0, p1, p2, p3, p4, p5, p6, p7, NULL, p8)) 56f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 57f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// Running without a simulator there is nothing to do. 58f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgclass SimulatorStack : public v8::internal::AllStatic { 59f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org public: 60f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org static uintptr_t JsLimitFromCLimit(v8::internal::Isolate* isolate, 61f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org uintptr_t c_limit) { 62f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org USE(isolate); 63f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return c_limit; 64f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 65f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 66f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org static uintptr_t RegisterCTryCatch(uintptr_t try_catch_address) { 67f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return try_catch_address; 68f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 69f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 70f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org static void UnregisterCTryCatch() { } 71f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org}; 72f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 73f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org#else // !defined(USE_SIMULATOR) 74f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 75f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgenum ReverseByteMode { 76f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Reverse16 = 0, 77f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Reverse32 = 1, 78f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Reverse64 = 2 79f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org}; 80f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 81f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 82f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// The proper way to initialize a simulated system register (such as NZCV) is as 83f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// follows: 84f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// SimSystemRegister nzcv = SimSystemRegister::DefaultValueFor(NZCV); 85f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgclass SimSystemRegister { 86f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org public: 87f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // The default constructor represents a register which has no writable bits. 88f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // It is not possible to set its value to anything other than 0. 89f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org SimSystemRegister() : value_(0), write_ignore_mask_(0xffffffff) { } 90f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 91f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org uint32_t RawValue() const { 92f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return value_; 93f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 94f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 95f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void SetRawValue(uint32_t new_value) { 96f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org value_ = (value_ & write_ignore_mask_) | (new_value & ~write_ignore_mask_); 97f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 98f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 99f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org uint32_t Bits(int msb, int lsb) const { 100f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return unsigned_bitextract_32(msb, lsb, value_); 101f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 102f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 103f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int32_t SignedBits(int msb, int lsb) const { 104f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return signed_bitextract_32(msb, lsb, value_); 105f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 106f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 107f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void SetBits(int msb, int lsb, uint32_t bits); 108f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 109f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Default system register values. 110f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org static SimSystemRegister DefaultValueFor(SystemRegister id); 111f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 1129801e3c558f3df82f01ac626b6171032afa33819machenbach@chromium.org#define DEFINE_GETTER(Name, HighBit, LowBit, Func, Type) \ 1139801e3c558f3df82f01ac626b6171032afa33819machenbach@chromium.org Type Name() const { return static_cast<Type>(Func(HighBit, LowBit)); } \ 1149801e3c558f3df82f01ac626b6171032afa33819machenbach@chromium.org void Set##Name(Type bits) { \ 1159801e3c558f3df82f01ac626b6171032afa33819machenbach@chromium.org SetBits(HighBit, LowBit, static_cast<Type>(bits)); \ 1169801e3c558f3df82f01ac626b6171032afa33819machenbach@chromium.org } 1179801e3c558f3df82f01ac626b6171032afa33819machenbach@chromium.org#define DEFINE_WRITE_IGNORE_MASK(Name, Mask) \ 118f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org static const uint32_t Name##WriteIgnoreMask = ~static_cast<uint32_t>(Mask); 119f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org SYSTEM_REGISTER_FIELDS_LIST(DEFINE_GETTER, DEFINE_WRITE_IGNORE_MASK) 120f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org#undef DEFINE_ZERO_BITS 121f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org#undef DEFINE_GETTER 122f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 123f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org protected: 124f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Most system registers only implement a few of the bits in the word. Other 125f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // bits are "read-as-zero, write-ignored". The write_ignore_mask argument 126f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // describes the bits which are not modifiable. 127f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org SimSystemRegister(uint32_t value, uint32_t write_ignore_mask) 128f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org : value_(value), write_ignore_mask_(write_ignore_mask) { } 129f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 130f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org uint32_t value_; 131f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org uint32_t write_ignore_mask_; 132f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org}; 133f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 134f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 135f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// Represent a register (r0-r31, v0-v31). 136f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgclass SimRegisterBase { 137f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org public: 138f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org template<typename T> 1391845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org void Set(T new_value) { 1401845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org value_ = 0; 1411845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org memcpy(&value_, &new_value, sizeof(T)); 142f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 143f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 144f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org template<typename T> 1451845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org T Get() const { 146f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org T result; 1471845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org memcpy(&result, &value_, sizeof(T)); 148f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return result; 149f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 150f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 151f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org protected: 1521845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org int64_t value_; 153f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org}; 1541845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org 1551845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org 1561845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.orgtypedef SimRegisterBase SimRegister; // r0-r31 1571845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.orgtypedef SimRegisterBase SimFPRegister; // v0-v31 158f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 159f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 160f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgclass Simulator : public DecoderVisitor { 161f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org public: 162f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org explicit Simulator(Decoder<DispatchingDecoderVisitor>* decoder, 163f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Isolate* isolate = NULL, 164f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org FILE* stream = stderr); 165f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Simulator(); 166f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org ~Simulator(); 167f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 168f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // System functions. 169f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 170f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org static void Initialize(Isolate* isolate); 171f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 172f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org static Simulator* current(v8::internal::Isolate* isolate); 173f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 174f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org class CallArgument; 175f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 176f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Call an arbitrary function taking an arbitrary number of arguments. The 177f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // varargs list must be a set of arguments with type CallArgument, and 178f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // terminated by CallArgument::End(). 179f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void CallVoid(byte* entry, CallArgument* args); 180f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 181f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Like CallVoid, but expect a return value. 182f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int64_t CallInt64(byte* entry, CallArgument* args); 183f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org double CallDouble(byte* entry, CallArgument* args); 184f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 185f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // V8 calls into generated JS code with 5 parameters and into 186f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // generated RegExp code with 10 parameters. These are convenience functions, 187f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // which set up the simulator state and grab the result on return. 188f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int64_t CallJS(byte* entry, 189f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org byte* function_entry, 190f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org JSFunction* func, 191f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Object* revc, 192f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int64_t argc, 193f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Object*** argv); 194f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int64_t CallRegExp(byte* entry, 195f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org String* input, 196f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int64_t start_offset, 197f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org const byte* input_start, 198f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org const byte* input_end, 199f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int* output, 200f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int64_t output_size, 201f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Address stack_base, 202f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int64_t direct_call, 203f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void* return_address, 204f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Isolate* isolate); 205f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 206f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // A wrapper class that stores an argument for one of the above Call 207f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // functions. 208f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // 209f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Only arguments up to 64 bits in size are supported. 210f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org class CallArgument { 211f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org public: 212f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org template<typename T> 213f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org explicit CallArgument(T argument) { 2147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bits_ = 0; 215e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(sizeof(argument) <= sizeof(bits_)); 216f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org memcpy(&bits_, &argument, sizeof(argument)); 217f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org type_ = X_ARG; 218f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 219f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 220f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org explicit CallArgument(double argument) { 221e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(sizeof(argument) == sizeof(bits_)); 222f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org memcpy(&bits_, &argument, sizeof(argument)); 223f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org type_ = D_ARG; 224f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 225f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 226f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org explicit CallArgument(float argument) { 227f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // TODO(all): CallArgument(float) is untested, remove this check once 228f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // tested. 229f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org UNIMPLEMENTED(); 230f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Make the D register a NaN to try to trap errors if the callee expects a 231f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // double. If it expects a float, the callee should ignore the top word. 232e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(sizeof(kFP64SignallingNaN) == sizeof(bits_)); 233f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org memcpy(&bits_, &kFP64SignallingNaN, sizeof(kFP64SignallingNaN)); 234f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Write the float payload to the S register. 235e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(sizeof(argument) <= sizeof(bits_)); 236f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org memcpy(&bits_, &argument, sizeof(argument)); 237f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org type_ = D_ARG; 238f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 239f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 240f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // This indicates the end of the arguments list, so that CallArgument 241f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // objects can be passed into varargs functions. 242f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org static CallArgument End() { return CallArgument(); } 243f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 244f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int64_t bits() const { return bits_; } 245f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org bool IsEnd() const { return type_ == NO_ARG; } 246f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org bool IsX() const { return type_ == X_ARG; } 247f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org bool IsD() const { return type_ == D_ARG; } 248f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 249f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org private: 250f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org enum CallArgumentType { X_ARG, D_ARG, NO_ARG }; 251f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 252f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // All arguments are aligned to at least 64 bits and we don't support 253f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // passing bigger arguments, so the payload size can be fixed at 64 bits. 254f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int64_t bits_; 255f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org CallArgumentType type_; 256f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 257f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org CallArgument() { type_ = NO_ARG; } 258f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org }; 259f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 260f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 261f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Start the debugging command line. 262f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void Debug(); 263f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 264f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org bool GetValue(const char* desc, int64_t* value); 265f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 266f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org bool PrintValue(const char* desc); 267f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 268f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Push an address onto the JS stack. 269f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org uintptr_t PushAddress(uintptr_t address); 270f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 271f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Pop an address from the JS stack. 272f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org uintptr_t PopAddress(); 273f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 274f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Accessor to the internal simulator stack area. 275f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org uintptr_t StackLimit() const; 276f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 277f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void ResetState(); 278f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 279f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Runtime call support. 280f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org static void* RedirectExternalReference(void* external_function, 281f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org ExternalReference::Type type); 2827010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org void DoRuntimeCall(Instruction* instr); 283f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 284f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Run the simulator. 285f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org static const Instruction* kEndOfSimAddress; 286f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void DecodeInstruction(); 287f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void Run(); 288f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void RunFrom(Instruction* start); 289f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 290f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Simulation helpers. 291f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org template <typename T> 292f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void set_pc(T new_pc) { 293e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(sizeof(T) == sizeof(pc_)); 294f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org memcpy(&pc_, &new_pc, sizeof(T)); 295f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org pc_modified_ = true; 296f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 297f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Instruction* pc() { return pc_; } 298f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 299f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void increment_pc() { 300f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (!pc_modified_) { 3014452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org pc_ = pc_->following(); 302f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 303f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 304f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org pc_modified_ = false; 305f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 306f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 307f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org virtual void Decode(Instruction* instr) { 308f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org decoder_->Decode(instr); 309f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 310f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 311f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void ExecuteInstruction() { 312e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsAligned(reinterpret_cast<uintptr_t>(pc_), kInstructionSize)); 313f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org CheckBreakNext(); 314f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Decode(pc_); 315f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org increment_pc(); 316f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org CheckBreakpoints(); 317f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 318f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 319f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Declare all Visitor functions. 320f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org #define DECLARE(A) void Visit##A(Instruction* instr); 321f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org VISITOR_LIST(DECLARE) 322f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org #undef DECLARE 323f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 3241845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org bool IsZeroRegister(unsigned code, Reg31Mode r31mode) const { 3251845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org return ((code == 31) && (r31mode == Reg31IsZeroRegister)); 3261845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org } 327f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 3281845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org // Register accessors. 329f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Return 'size' bits of the value of an integer register, as the specified 330f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // type. The value is zero-extended to fill the result. 331f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // 332f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org template<typename T> 3331845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org T reg(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister) const { 334e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(code < kNumberOfRegisters); 3351845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org if (IsZeroRegister(code, r31mode)) { 3361845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org return 0; 337f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 3381845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org return registers_[code].Get<T>(); 339f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 340f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 341f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Common specialized accessors for the reg() template. 3421845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org int32_t wreg(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister) const { 343f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return reg<int32_t>(code, r31mode); 344f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 345f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 3461845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org int64_t xreg(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister) const { 347f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return reg<int64_t>(code, r31mode); 348f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 349f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 3502c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // Write 'value' into an integer register. The value is zero-extended. This 3512c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // behaviour matches AArch64 register writes. 352f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org template<typename T> 353f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void set_reg(unsigned code, T value, 354f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Reg31Mode r31mode = Reg31IsZeroRegister) { 3552c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org set_reg_no_log(code, value, r31mode); 3562c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org LogRegister(code, r31mode); 357f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 358f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 359f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Common specialized accessors for the set_reg() template. 360f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void set_wreg(unsigned code, int32_t value, 361f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Reg31Mode r31mode = Reg31IsZeroRegister) { 3621845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org set_reg(code, value, r31mode); 363f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 364f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 365f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void set_xreg(unsigned code, int64_t value, 366f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Reg31Mode r31mode = Reg31IsZeroRegister) { 3671845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org set_reg(code, value, r31mode); 368f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 369f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 3702c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // As above, but don't automatically log the register update. 3712c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org template <typename T> 3722c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org void set_reg_no_log(unsigned code, T value, 3732c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Reg31Mode r31mode = Reg31IsZeroRegister) { 3742c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org DCHECK(code < kNumberOfRegisters); 3752c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if (!IsZeroRegister(code, r31mode)) { 3762c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org registers_[code].Set(value); 3772c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org } 3782c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org } 3792c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 3802c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org void set_wreg_no_log(unsigned code, int32_t value, 3812c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Reg31Mode r31mode = Reg31IsZeroRegister) { 3822c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org set_reg_no_log(code, value, r31mode); 3832c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org } 3842c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 3852c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org void set_xreg_no_log(unsigned code, int64_t value, 3862c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Reg31Mode r31mode = Reg31IsZeroRegister) { 3872c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org set_reg_no_log(code, value, r31mode); 3882c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org } 3892c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 390f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Commonly-used special cases. 391f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org template<typename T> 392f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void set_lr(T value) { 393e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(sizeof(T) == kPointerSize); 394f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org set_reg(kLinkRegCode, value); 395f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 396f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 397f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org template<typename T> 398f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void set_sp(T value) { 399e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(sizeof(T) == kPointerSize); 400f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org set_reg(31, value, Reg31IsStackPointer); 401f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 402f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 403f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int64_t sp() { return xreg(31, Reg31IsStackPointer); } 404f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int64_t jssp() { return xreg(kJSSPCode, Reg31IsStackPointer); } 405f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int64_t fp() { 406f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return xreg(kFramePointerRegCode, Reg31IsStackPointer); 407f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 408f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Instruction* lr() { return reg<Instruction*>(kLinkRegCode); } 409f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 410f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Address get_sp() { return reg<Address>(31, Reg31IsStackPointer); } 411f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 412f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org template<typename T> 413f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org T fpreg(unsigned code) const { 414e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(code < kNumberOfRegisters); 4151845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org return fpregisters_[code].Get<T>(); 416f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 417f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 418f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Common specialized accessors for the fpreg() template. 419f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org float sreg(unsigned code) const { 420f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return fpreg<float>(code); 421f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 422f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 423f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org uint32_t sreg_bits(unsigned code) const { 424f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return fpreg<uint32_t>(code); 425f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 426f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 427f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org double dreg(unsigned code) const { 428f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return fpreg<double>(code); 429f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 430f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 431f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org uint64_t dreg_bits(unsigned code) const { 432f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return fpreg<uint64_t>(code); 433f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 434f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 435f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org double fpreg(unsigned size, unsigned code) const { 436f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org switch (size) { 43797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org case kSRegSizeInBits: return sreg(code); 43897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org case kDRegSizeInBits: return dreg(code); 439f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org default: 440f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org UNREACHABLE(); 441f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return 0.0; 442f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 443f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 444f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 445f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Write 'value' into a floating-point register. The value is zero-extended. 446f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // This behaviour matches AArch64 register writes. 447f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org template<typename T> 448f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void set_fpreg(unsigned code, T value) { 4492c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org set_fpreg_no_log(code, value); 4502c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 4512c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if (sizeof(value) <= kSRegSize) { 4522c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org LogFPRegister(code, kPrintSRegValue); 4532c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org } else { 4542c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org LogFPRegister(code, kPrintDRegValue); 4552c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org } 456f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 457f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 458f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Common specialized accessors for the set_fpreg() template. 459f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void set_sreg(unsigned code, float value) { 460f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org set_fpreg(code, value); 461f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 462f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 463f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void set_sreg_bits(unsigned code, uint32_t value) { 464f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org set_fpreg(code, value); 465f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 466f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 467f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void set_dreg(unsigned code, double value) { 468f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org set_fpreg(code, value); 469f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 470f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 471f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void set_dreg_bits(unsigned code, uint64_t value) { 472f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org set_fpreg(code, value); 473f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 474f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 4752c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // As above, but don't automatically log the register update. 4762c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org template <typename T> 4772c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org void set_fpreg_no_log(unsigned code, T value) { 4782c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org DCHECK((sizeof(value) == kDRegSize) || (sizeof(value) == kSRegSize)); 4792c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org DCHECK(code < kNumberOfFPRegisters); 4802c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org fpregisters_[code].Set(value); 4812c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org } 4822c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 4832c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org void set_sreg_no_log(unsigned code, float value) { 4842c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org set_fpreg_no_log(code, value); 4852c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org } 4862c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 4872c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org void set_dreg_no_log(unsigned code, double value) { 4882c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org set_fpreg_no_log(code, value); 4892c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org } 4902c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 491f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org SimSystemRegister& nzcv() { return nzcv_; } 492f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org SimSystemRegister& fpcr() { return fpcr_; } 493f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 494f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Debug helpers 495f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 496f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Simulator breakpoints. 497f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org struct Breakpoint { 498f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Instruction* location; 499f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org bool enabled; 500f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org }; 501f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org std::vector<Breakpoint> breakpoints_; 502f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void SetBreakpoint(Instruction* breakpoint); 503f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void ListBreakpoints(); 504f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void CheckBreakpoints(); 505f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 506f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Helpers for the 'next' command. 507f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // When this is set, the Simulator will insert a breakpoint after the next BL 508f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // instruction it meets. 509f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org bool break_on_next_; 510f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Check if the Simulator should insert a break after the current instruction 511f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // for the 'next' command. 512f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void CheckBreakNext(); 513f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 514f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Disassemble instruction at the given address. 515f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void PrintInstructionsAt(Instruction* pc, uint64_t count); 516f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 5172c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // Print all registers of the specified types. 5182c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org void PrintRegisters(); 5192c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org void PrintFPRegisters(); 5202c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org void PrintSystemRegisters(); 5212c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 5222c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // Like Print* (above), but respect log_parameters(). 523f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void LogSystemRegisters() { 5242c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if (log_parameters() & LOG_SYS_REGS) PrintSystemRegisters(); 525f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 526f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void LogRegisters() { 5272c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if (log_parameters() & LOG_REGS) PrintRegisters(); 528f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 529f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void LogFPRegisters() { 5302c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if (log_parameters() & LOG_FP_REGS) PrintFPRegisters(); 5312c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org } 5322c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 5332c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // Specify relevant register sizes, for PrintFPRegister. 5342c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // 5352c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // These values are bit masks; they can be combined in case multiple views of 5362c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // a machine register are interesting. 5372c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org enum PrintFPRegisterSizes { 5382c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org kPrintDRegValue = 1 << kDRegSize, 5392c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org kPrintSRegValue = 1 << kSRegSize, 5402c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org kPrintAllFPRegValues = kPrintDRegValue | kPrintSRegValue 5412c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org }; 5422c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 5432c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // Print individual register values (after update). 5442c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org void PrintRegister(unsigned code, Reg31Mode r31mode = Reg31IsStackPointer); 5452c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org void PrintFPRegister(unsigned code, 5462c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org PrintFPRegisterSizes sizes = kPrintAllFPRegValues); 5472c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org void PrintSystemRegister(SystemRegister id); 5482c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 5492c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // Like Print* (above), but respect log_parameters(). 5502c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org void LogRegister(unsigned code, Reg31Mode r31mode = Reg31IsStackPointer) { 5512c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if (log_parameters() & LOG_REGS) PrintRegister(code, r31mode); 552f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 5532c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org void LogFPRegister(unsigned code, 5542c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org PrintFPRegisterSizes sizes = kPrintAllFPRegValues) { 5552c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if (log_parameters() & LOG_FP_REGS) PrintFPRegister(code, sizes); 556f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 5572c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org void LogSystemRegister(SystemRegister id) { 5582c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if (log_parameters() & LOG_SYS_REGS) PrintSystemRegister(id); 5592c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org } 5602c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 5612c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // Print memory accesses. 5622c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org void PrintRead(uintptr_t address, size_t size, unsigned reg_code); 5632c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org void PrintReadFP(uintptr_t address, size_t size, unsigned reg_code); 5642c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org void PrintWrite(uintptr_t address, size_t size, unsigned reg_code); 5652c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org void PrintWriteFP(uintptr_t address, size_t size, unsigned reg_code); 5662c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 5672c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // Like Print* (above), but respect log_parameters(). 5682c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org void LogRead(uintptr_t address, size_t size, unsigned reg_code) { 5692c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if (log_parameters() & LOG_REGS) PrintRead(address, size, reg_code); 5702c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org } 5712c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org void LogReadFP(uintptr_t address, size_t size, unsigned reg_code) { 5722c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if (log_parameters() & LOG_FP_REGS) PrintReadFP(address, size, reg_code); 5732c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org } 5742c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org void LogWrite(uintptr_t address, size_t size, unsigned reg_code) { 5752c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if (log_parameters() & LOG_WRITE) PrintWrite(address, size, reg_code); 5762c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org } 5772c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org void LogWriteFP(uintptr_t address, size_t size, unsigned reg_code) { 5782c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if (log_parameters() & LOG_WRITE) PrintWriteFP(address, size, reg_code); 579f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 580f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 581f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int log_parameters() { return log_parameters_; } 582f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void set_log_parameters(int new_parameters) { 583f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org log_parameters_ = new_parameters; 584f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (!decoder_) { 585f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (new_parameters & LOG_DISASM) { 586f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org PrintF("Run --debug-sim to dynamically turn on disassembler\n"); 587f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 588f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return; 589f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 590f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (new_parameters & LOG_DISASM) { 591f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org decoder_->InsertVisitorBefore(print_disasm_, this); 592f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } else { 593f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org decoder_->RemoveVisitor(print_disasm_); 594f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 595f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 596f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 597f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org static inline const char* WRegNameForCode(unsigned code, 598f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Reg31Mode mode = Reg31IsZeroRegister); 599f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org static inline const char* XRegNameForCode(unsigned code, 600f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Reg31Mode mode = Reg31IsZeroRegister); 601f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org static inline const char* SRegNameForCode(unsigned code); 602f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org static inline const char* DRegNameForCode(unsigned code); 603f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org static inline const char* VRegNameForCode(unsigned code); 604f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org static inline int CodeFromName(const char* name); 605f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 606f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org protected: 607f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Simulation helpers ------------------------------------ 608f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org bool ConditionPassed(Condition cond) { 6099801e3c558f3df82f01ac626b6171032afa33819machenbach@chromium.org SimSystemRegister& flags = nzcv(); 610f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org switch (cond) { 611f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case eq: 6129801e3c558f3df82f01ac626b6171032afa33819machenbach@chromium.org return flags.Z(); 613f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case ne: 6149801e3c558f3df82f01ac626b6171032afa33819machenbach@chromium.org return !flags.Z(); 615f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case hs: 6169801e3c558f3df82f01ac626b6171032afa33819machenbach@chromium.org return flags.C(); 617f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case lo: 6189801e3c558f3df82f01ac626b6171032afa33819machenbach@chromium.org return !flags.C(); 619f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case mi: 6209801e3c558f3df82f01ac626b6171032afa33819machenbach@chromium.org return flags.N(); 621f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case pl: 6229801e3c558f3df82f01ac626b6171032afa33819machenbach@chromium.org return !flags.N(); 623f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case vs: 6249801e3c558f3df82f01ac626b6171032afa33819machenbach@chromium.org return flags.V(); 625f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case vc: 6269801e3c558f3df82f01ac626b6171032afa33819machenbach@chromium.org return !flags.V(); 627f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case hi: 6289801e3c558f3df82f01ac626b6171032afa33819machenbach@chromium.org return flags.C() && !flags.Z(); 629f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case ls: 6309801e3c558f3df82f01ac626b6171032afa33819machenbach@chromium.org return !(flags.C() && !flags.Z()); 631f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case ge: 6329801e3c558f3df82f01ac626b6171032afa33819machenbach@chromium.org return flags.N() == flags.V(); 633f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case lt: 6349801e3c558f3df82f01ac626b6171032afa33819machenbach@chromium.org return flags.N() != flags.V(); 635f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case gt: 6369801e3c558f3df82f01ac626b6171032afa33819machenbach@chromium.org return !flags.Z() && (flags.N() == flags.V()); 637f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case le: 6389801e3c558f3df82f01ac626b6171032afa33819machenbach@chromium.org return !(!flags.Z() && (flags.N() == flags.V())); 639f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case nv: // Fall through. 640f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case al: 641f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return true; 642f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org default: 643f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org UNREACHABLE(); 644f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return false; 645f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 646f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 647f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 648f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org bool ConditionFailed(Condition cond) { 649f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return !ConditionPassed(cond); 650f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 651f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 6521845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org template<typename T> 6531845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org void AddSubHelper(Instruction* instr, T op2); 6541845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org template<typename T> 6551845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org T AddWithCarry(bool set_flags, 6561845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org T src1, 6571845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org T src2, 6581845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org T carry_in = 0); 6591845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org template<typename T> 6601845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org void AddSubWithCarry(Instruction* instr); 6611845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org template<typename T> 6621845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org void LogicalHelper(Instruction* instr, T op2); 6631845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org template<typename T> 6641845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org void ConditionalCompareHelper(Instruction* instr, T op2); 665f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void LoadStoreHelper(Instruction* instr, 666f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int64_t offset, 667f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org AddrMode addrmode); 668f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void LoadStorePairHelper(Instruction* instr, AddrMode addrmode); 6692c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org uintptr_t LoadStoreAddress(unsigned addr_reg, int64_t offset, 6702c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org AddrMode addrmode); 671f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void LoadStoreWriteBack(unsigned addr_reg, 672f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int64_t offset, 673f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org AddrMode addrmode); 6742c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org void CheckMemoryAccess(uintptr_t address, uintptr_t stack); 675f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 6762c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // Memory read helpers. 6779aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org template <typename T, typename A> 6789aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org T MemoryRead(A address) { 6799aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org T value; 6809aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org STATIC_ASSERT((sizeof(value) == 1) || (sizeof(value) == 2) || 6819aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org (sizeof(value) == 4) || (sizeof(value) == 8)); 6829aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org memcpy(&value, reinterpret_cast<const void*>(address), sizeof(value)); 6839aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org return value; 6849aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org } 685f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 6862c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // Memory write helpers. 6879aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org template <typename T, typename A> 6889aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org void MemoryWrite(A address, T value) { 6899aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org STATIC_ASSERT((sizeof(value) == 1) || (sizeof(value) == 2) || 6909aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org (sizeof(value) == 4) || (sizeof(value) == 8)); 6919aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org memcpy(reinterpret_cast<void*>(address), &value, sizeof(value)); 6929aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org } 6931845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org 6941845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org template <typename T> 6951845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org T ShiftOperand(T value, 696f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Shift shift_type, 697f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org unsigned amount); 6981845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org template <typename T> 6991845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org T ExtendValue(T value, 7001845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org Extend extend_type, 7011845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org unsigned left_shift = 0); 7021845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org template <typename T> 7031845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org void Extract(Instruction* instr); 7041845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org template <typename T> 7051845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org void DataProcessing2Source(Instruction* instr); 7061845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org template <typename T> 7071845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org void BitfieldHelper(Instruction* instr); 708f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 709f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org uint64_t ReverseBits(uint64_t value, unsigned num_bits); 710f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org uint64_t ReverseBytes(uint64_t value, ReverseByteMode mode); 711f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 7126b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org template <typename T> 7136b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org T FPDefaultNaN() const; 7146b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org 715f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void FPCompare(double val0, double val1); 716f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org double FPRoundInt(double value, FPRounding round_mode); 717f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org double FPToDouble(float value); 718f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org float FPToFloat(double value, FPRounding round_mode); 719f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org double FixedToDouble(int64_t src, int fbits, FPRounding round_mode); 720f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org double UFixedToDouble(uint64_t src, int fbits, FPRounding round_mode); 721f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org float FixedToFloat(int64_t src, int fbits, FPRounding round_mode); 722f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org float UFixedToFloat(uint64_t src, int fbits, FPRounding round_mode); 723f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int32_t FPToInt32(double value, FPRounding rmode); 724f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int64_t FPToInt64(double value, FPRounding rmode); 725f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org uint32_t FPToUInt32(double value, FPRounding rmode); 726f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org uint64_t FPToUInt64(double value, FPRounding rmode); 727f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 728f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org template <typename T> 7296b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org T FPAdd(T op1, T op2); 730f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 731f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org template <typename T> 7326b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org T FPDiv(T op1, T op2); 7336b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org 7346b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org template <typename T> 7356b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org T FPMax(T a, T b); 736f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 737f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org template <typename T> 738f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org T FPMaxNM(T a, T b); 739f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 740f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org template <typename T> 7416b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org T FPMin(T a, T b); 7426b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org 7436b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org template <typename T> 744f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org T FPMinNM(T a, T b); 745f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 7466b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org template <typename T> 7476b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org T FPMul(T op1, T op2); 7486b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org 7496b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org template <typename T> 7506b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org T FPMulAdd(T a, T op1, T op2); 7516b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org 7526b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org template <typename T> 7536b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org T FPSqrt(T op); 7546b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org 7556b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org template <typename T> 7566b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org T FPSub(T op1, T op2); 7576b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org 7586b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org // Standard NaN processing. 7596b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org template <typename T> 7606b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org T FPProcessNaN(T op); 7616b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org 7626b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org bool FPProcessNaNs(Instruction* instr); 7636b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org 7646b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org template <typename T> 7656b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org T FPProcessNaNs(T op1, T op2); 7666b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org 7676b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org template <typename T> 7686b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org T FPProcessNaNs3(T op1, T op2, T op3); 7696b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org 770f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void CheckStackAlignment(); 771f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 772f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org inline void CheckPCSComplianceAndRun(); 773f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 774f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org#ifdef DEBUG 775f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Corruption values should have their least significant byte cleared to 776f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // allow the code of the register being corrupted to be inserted. 777f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org static const uint64_t kCallerSavedRegisterCorruptionValue = 778f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 0xca11edc0de000000UL; 779f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // This value is a NaN in both 32-bit and 64-bit FP. 780f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org static const uint64_t kCallerSavedFPRegisterCorruptionValue = 781f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 0x7ff000007f801000UL; 782f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // This value is a mix of 32/64-bits NaN and "verbose" immediate. 783f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org static const uint64_t kDefaultCPURegisterCorruptionValue = 784f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 0x7ffbad007f8bad00UL; 785f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 786f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void CorruptRegisters(CPURegList* list, 787f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org uint64_t value = kDefaultCPURegisterCorruptionValue); 788f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void CorruptAllCallerSavedCPURegisters(); 789f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org#endif 790f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 791a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org // Pseudo Printf instruction 792a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org void DoPrintf(Instruction* instr); 793a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org 794f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Processor state --------------------------------------- 795f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 796f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Output stream. 797f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org FILE* stream_; 798f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org PrintDisassembler* print_disasm_; 7999e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org void PRINTF_METHOD_CHECKING TraceSim(const char* format, ...); 800f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 801f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Instrumentation. 802f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Instrument* instrument_; 803f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 804f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // General purpose registers. Register 31 is the stack pointer. 805f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org SimRegister registers_[kNumberOfRegisters]; 806f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 807f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Floating point registers 808f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org SimFPRegister fpregisters_[kNumberOfFPRegisters]; 809f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 810f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Processor state 811f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // bits[31, 27]: Condition flags N, Z, C, and V. 812f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // (Negative, Zero, Carry, Overflow) 813f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org SimSystemRegister nzcv_; 814f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 815f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Floating-Point Control Register 816f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org SimSystemRegister fpcr_; 817f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 818f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Only a subset of FPCR features are supported by the simulator. This helper 819f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // checks that the FPCR settings are supported. 820f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // 821f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // This is checked when floating-point instructions are executed, not when 822f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // FPCR is set. This allows generated code to modify FPCR for external 823f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // functions, or to save and restore it when entering and leaving generated 824f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // code. 825f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void AssertSupportedFPCR() { 826e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(fpcr().FZ() == 0); // No flush-to-zero support. 827e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(fpcr().RMode() == FPTieEven); // Ties-to-even rounding only. 828f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 829f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // The simulator does not support half-precision operations so fpcr().AHP() 830f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // is irrelevant, and is not checked here. 831f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 832f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 8331845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org template <typename T> 8341845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org static int CalcNFlag(T result) { 8351845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org return (result >> (sizeof(T) * 8 - 1)) & 1; 836f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 837f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 838f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org static int CalcZFlag(uint64_t result) { 839f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return result == 0; 840f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 841f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 842f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org static const uint32_t kConditionFlagsMask = 0xf0000000; 843f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 844f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Stack 8452c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org uintptr_t stack_; 8462c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org static const size_t stack_protection_size_ = KB; 8472c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org size_t stack_size_; 8482c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org uintptr_t stack_limit_; 849f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 850f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Decoder<DispatchingDecoderVisitor>* decoder_; 851f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Decoder<DispatchingDecoderVisitor>* disassembler_decoder_; 852f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 853f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Indicates if the pc has been modified by the instruction and should not be 854f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // automatically incremented. 855f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org bool pc_modified_; 856f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Instruction* pc_; 857f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 858f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org static const char* xreg_names[]; 859f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org static const char* wreg_names[]; 860f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org static const char* sreg_names[]; 861f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org static const char* dreg_names[]; 862f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org static const char* vreg_names[]; 863f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 864f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Debugger input. 865f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void set_last_debugger_input(char* input) { 866f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org DeleteArray(last_debugger_input_); 867f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org last_debugger_input_ = input; 868f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 869f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org char* last_debugger_input() { return last_debugger_input_; } 870f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org char* last_debugger_input_; 871f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 872f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org private: 873f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void Init(FILE* stream); 874f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 875f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int log_parameters_; 876f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Isolate* isolate_; 877f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org}; 878f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 879f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 880f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// When running with the simulator transition into simulated execution at this 881f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// point. 882f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org#define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4) \ 883f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org reinterpret_cast<Object*>(Simulator::current(Isolate::Current())->CallJS( \ 884f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org FUNCTION_ADDR(entry), \ 885f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org p0, p1, p2, p3, p4)) 886f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 887f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7, p8) \ 888f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Simulator::current(Isolate::Current())->CallRegExp( \ 889f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org entry, \ 890f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org p0, p1, p2, p3, p4, p5, p6, p7, NULL, p8) 891f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 892f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 893f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// The simulator has its own stack. Thus it has a different stack limit from 894f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// the C-based native code. 895f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// See also 'class SimulatorStack' in arm/simulator-arm.h. 896f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgclass SimulatorStack : public v8::internal::AllStatic { 897f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org public: 898f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org static uintptr_t JsLimitFromCLimit(v8::internal::Isolate* isolate, 899f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org uintptr_t c_limit) { 900f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return Simulator::current(isolate)->StackLimit(); 901f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 902f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 903f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org static uintptr_t RegisterCTryCatch(uintptr_t try_catch_address) { 904f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Simulator* sim = Simulator::current(Isolate::Current()); 905f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return sim->PushAddress(try_catch_address); 906f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 907f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 908f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org static void UnregisterCTryCatch() { 909f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Simulator::current(Isolate::Current())->PopAddress(); 910f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 911f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org}; 912f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 913f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org#endif // !defined(USE_SIMULATOR) 914f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 915f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} } // namespace v8::internal 916f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 917fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org#endif // V8_ARM64_SIMULATOR_ARM64_H_ 918