1ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Copyright 2013, ARM Limited 2ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// All rights reserved. 3ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// 4ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Redistribution and use in source and binary forms, with or without 5ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// modification, are permitted provided that the following conditions are met: 6ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// 7ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// * Redistributions of source code must retain the above copyright notice, 8ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// this list of conditions and the following disclaimer. 9ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// * Redistributions in binary form must reproduce the above copyright notice, 10ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// this list of conditions and the following disclaimer in the documentation 11ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// and/or other materials provided with the distribution. 12ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// * Neither the name of ARM Limited nor the names of its contributors may be 13ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// used to endorse or promote products derived from this software without 14ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// specific prior written permission. 15ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// 16ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND 17ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 20ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 27ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#ifndef VIXL_A64_SIMULATOR_A64_H_ 28ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#define VIXL_A64_SIMULATOR_A64_H_ 29ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 30bc4afbd2754e20d14114e4ba83f9035b26ab701dSerban Constantinescu#include "globals-vixl.h" 31bc4afbd2754e20d14114e4ba83f9035b26ab701dSerban Constantinescu#include "utils-vixl.h" 32ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#include "a64/instructions-a64.h" 33ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#include "a64/assembler-a64.h" 34ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#include "a64/disasm-a64.h" 35578645f14e122d2b87d907e298cda7e7d0babf1farmvixl#include "a64/instrument-a64.h" 36ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 37ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlnamespace vixl { 38ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 39ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlenum ReverseByteMode { 40ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Reverse16 = 0, 41ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Reverse32 = 1, 42ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Reverse64 = 2 43ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}; 44ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 45ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// Printf. See debugger-a64.h for more information on pseudo instructions. 46ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// - arg_count: The number of arguments. 47ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// - arg_pattern: A set of PrintfArgPattern values, packed into two-bit fields. 48ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// 49ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Simulate a call to printf. 50ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// 51ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// Floating-point and integer arguments are passed in separate sets of registers 52ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// in AAPCS64 (even for varargs functions), so it is not possible to determine 53ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// the type of each argument without some information about the values that were 54ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// passed in. This information could be retrieved from the printf format string, 55ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// but the format string is not trivial to parse so we encode the relevant 56ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// information with the HLT instruction. 57ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// 58ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// The interface is as follows: 59ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// x0: The format string 60ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// x1-x7: Optional arguments, if type == CPURegister::kRegister 61ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// d0-d7: Optional arguments, if type == CPURegister::kFPRegister 62ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlconst Instr kPrintfOpcode = 0xdeb1; 63ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlconst unsigned kPrintfArgCountOffset = 1 * kInstructionSize; 64ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlconst unsigned kPrintfArgPatternListOffset = 2 * kInstructionSize; 65ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlconst unsigned kPrintfLength = 3 * kInstructionSize; 66ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 67ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlconst unsigned kPrintfMaxArgCount = 4; 68ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 69ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// The argument pattern is a set of two-bit-fields, each with one of the 70ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// following values: 71ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlenum PrintfArgPattern { 72ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl kPrintfArgW = 1, 73ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl kPrintfArgX = 2, 74ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl // There is no kPrintfArgS because floats are always converted to doubles in C 75ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl // varargs calls. 76ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl kPrintfArgD = 3 77ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl}; 78ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlstatic const unsigned kPrintfArgPatternBits = 2; 79ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 80578645f14e122d2b87d907e298cda7e7d0babf1farmvixl 81578645f14e122d2b87d907e298cda7e7d0babf1farmvixl// The proper way to initialize a simulated system register (such as NZCV) is as 82578645f14e122d2b87d907e298cda7e7d0babf1farmvixl// follows: 83578645f14e122d2b87d907e298cda7e7d0babf1farmvixl// SimSystemRegister nzcv = SimSystemRegister::DefaultValueFor(NZCV); 84578645f14e122d2b87d907e298cda7e7d0babf1farmvixlclass SimSystemRegister { 85578645f14e122d2b87d907e298cda7e7d0babf1farmvixl public: 86578645f14e122d2b87d907e298cda7e7d0babf1farmvixl // The default constructor represents a register which has no writable bits. 87578645f14e122d2b87d907e298cda7e7d0babf1farmvixl // It is not possible to set its value to anything other than 0. 88578645f14e122d2b87d907e298cda7e7d0babf1farmvixl SimSystemRegister() : value_(0), write_ignore_mask_(0xffffffff) { } 89578645f14e122d2b87d907e298cda7e7d0babf1farmvixl 90578645f14e122d2b87d907e298cda7e7d0babf1farmvixl inline uint32_t RawValue() const { 91578645f14e122d2b87d907e298cda7e7d0babf1farmvixl return value_; 92578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 93578645f14e122d2b87d907e298cda7e7d0babf1farmvixl 94578645f14e122d2b87d907e298cda7e7d0babf1farmvixl inline void SetRawValue(uint32_t new_value) { 95578645f14e122d2b87d907e298cda7e7d0babf1farmvixl value_ = (value_ & write_ignore_mask_) | (new_value & ~write_ignore_mask_); 96578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 97578645f14e122d2b87d907e298cda7e7d0babf1farmvixl 98578645f14e122d2b87d907e298cda7e7d0babf1farmvixl inline uint32_t Bits(int msb, int lsb) const { 99578645f14e122d2b87d907e298cda7e7d0babf1farmvixl return unsigned_bitextract_32(msb, lsb, value_); 100578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 101578645f14e122d2b87d907e298cda7e7d0babf1farmvixl 102578645f14e122d2b87d907e298cda7e7d0babf1farmvixl inline int32_t SignedBits(int msb, int lsb) const { 103578645f14e122d2b87d907e298cda7e7d0babf1farmvixl return signed_bitextract_32(msb, lsb, value_); 104578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 105578645f14e122d2b87d907e298cda7e7d0babf1farmvixl 106578645f14e122d2b87d907e298cda7e7d0babf1farmvixl void SetBits(int msb, int lsb, uint32_t bits); 107578645f14e122d2b87d907e298cda7e7d0babf1farmvixl 108578645f14e122d2b87d907e298cda7e7d0babf1farmvixl // Default system register values. 109578645f14e122d2b87d907e298cda7e7d0babf1farmvixl static SimSystemRegister DefaultValueFor(SystemRegister id); 110578645f14e122d2b87d907e298cda7e7d0babf1farmvixl 111578645f14e122d2b87d907e298cda7e7d0babf1farmvixl#define DEFINE_GETTER(Name, HighBit, LowBit, Func) \ 112578645f14e122d2b87d907e298cda7e7d0babf1farmvixl inline uint32_t Name() const { return Func(HighBit, LowBit); } \ 113578645f14e122d2b87d907e298cda7e7d0babf1farmvixl inline void Set##Name(uint32_t bits) { SetBits(HighBit, LowBit, bits); } 114578645f14e122d2b87d907e298cda7e7d0babf1farmvixl#define DEFINE_WRITE_IGNORE_MASK(Name, Mask) \ 115578645f14e122d2b87d907e298cda7e7d0babf1farmvixl static const uint32_t Name##WriteIgnoreMask = ~static_cast<uint32_t>(Mask); 116578645f14e122d2b87d907e298cda7e7d0babf1farmvixl 117578645f14e122d2b87d907e298cda7e7d0babf1farmvixl SYSTEM_REGISTER_FIELDS_LIST(DEFINE_GETTER, DEFINE_WRITE_IGNORE_MASK) 118578645f14e122d2b87d907e298cda7e7d0babf1farmvixl 119578645f14e122d2b87d907e298cda7e7d0babf1farmvixl#undef DEFINE_ZERO_BITS 120578645f14e122d2b87d907e298cda7e7d0babf1farmvixl#undef DEFINE_GETTER 121578645f14e122d2b87d907e298cda7e7d0babf1farmvixl 122578645f14e122d2b87d907e298cda7e7d0babf1farmvixl protected: 123578645f14e122d2b87d907e298cda7e7d0babf1farmvixl // Most system registers only implement a few of the bits in the word. Other 124578645f14e122d2b87d907e298cda7e7d0babf1farmvixl // bits are "read-as-zero, write-ignored". The write_ignore_mask argument 125578645f14e122d2b87d907e298cda7e7d0babf1farmvixl // describes the bits which are not modifiable. 126578645f14e122d2b87d907e298cda7e7d0babf1farmvixl SimSystemRegister(uint32_t value, uint32_t write_ignore_mask) 127578645f14e122d2b87d907e298cda7e7d0babf1farmvixl : value_(value), write_ignore_mask_(write_ignore_mask) { } 128578645f14e122d2b87d907e298cda7e7d0babf1farmvixl 129578645f14e122d2b87d907e298cda7e7d0babf1farmvixl uint32_t value_; 130578645f14e122d2b87d907e298cda7e7d0babf1farmvixl uint32_t write_ignore_mask_; 131578645f14e122d2b87d907e298cda7e7d0babf1farmvixl}; 132578645f14e122d2b87d907e298cda7e7d0babf1farmvixl 133578645f14e122d2b87d907e298cda7e7d0babf1farmvixl 134f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl// Represent a register (r0-r31, v0-v31). 135f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixltemplate<int kSizeInBytes> 136f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlclass SimRegisterBase { 137f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl public: 138f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl template<typename T> 139f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl void Set(T new_value, unsigned size = sizeof(T)) { 1401123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(size <= kSizeInBytes); 1411123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(size <= sizeof(new_value)); 142f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl // All AArch64 registers are zero-extending; Writing a W register clears the 143f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl // top bits of the corresponding X register. 144f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl memset(value_, 0, kSizeInBytes); 145f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl memcpy(value_, &new_value, size); 146f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 147f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl 148f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl // Copy 'size' bytes of the register to the result, and zero-extend to fill 149f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl // the result. 150f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl template<typename T> 151f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl T Get(unsigned size = sizeof(T)) const { 1521123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(size <= kSizeInBytes); 153f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl T result; 154f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl memset(&result, 0, sizeof(result)); 155f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl memcpy(&result, value_, size); 156f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl return result; 157f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 158f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl 159f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl protected: 160f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl uint8_t value_[kSizeInBytes]; 161f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl}; 162f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixltypedef SimRegisterBase<kXRegSizeInBytes> SimRegister; // r0-r31 163f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixltypedef SimRegisterBase<kDRegSizeInBytes> SimFPRegister; // v0-v31 164f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl 165f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl 166ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass Simulator : public DecoderVisitor { 167ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public: 168ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl explicit Simulator(Decoder* decoder, FILE* stream = stdout); 169ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ~Simulator(); 170ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 171ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void ResetState(); 172ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 173ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Run the simulator. 174ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl virtual void Run(); 175ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void RunFrom(Instruction* first); 176ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 177ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Simulation helpers. 178ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl inline Instruction* pc() { return pc_; } 179ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl inline void set_pc(Instruction* new_pc) { 180ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl pc_ = new_pc; 181ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl pc_modified_ = true; 182ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 183ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 184ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl inline void increment_pc() { 185ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (!pc_modified_) { 186ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl pc_ = pc_->NextInstruction(); 187ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 188ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 189ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl pc_modified_ = false; 190ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 191ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 192ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl inline void ExecuteInstruction() { 193ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // The program counter should always be aligned. 1941123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(IsWordAligned(pc_)); 195ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl decoder_->Decode(pc_); 196ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl increment_pc(); 197ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 198ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 199ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Declare all Visitor functions. 200ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #define DECLARE(A) void Visit##A(Instruction* instr); 201ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl VISITOR_LIST(DECLARE) 202ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #undef DECLARE 203ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 204ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Register accessors. 205f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl 206f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl // Return 'size' bits of the value of an integer register, as the specified 207f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl // type. The value is zero-extended to fill the result. 208f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl // 209f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl // The only supported values of 'size' are kXRegSize and kWRegSize. 210f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl template<typename T> 211f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl inline T reg(unsigned size, unsigned code, 212f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl Reg31Mode r31mode = Reg31IsZeroRegister) const { 213f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl unsigned size_in_bytes = size / 8; 2141123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(size_in_bytes <= sizeof(T)); 2151123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT((size == kXRegSize) || (size == kWRegSize)); 2161123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(code < kNumberOfRegisters); 217f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl 218ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if ((code == 31) && (r31mode == Reg31IsZeroRegister)) { 219f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl T result; 220f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl memset(&result, 0, sizeof(result)); 221f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl return result; 222ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 223f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl return registers_[code].Get<T>(size_in_bytes); 224f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 225f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl 226f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl // Like reg(), but infer the access size from the template type. 227f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl template<typename T> 228f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl inline T reg(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister) const { 229f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl return reg<T>(sizeof(T) * 8, code, r31mode); 230f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 231f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl 232f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl // Common specialized accessors for the reg() template. 233f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl inline int32_t wreg(unsigned code, 234f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl Reg31Mode r31mode = Reg31IsZeroRegister) const { 235f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl return reg<int32_t>(code, r31mode); 236ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 237ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 238ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl inline int64_t xreg(unsigned code, 239ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Reg31Mode r31mode = Reg31IsZeroRegister) const { 240f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl return reg<int64_t>(code, r31mode); 241f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 242f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl 243f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl inline int64_t reg(unsigned size, unsigned code, 244f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl Reg31Mode r31mode = Reg31IsZeroRegister) const { 245f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl return reg<int64_t>(size, code, r31mode); 246f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 247f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl 248f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl // Write 'size' bits of 'value' into an integer register. The value is 249f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl // zero-extended. This behaviour matches AArch64 register writes. 250f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl // 251f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl // The only supported values of 'size' are kXRegSize and kWRegSize. 252f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl template<typename T> 253f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl inline void set_reg(unsigned size, unsigned code, T value, 254f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl Reg31Mode r31mode = Reg31IsZeroRegister) { 255f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl unsigned size_in_bytes = size / 8; 2561123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(size_in_bytes <= sizeof(T)); 2571123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT((size == kXRegSize) || (size == kWRegSize)); 2581123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(code < kNumberOfRegisters); 259f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl 260ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if ((code == 31) && (r31mode == Reg31IsZeroRegister)) { 261f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl return; 262ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 263f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl return registers_[code].Set(value, size_in_bytes); 264ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 265ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 266f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl // Like set_reg(), but infer the access size from the template type. 267f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl template<typename T> 268f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl inline void set_reg(unsigned code, T value, 269f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl Reg31Mode r31mode = Reg31IsZeroRegister) { 270f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl set_reg(sizeof(value) * 8, code, value, r31mode); 271ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 272ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 273f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl // Common specialized accessors for the set_reg() template. 274ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl inline void set_wreg(unsigned code, int32_t value, 275ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Reg31Mode r31mode = Reg31IsZeroRegister) { 276f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl set_reg(kWRegSize, code, value, r31mode); 277ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 278ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 279ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl inline void set_xreg(unsigned code, int64_t value, 280ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Reg31Mode r31mode = Reg31IsZeroRegister) { 281f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl set_reg(kXRegSize, code, value, r31mode); 282ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 283ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 284f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl // Commonly-used special cases. 285f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl template<typename T> 286f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl inline void set_lr(T value) { 287f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl set_reg(kLinkRegCode, value); 288ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 289ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 290f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl template<typename T> 291f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl inline void set_sp(T value) { 2929b9674a6dd7b5f23d73a5432b74affe4bc380c31Serban Constantinescu set_reg(31, value, Reg31IsStackPointer); 293f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 294ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 295f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl // Return 'size' bits of the value of a floating-point register, as the 296f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl // specified type. The value is zero-extended to fill the result. 297f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl // 298f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl // The only supported values of 'size' are kDRegSize and kSRegSize. 299f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl template<typename T> 300f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl inline T fpreg(unsigned size, unsigned code) const { 301f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl unsigned size_in_bytes = size / 8; 3021123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(size_in_bytes <= sizeof(T)); 3031123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT((size == kDRegSize) || (size == kSRegSize)); 3041123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(code < kNumberOfFPRegisters); 305f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl return fpregisters_[code].Get<T>(size_in_bytes); 306ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 307f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl 308f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl // Like fpreg(), but infer the access size from the template type. 309f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl template<typename T> 310f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl inline T fpreg(unsigned code) const { 311f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl return fpreg<T>(sizeof(T) * 8, code); 312ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 313ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 314f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl // Common specialized accessors for the fpreg() template. 315ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl inline float sreg(unsigned code) const { 316f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl return fpreg<float>(code); 317ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 318ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 319ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl inline uint32_t sreg_bits(unsigned code) const { 320f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl return fpreg<uint32_t>(code); 321ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 322ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 323ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl inline double dreg(unsigned code) const { 324f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl return fpreg<double>(code); 325ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 326ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 327ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl inline uint64_t dreg_bits(unsigned code) const { 328f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl return fpreg<uint64_t>(code); 329ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 330ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 331ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl inline double fpreg(unsigned size, unsigned code) const { 332ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (size) { 333ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case kSRegSize: return sreg(code); 334ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case kDRegSize: return dreg(code); 335f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl default: 3361123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_UNREACHABLE(); 337ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 0.0; 338ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 339ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 340ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 341f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl // Write 'value' into a floating-point register. The value is zero-extended. 342f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl // This behaviour matches AArch64 register writes. 343f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl template<typename T> 344f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl inline void set_fpreg(unsigned code, T value) { 3451123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT((sizeof(value) == kDRegSizeInBytes) || 346f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl (sizeof(value) == kSRegSizeInBytes)); 3471123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(code < kNumberOfFPRegisters); 348f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl fpregisters_[code].Set(value, sizeof(value)); 349ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 350ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 351f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl // Common specialized accessors for the set_fpreg() template. 352f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl inline void set_sreg(unsigned code, float value) { 353f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl set_fpreg(code, value); 354ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 355ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 356f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl inline void set_sreg_bits(unsigned code, uint32_t value) { 357f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl set_fpreg(code, value); 358ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 359ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 360f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl inline void set_dreg(unsigned code, double value) { 361f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl set_fpreg(code, value); 362ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 363ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 364f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl inline void set_dreg_bits(unsigned code, uint64_t value) { 365f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl set_fpreg(code, value); 366ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 367ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 368578645f14e122d2b87d907e298cda7e7d0babf1farmvixl bool N() { return nzcv_.N() != 0; } 369578645f14e122d2b87d907e298cda7e7d0babf1farmvixl bool Z() { return nzcv_.Z() != 0; } 370578645f14e122d2b87d907e298cda7e7d0babf1farmvixl bool C() { return nzcv_.C() != 0; } 371578645f14e122d2b87d907e298cda7e7d0babf1farmvixl bool V() { return nzcv_.V() != 0; } 372578645f14e122d2b87d907e298cda7e7d0babf1farmvixl SimSystemRegister& nzcv() { return nzcv_; } 373578645f14e122d2b87d907e298cda7e7d0babf1farmvixl 374578645f14e122d2b87d907e298cda7e7d0babf1farmvixl // TODO(jbramley): Find a way to make the fpcr_ members return the proper 3751123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // types, so these accessors are not necessary. 376578645f14e122d2b87d907e298cda7e7d0babf1farmvixl FPRounding RMode() { return static_cast<FPRounding>(fpcr_.RMode()); } 3771123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl bool DN() { return fpcr_.DN() != 0; } 378578645f14e122d2b87d907e298cda7e7d0babf1farmvixl SimSystemRegister& fpcr() { return fpcr_; } 379ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 380ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Debug helpers 381578645f14e122d2b87d907e298cda7e7d0babf1farmvixl void PrintSystemRegisters(bool print_all = false); 382ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void PrintRegisters(bool print_all_regs = false); 383ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void PrintFPRegisters(bool print_all_regs = false); 384ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void PrintProcessorState(); 385ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 386ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static const char* WRegNameForCode(unsigned code, 387ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Reg31Mode mode = Reg31IsZeroRegister); 388ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static const char* XRegNameForCode(unsigned code, 389ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Reg31Mode mode = Reg31IsZeroRegister); 390ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static const char* SRegNameForCode(unsigned code); 391ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static const char* DRegNameForCode(unsigned code); 392ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static const char* VRegNameForCode(unsigned code); 393ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 394ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl inline bool coloured_trace() { return coloured_trace_; } 3951123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl void set_coloured_trace(bool value); 396ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 397ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl inline bool disasm_trace() { return disasm_trace_; } 398ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl inline void set_disasm_trace(bool value) { 399ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (value != disasm_trace_) { 400ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (value) { 401ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl decoder_->InsertVisitorBefore(print_disasm_, this); 402ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 403ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl decoder_->RemoveVisitor(print_disasm_); 404ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 405ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl disasm_trace_ = value; 406ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 407ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 408578645f14e122d2b87d907e298cda7e7d0babf1farmvixl inline void set_instruction_stats(bool value) { 409578645f14e122d2b87d907e298cda7e7d0babf1farmvixl if (value != instruction_stats_) { 410578645f14e122d2b87d907e298cda7e7d0babf1farmvixl if (value) { 411578645f14e122d2b87d907e298cda7e7d0babf1farmvixl decoder_->AppendVisitor(instrumentation_); 412578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } else { 413578645f14e122d2b87d907e298cda7e7d0babf1farmvixl decoder_->RemoveVisitor(instrumentation_); 414578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 415578645f14e122d2b87d907e298cda7e7d0babf1farmvixl instruction_stats_ = value; 416578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 417578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 418ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 419ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl protected: 4201123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl const char* clr_normal; 4211123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl const char* clr_flag_name; 4221123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl const char* clr_flag_value; 4231123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl const char* clr_reg_name; 4241123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl const char* clr_reg_value; 4251123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl const char* clr_fpreg_name; 4261123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl const char* clr_fpreg_value; 4271123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl const char* clr_memory_value; 4281123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl const char* clr_memory_address; 4291123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl const char* clr_debug_number; 4301123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl const char* clr_debug_message; 4311123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl const char* clr_printf; 4321123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 433ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Simulation helpers ------------------------------------ 434ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl bool ConditionPassed(Condition cond) { 435ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (cond) { 436ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case eq: 437ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return Z(); 438ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ne: 439ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return !Z(); 440ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case hs: 441ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return C(); 442ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case lo: 443ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return !C(); 444ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case mi: 445ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return N(); 446ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case pl: 447ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return !N(); 448ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case vs: 449ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return V(); 450ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case vc: 451ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return !V(); 452ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case hi: 453ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return C() && !Z(); 454ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ls: 455ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return !(C() && !Z()); 456ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ge: 457ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return N() == V(); 458ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case lt: 459ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return N() != V(); 460ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case gt: 461ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return !Z() && (N() == V()); 462ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case le: 463ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return !(!Z() && (N() == V())); 464578645f14e122d2b87d907e298cda7e7d0babf1farmvixl case nv: // Fall through. 465ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case al: 466ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return true; 467ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: 4681123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_UNREACHABLE(); 469ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return false; 470ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 471ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 472ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 473ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl bool ConditionFailed(Condition cond) { 474ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return !ConditionPassed(cond); 475ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 476ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 477ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void AddSubHelper(Instruction* instr, int64_t op2); 478ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int64_t AddWithCarry(unsigned reg_size, 479ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl bool set_flags, 480ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int64_t src1, 481ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int64_t src2, 482ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int64_t carry_in = 0); 483ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void LogicalHelper(Instruction* instr, int64_t op2); 484ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void ConditionalCompareHelper(Instruction* instr, int64_t op2); 485ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void LoadStoreHelper(Instruction* instr, 486ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int64_t offset, 487ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AddrMode addrmode); 488ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void LoadStorePairHelper(Instruction* instr, AddrMode addrmode); 489ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl uint8_t* AddressModeHelper(unsigned addr_reg, 490ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int64_t offset, 491ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AddrMode addrmode); 492ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 493ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl uint64_t MemoryRead(const uint8_t* address, unsigned num_bytes); 494ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl uint8_t MemoryRead8(uint8_t* address); 495ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl uint16_t MemoryRead16(uint8_t* address); 496ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl uint32_t MemoryRead32(uint8_t* address); 497ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl float MemoryReadFP32(uint8_t* address); 498ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl uint64_t MemoryRead64(uint8_t* address); 499ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl double MemoryReadFP64(uint8_t* address); 500ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 501ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void MemoryWrite(uint8_t* address, uint64_t value, unsigned num_bytes); 502ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void MemoryWrite32(uint8_t* address, uint32_t value); 503ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void MemoryWriteFP32(uint8_t* address, float value); 504ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void MemoryWrite64(uint8_t* address, uint64_t value); 505ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void MemoryWriteFP64(uint8_t* address, double value); 506ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 507ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int64_t ShiftOperand(unsigned reg_size, 508ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int64_t value, 509ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Shift shift_type, 510ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl unsigned amount); 511ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int64_t Rotate(unsigned reg_width, 512ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int64_t value, 513ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Shift shift_type, 514ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl unsigned amount); 515ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int64_t ExtendValue(unsigned reg_width, 516ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int64_t value, 517ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Extend extend_type, 518ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl unsigned left_shift = 0); 519ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 520ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl uint64_t ReverseBits(uint64_t value, unsigned num_bits); 521ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl uint64_t ReverseBytes(uint64_t value, ReverseByteMode mode); 522ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 5231123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl template <typename T> 5241123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl T FPDefaultNaN() const; 5251123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 526ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void FPCompare(double val0, double val1); 527ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl double FPRoundInt(double value, FPRounding round_mode); 528578645f14e122d2b87d907e298cda7e7d0babf1farmvixl double FPToDouble(float value); 529578645f14e122d2b87d907e298cda7e7d0babf1farmvixl float FPToFloat(double value, FPRounding round_mode); 530578645f14e122d2b87d907e298cda7e7d0babf1farmvixl double FixedToDouble(int64_t src, int fbits, FPRounding round_mode); 531578645f14e122d2b87d907e298cda7e7d0babf1farmvixl double UFixedToDouble(uint64_t src, int fbits, FPRounding round_mode); 532578645f14e122d2b87d907e298cda7e7d0babf1farmvixl float FixedToFloat(int64_t src, int fbits, FPRounding round_mode); 533578645f14e122d2b87d907e298cda7e7d0babf1farmvixl float UFixedToFloat(uint64_t src, int fbits, FPRounding round_mode); 534ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int32_t FPToInt32(double value, FPRounding rmode); 535ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int64_t FPToInt64(double value, FPRounding rmode); 536ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl uint32_t FPToUInt32(double value, FPRounding rmode); 537ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl uint64_t FPToUInt64(double value, FPRounding rmode); 538f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl 539f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl template <typename T> 5401123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl T FPAdd(T op1, T op2); 541f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl 542f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl template <typename T> 5431123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl T FPDiv(T op1, T op2); 5441123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 5451123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl template <typename T> 5461123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl T FPMax(T a, T b); 547f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl 548f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl template <typename T> 549f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl T FPMaxNM(T a, T b); 550f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl 551f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl template <typename T> 5521123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl T FPMin(T a, T b); 5531123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 5541123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl template <typename T> 555f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl T FPMinNM(T a, T b); 556ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 5571123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl template <typename T> 5581123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl T FPMul(T op1, T op2); 5591123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 5601123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl template <typename T> 5611123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl T FPMulAdd(T a, T op1, T op2); 5621123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 5631123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl template <typename T> 5641123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl T FPSqrt(T op); 5651123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 5661123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl template <typename T> 5671123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl T FPSub(T op1, T op2); 5681123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 5691123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // This doesn't do anything at the moment. We'll need it if we want support 5701123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // for cumulative exception bits or floating-point exceptions. 5711123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl void FPProcessException() { } 5721123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 5731123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // Standard NaN processing. 5741123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl template <typename T> 5751123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl T FPProcessNaN(T op); 5761123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 5771123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl bool FPProcessNaNs(Instruction* instr); 5781123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 5791123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl template <typename T> 5801123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl T FPProcessNaNs(T op1, T op2); 5811123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 5821123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl template <typename T> 5831123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl T FPProcessNaNs3(T op1, T op2, T op3); 5841123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 585ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Pseudo Printf instruction 586ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void DoPrintf(Instruction* instr); 587ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 588ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Processor state --------------------------------------- 589ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 590ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Output stream. 591ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FILE* stream_; 592ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl PrintDisassembler* print_disasm_; 593ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 594578645f14e122d2b87d907e298cda7e7d0babf1farmvixl // Instruction statistics instrumentation. 595578645f14e122d2b87d907e298cda7e7d0babf1farmvixl Instrument* instrumentation_; 596578645f14e122d2b87d907e298cda7e7d0babf1farmvixl 597ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // General purpose registers. Register 31 is the stack pointer. 598ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl SimRegister registers_[kNumberOfRegisters]; 599ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 600ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Floating point registers 601ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl SimFPRegister fpregisters_[kNumberOfFPRegisters]; 602ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 603ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Program Status Register. 604ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // bits[31, 27]: Condition flags N, Z, C, and V. 605ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // (Negative, Zero, Carry, Overflow) 606578645f14e122d2b87d907e298cda7e7d0babf1farmvixl SimSystemRegister nzcv_; 607578645f14e122d2b87d907e298cda7e7d0babf1farmvixl 608578645f14e122d2b87d907e298cda7e7d0babf1farmvixl // Floating-Point Control Register 609578645f14e122d2b87d907e298cda7e7d0babf1farmvixl SimSystemRegister fpcr_; 610578645f14e122d2b87d907e298cda7e7d0babf1farmvixl 611578645f14e122d2b87d907e298cda7e7d0babf1farmvixl // Only a subset of FPCR features are supported by the simulator. This helper 612578645f14e122d2b87d907e298cda7e7d0babf1farmvixl // checks that the FPCR settings are supported. 613578645f14e122d2b87d907e298cda7e7d0babf1farmvixl // 614578645f14e122d2b87d907e298cda7e7d0babf1farmvixl // This is checked when floating-point instructions are executed, not when 615578645f14e122d2b87d907e298cda7e7d0babf1farmvixl // FPCR is set. This allows generated code to modify FPCR for external 616578645f14e122d2b87d907e298cda7e7d0babf1farmvixl // functions, or to save and restore it when entering and leaving generated 617578645f14e122d2b87d907e298cda7e7d0babf1farmvixl // code. 618578645f14e122d2b87d907e298cda7e7d0babf1farmvixl void AssertSupportedFPCR() { 6191123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(fpcr().FZ() == 0); // No flush-to-zero support. 6201123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(fpcr().RMode() == FPTieEven); // Ties-to-even rounding only. 621578645f14e122d2b87d907e298cda7e7d0babf1farmvixl 622578645f14e122d2b87d907e298cda7e7d0babf1farmvixl // The simulator does not support half-precision operations so fpcr().AHP() 623578645f14e122d2b87d907e298cda7e7d0babf1farmvixl // is irrelevant, and is not checked here. 624578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 625ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 626578645f14e122d2b87d907e298cda7e7d0babf1farmvixl static inline int CalcNFlag(uint64_t result, unsigned reg_size) { 627578645f14e122d2b87d907e298cda7e7d0babf1farmvixl return (result >> (reg_size - 1)) & 1; 628ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 629ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 630578645f14e122d2b87d907e298cda7e7d0babf1farmvixl static inline int CalcZFlag(uint64_t result) { 631578645f14e122d2b87d907e298cda7e7d0babf1farmvixl return result == 0; 632ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 633ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 634ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static const uint32_t kConditionFlagsMask = 0xf0000000; 635ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 636ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Stack 637ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl byte* stack_; 638ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static const int stack_protection_size_ = 256; 639ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // 2 KB stack. 640ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static const int stack_size_ = 2 * 1024 + 2 * stack_protection_size_; 641ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl byte* stack_limit_; 642ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 643ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Decoder* decoder_; 644ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Indicates if the pc has been modified by the instruction and should not be 645ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // automatically incremented. 646ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl bool pc_modified_; 647ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Instruction* pc_; 648ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 649ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static const char* xreg_names[]; 650ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static const char* wreg_names[]; 651ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static const char* sreg_names[]; 652ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static const char* dreg_names[]; 653ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static const char* vreg_names[]; 654ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 655ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static const Instruction* kEndOfSimAddress; 656ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 657ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl private: 658ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl bool coloured_trace_; 659578645f14e122d2b87d907e298cda7e7d0babf1farmvixl 660ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Indicates whether the disassembly trace is active. 661ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl bool disasm_trace_; 662578645f14e122d2b87d907e298cda7e7d0babf1farmvixl 663578645f14e122d2b87d907e298cda7e7d0babf1farmvixl // Indicates whether the instruction instrumentation is active. 664578645f14e122d2b87d907e298cda7e7d0babf1farmvixl bool instruction_stats_; 665ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}; 666ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} // namespace vixl 667ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 668ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#endif // VIXL_A64_SIMULATOR_A64_H_ 669