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