1b78f13911bfe6eda303e91ef215c87a165aae8aeAlexandre Rames// Copyright 2014, VIXL authors
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 ARM LIMITED AND CONTRIBUTORS "AS IS" AND ANY
17ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// 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 ARM LIMITED BE LIABLE FOR ANY DIRECT, INDIRECT,
20ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
22ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
25ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
271e85b7f2e8ad2bfb233de29405aade635ed207cePierre Langlois#ifdef VIXL_INCLUDE_SIMULATOR_AARCH64
28b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl
29b49bdb7996e603555eba4c8b56c7325e3e737ab6Alexandre Rames#include "debugger-aarch64.h"
30ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
31ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlnamespace vixl {
3288c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisnamespace aarch64 {
33ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
34ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// List of commands supported by the debugger.
350f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl#define DEBUG_COMMAND_LIST(C) \
360f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  C(HelpCommand)              \
370f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  C(ContinueCommand)          \
380f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  C(StepCommand)              \
3980497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames  C(SkipCommand)              \
400f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  C(DisasmCommand)            \
410f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  C(PrintCommand)             \
420f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  C(ExamineCommand)
43ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
44ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Debugger command lines are broken up in token of different type to make
45ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// processing easier later on.
46ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass Token {
47ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public:
48ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  virtual ~Token() {}
49ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
50ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Token type.
51ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  virtual bool IsRegister() const { return false; }
52ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  virtual bool IsFPRegister() const { return false; }
53ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  virtual bool IsIdentifier() const { return false; }
54ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  virtual bool IsAddress() const { return false; }
55ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  virtual bool IsInteger() const { return false; }
56ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  virtual bool IsFormat() const { return false; }
57ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  virtual bool IsUnknown() const { return false; }
58ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Token properties.
59ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  virtual bool CanAddressMemory() const { return false; }
60684cd2a7f5845539b58d0da7e012e39df49ceff0armvixl  virtual uint8_t* ToAddress(Debugger* debugger) const = 0;
61ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  virtual void Print(FILE* out = stdout) const = 0;
62ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
63ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static Token* Tokenize(const char* arg);
64ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl};
65ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
66ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Tokens often hold one value.
670f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixltemplate <typename T>
680f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixlclass ValueToken : public Token {
69ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public:
70ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  explicit ValueToken(T value) : value_(value) {}
71ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  ValueToken() {}
72ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
73ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  T value() const { return value_; }
74ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
753fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  VIXL_NO_RETURN virtual uint8_t* ToAddress(Debugger* debugger) const
763fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois      VIXL_OVERRIDE {
77684cd2a7f5845539b58d0da7e012e39df49ceff0armvixl    USE(debugger);
78684cd2a7f5845539b58d0da7e012e39df49ceff0armvixl    VIXL_ABORT();
79684cd2a7f5845539b58d0da7e012e39df49ceff0armvixl  }
80684cd2a7f5845539b58d0da7e012e39df49ceff0armvixl
81ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl protected:
82ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  T value_;
83ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl};
84ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
85ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Integer registers (X or W) and their aliases.
86ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Format: wn or xn with 0 <= n < 32 or a name in the aliases list.
87ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass RegisterToken : public ValueToken<const Register> {
88ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public:
89ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  explicit RegisterToken(const Register reg)
90ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      : ValueToken<const Register>(reg) {}
91ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
923fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  virtual bool IsRegister() const VIXL_OVERRIDE { return true; }
933fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  virtual bool CanAddressMemory() const VIXL_OVERRIDE {
943fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois    return value().Is64Bits();
953fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  }
963fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  virtual uint8_t* ToAddress(Debugger* debugger) const VIXL_OVERRIDE;
973fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  virtual void Print(FILE* out = stdout) const VIXL_OVERRIDE;
98ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  const char* Name() const;
99ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
100ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static Token* Tokenize(const char* arg);
101ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static RegisterToken* Cast(Token* tok) {
102b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl    VIXL_ASSERT(tok->IsRegister());
103ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return reinterpret_cast<RegisterToken*>(tok);
104ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
105ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
106ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl private:
107ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static const int kMaxAliasNumber = 4;
108ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static const char* kXAliases[kNumberOfRegisters][kMaxAliasNumber];
109ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static const char* kWAliases[kNumberOfRegisters][kMaxAliasNumber];
110ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl};
111ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
112ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Floating point registers (D or S).
113ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Format: sn or dn with 0 <= n < 32.
114ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass FPRegisterToken : public ValueToken<const FPRegister> {
115ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public:
116ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  explicit FPRegisterToken(const FPRegister fpreg)
117ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      : ValueToken<const FPRegister>(fpreg) {}
118ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1193fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  virtual bool IsFPRegister() const VIXL_OVERRIDE { return true; }
1203fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  virtual void Print(FILE* out = stdout) const VIXL_OVERRIDE;
121ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
122ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static Token* Tokenize(const char* arg);
123ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static FPRegisterToken* Cast(Token* tok) {
124b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl    VIXL_ASSERT(tok->IsFPRegister());
125ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return reinterpret_cast<FPRegisterToken*>(tok);
126ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
127ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl};
128ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
129ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
130ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Non-register identifiers.
131ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Format: Alphanumeric string starting with a letter.
132ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass IdentifierToken : public ValueToken<char*> {
133ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public:
134ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  explicit IdentifierToken(const char* name) {
135db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl    size_t size = strlen(name) + 1;
136ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    value_ = new char[size];
137ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    strncpy(value_, name, size);
138ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
139ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  virtual ~IdentifierToken() { delete[] value_; }
140ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1413fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  virtual bool IsIdentifier() const VIXL_OVERRIDE { return true; }
1423fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  virtual bool CanAddressMemory() const VIXL_OVERRIDE {
1433fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois    return strcmp(value(), "pc") == 0;
1443fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  }
1453fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  virtual uint8_t* ToAddress(Debugger* debugger) const VIXL_OVERRIDE;
1463fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  virtual void Print(FILE* out = stdout) const VIXL_OVERRIDE;
147ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
148ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static Token* Tokenize(const char* arg);
149ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static IdentifierToken* Cast(Token* tok) {
150b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl    VIXL_ASSERT(tok->IsIdentifier());
151ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return reinterpret_cast<IdentifierToken*>(tok);
152ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
153ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl};
154ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
155ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// 64-bit address literal.
156ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Format: 0x... with up to 16 hexadecimal digits.
157ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass AddressToken : public ValueToken<uint8_t*> {
158ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public:
159ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  explicit AddressToken(uint8_t* address) : ValueToken<uint8_t*>(address) {}
160ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1613fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  virtual bool IsAddress() const VIXL_OVERRIDE { return true; }
1623fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  virtual bool CanAddressMemory() const VIXL_OVERRIDE { return true; }
1633fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  virtual uint8_t* ToAddress(Debugger* debugger) const VIXL_OVERRIDE;
1643fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  virtual void Print(FILE* out = stdout) const VIXL_OVERRIDE;
165ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
166ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static Token* Tokenize(const char* arg);
167ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static AddressToken* Cast(Token* tok) {
168b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl    VIXL_ASSERT(tok->IsAddress());
169ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return reinterpret_cast<AddressToken*>(tok);
170ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
171ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl};
172ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
173ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
174ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// 64-bit decimal integer literal.
175ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Format: n.
176ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass IntegerToken : public ValueToken<int64_t> {
177ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public:
178db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl  explicit IntegerToken(int64_t value) : ValueToken<int64_t>(value) {}
179ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1803fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  virtual bool IsInteger() const VIXL_OVERRIDE { return true; }
1813fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  virtual void Print(FILE* out = stdout) const VIXL_OVERRIDE;
182ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
183ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static Token* Tokenize(const char* arg);
184ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static IntegerToken* Cast(Token* tok) {
185b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl    VIXL_ASSERT(tok->IsInteger());
186ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return reinterpret_cast<IntegerToken*>(tok);
187ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
188ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl};
189ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
190ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Literal describing how to print a chunk of data (up to 64 bits).
191f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl// Format: .ln
192f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl// where l (letter) is one of
193f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl//  * x: hexadecimal
194ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//  * s: signed integer
195ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//  * u: unsigned integer
196f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl//  * f: floating point
197f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl//  * i: instruction
198f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl// and n (size) is one of 8, 16, 32 and 64. n should be omitted for
199f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl// instructions.
200ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass FormatToken : public Token {
201ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public:
202ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  FormatToken() {}
203ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2043fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  virtual bool IsFormat() const VIXL_OVERRIDE { return true; }
205ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  virtual int SizeOf() const = 0;
206be0e12aec9f1e1b55004a3d34f80693bf985017fPierre Langlois  virtual char GetTypeCode() const = 0;
207ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  virtual void PrintData(void* data, FILE* out = stdout) const = 0;
2083fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  virtual void Print(FILE* out = stdout) const VIXL_OVERRIDE = 0;
209ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2103fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  VIXL_NO_RETURN virtual uint8_t* ToAddress(Debugger* debugger) const
2113fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois      VIXL_OVERRIDE {
212684cd2a7f5845539b58d0da7e012e39df49ceff0armvixl    USE(debugger);
213684cd2a7f5845539b58d0da7e012e39df49ceff0armvixl    VIXL_ABORT();
214684cd2a7f5845539b58d0da7e012e39df49ceff0armvixl  }
215684cd2a7f5845539b58d0da7e012e39df49ceff0armvixl
216ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static Token* Tokenize(const char* arg);
217ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static FormatToken* Cast(Token* tok) {
218b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl    VIXL_ASSERT(tok->IsFormat());
219ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return reinterpret_cast<FormatToken*>(tok);
220ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
221ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl};
222ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
223ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2240f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixltemplate <typename T>
2250f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixlclass Format : public FormatToken {
226ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public:
227f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  Format(const char* fmt, char type_code) : fmt_(fmt), type_code_(type_code) {}
228ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2293fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  virtual int SizeOf() const VIXL_OVERRIDE { return sizeof(T); }
2303fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  virtual char GetTypeCode() const VIXL_OVERRIDE { return type_code_; }
2313fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  virtual void PrintData(void* data, FILE* out = stdout) const VIXL_OVERRIDE {
232ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    T value;
233ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    memcpy(&value, data, sizeof(value));
234ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    fprintf(out, fmt_, value);
235ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
2363fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  virtual void Print(FILE* out = stdout) const VIXL_OVERRIDE;
237ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
238ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl private:
239ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  const char* fmt_;
240f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  char type_code_;
241ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl};
242ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
243ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Tokens which don't fit any of the above.
244ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass UnknownToken : public Token {
245ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public:
246ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  explicit UnknownToken(const char* arg) {
247db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl    size_t size = strlen(arg) + 1;
248ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    unknown_ = new char[size];
249ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    strncpy(unknown_, arg, size);
250ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
251ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  virtual ~UnknownToken() { delete[] unknown_; }
2523fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  VIXL_NO_RETURN virtual uint8_t* ToAddress(Debugger* debugger) const
2533fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois      VIXL_OVERRIDE {
254684cd2a7f5845539b58d0da7e012e39df49ceff0armvixl    USE(debugger);
255684cd2a7f5845539b58d0da7e012e39df49ceff0armvixl    VIXL_ABORT();
256684cd2a7f5845539b58d0da7e012e39df49ceff0armvixl  }
257ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2583fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  virtual bool IsUnknown() const VIXL_OVERRIDE { return true; }
2593fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  virtual void Print(FILE* out = stdout) const VIXL_OVERRIDE;
260ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
261ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl private:
262ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  char* unknown_;
263ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl};
264ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
265ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
266ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// All debugger commands must subclass DebugCommand and implement Run, Print
267ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// and Build. Commands must also define kHelp and kAliases.
268ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass DebugCommand {
269ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public:
270ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  explicit DebugCommand(Token* name) : name_(IdentifierToken::Cast(name)) {}
271ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  DebugCommand() : name_(NULL) {}
272ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  virtual ~DebugCommand() { delete name_; }
273ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
274ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  const char* name() { return name_->value(); }
2754886a725301d6cc426c2a8151bb48fbec3946b3aAlexandre Rames  // Run the command on the given debugger.
2764886a725301d6cc426c2a8151bb48fbec3946b3aAlexandre Rames  // Return `true` if control should be given back to the debugger.
2770f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  virtual bool Run(Debugger* debugger) = 0;
278ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  virtual void Print(FILE* out = stdout);
279ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
280ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static bool Match(const char* name, const char** aliases);
281ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static DebugCommand* Parse(char* line);
282ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static void PrintHelp(const char** aliases,
283ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                        const char* args,
284ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                        const char* help);
285ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
286ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl private:
287ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  IdentifierToken* name_;
288ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl};
289ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
290ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// For all commands below see their respective kHelp and kAliases in
291d3832965c62a8ad461b9ea9eb0994ca6b0a3da2cAlexandre Rames// debugger-aarch64.cc
292ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass HelpCommand : public DebugCommand {
293ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public:
294ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  explicit HelpCommand(Token* name) : DebugCommand(name) {}
295ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2963fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  virtual bool Run(Debugger* debugger) VIXL_OVERRIDE;
297ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
298ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static DebugCommand* Build(std::vector<Token*> args);
299ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
300ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static const char* kHelp;
301ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static const char* kAliases[];
302ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static const char* kArguments;
303ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl};
304ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
305ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
306ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass ContinueCommand : public DebugCommand {
307ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public:
308ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  explicit ContinueCommand(Token* name) : DebugCommand(name) {}
309ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
3103fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  virtual bool Run(Debugger* debugger) VIXL_OVERRIDE;
311ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
312ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static DebugCommand* Build(std::vector<Token*> args);
313ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
314ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static const char* kHelp;
315ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static const char* kAliases[];
316ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static const char* kArguments;
317ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl};
318ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
319ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
320ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass StepCommand : public DebugCommand {
321ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public:
322ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  StepCommand(Token* name, IntegerToken* count)
323ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      : DebugCommand(name), count_(count) {}
324ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  virtual ~StepCommand() { delete count_; }
325ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
326ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  int64_t count() { return count_->value(); }
3273fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  virtual bool Run(Debugger* debugger) VIXL_OVERRIDE;
3283fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  virtual void Print(FILE* out = stdout) VIXL_OVERRIDE;
329ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
330ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static DebugCommand* Build(std::vector<Token*> args);
331ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
332ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static const char* kHelp;
333ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static const char* kAliases[];
334ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static const char* kArguments;
335ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
336ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl private:
337ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  IntegerToken* count_;
338ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl};
339ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
34080497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Ramesclass SkipCommand : public DebugCommand {
34180497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames public:
34280497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames  SkipCommand(Token* name, IntegerToken* count)
34380497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames      : DebugCommand(name), count_(count) {}
34480497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames  virtual ~SkipCommand() { delete count_; }
34580497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames
34680497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames  int64_t count() { return count_->value(); }
3473fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  virtual bool Run(Debugger* debugger) VIXL_OVERRIDE;
3483fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  virtual void Print(FILE* out = stdout) VIXL_OVERRIDE;
34980497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames
35080497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames  static DebugCommand* Build(std::vector<Token*> args);
35180497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames
35280497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames  static const char* kHelp;
35380497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames  static const char* kAliases[];
35480497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames  static const char* kArguments;
35580497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames
35680497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames private:
35780497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames  IntegerToken* count_;
35880497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames};
35980497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames
360ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass DisasmCommand : public DebugCommand {
361ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public:
362ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static DebugCommand* Build(std::vector<Token*> args);
363ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
364ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static const char* kHelp;
365ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static const char* kAliases[];
366ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static const char* kArguments;
367ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl};
368ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
369ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
370ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass PrintCommand : public DebugCommand {
371ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public:
372f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  PrintCommand(Token* name, Token* target, FormatToken* format)
373f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      : DebugCommand(name), target_(target), format_(format) {}
374f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  virtual ~PrintCommand() {
375f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    delete target_;
376f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    delete format_;
377f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  }
378ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
379ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Token* target() { return target_; }
380f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  FormatToken* format() { return format_; }
3813fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  virtual bool Run(Debugger* debugger) VIXL_OVERRIDE;
3823fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  virtual void Print(FILE* out = stdout) VIXL_OVERRIDE;
383ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
384ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static DebugCommand* Build(std::vector<Token*> args);
385ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
386ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static const char* kHelp;
387ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static const char* kAliases[];
388ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static const char* kArguments;
389ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
390ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl private:
391ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Token* target_;
392f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  FormatToken* format_;
393ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl};
394ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
395f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlclass ExamineCommand : public DebugCommand {
396ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public:
397f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  ExamineCommand(Token* name,
398f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl                 Token* target,
399f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl                 FormatToken* format,
400f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl                 IntegerToken* count)
401f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      : DebugCommand(name), target_(target), format_(format), count_(count) {}
402f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  virtual ~ExamineCommand() {
403ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    delete target_;
404ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    delete format_;
405f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    delete count_;
406ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
407ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
408ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Token* target() { return target_; }
409ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  FormatToken* format() { return format_; }
410f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  IntegerToken* count() { return count_; }
4113fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  virtual bool Run(Debugger* debugger) VIXL_OVERRIDE;
4123fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  virtual void Print(FILE* out = stdout) VIXL_OVERRIDE;
413ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
414ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static DebugCommand* Build(std::vector<Token*> args);
415ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
416ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static const char* kHelp;
417ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static const char* kAliases[];
418ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static const char* kArguments;
419ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
420ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl private:
421ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Token* target_;
422ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  FormatToken* format_;
423f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  IntegerToken* count_;
424ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl};
425ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
426ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Commands which name does not match any of the known commnand.
427ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass UnknownCommand : public DebugCommand {
428ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public:
429ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  explicit UnknownCommand(std::vector<Token*> args) : args_(args) {}
430ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  virtual ~UnknownCommand();
431ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
4323fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  virtual bool Run(Debugger* debugger) VIXL_OVERRIDE;
433ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
434ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl private:
435ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  std::vector<Token*> args_;
436ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl};
437ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
438ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Commands which name match a known command but the syntax is invalid.
439ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass InvalidCommand : public DebugCommand {
440ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public:
441ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  InvalidCommand(std::vector<Token*> args, int index, const char* cause)
442ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      : args_(args), index_(index), cause_(cause) {}
443ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  virtual ~InvalidCommand();
444ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
4453fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  virtual bool Run(Debugger* debugger) VIXL_OVERRIDE;
446ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
447ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl private:
448ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  std::vector<Token*> args_;
449ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  int index_;
450ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  const char* cause_;
451ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl};
452ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
4530f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixlconst char* HelpCommand::kAliases[] = {"help", NULL};
454ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlconst char* HelpCommand::kArguments = NULL;
455f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlconst char* HelpCommand::kHelp = "  Print this help.";
456ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
4570f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixlconst char* ContinueCommand::kAliases[] = {"continue", "c", NULL};
458ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlconst char* ContinueCommand::kArguments = NULL;
459f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlconst char* ContinueCommand::kHelp = "  Resume execution.";
460ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
4610f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixlconst char* StepCommand::kAliases[] = {"stepi", "si", NULL};
462ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlconst char* StepCommand::kArguments = "[n = 1]";
463f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlconst char* StepCommand::kHelp = "  Execute n next instruction(s).";
464ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
46580497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Ramesconst char* SkipCommand::kAliases[] = {"skip", NULL};
46680497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Ramesconst char* SkipCommand::kArguments = "[n = 1]";
46780497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Ramesconst char* SkipCommand::kHelp = "  Skip the next n instruction(s).";
46880497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames
4690f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixlconst char* DisasmCommand::kAliases[] = {"disasm", "di", NULL};
470f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlconst char* DisasmCommand::kArguments = "[n = 10]";
471ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlconst char* DisasmCommand::kHelp =
4720f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    "  Disassemble n instruction(s) at pc.\n"
4730f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    "  This command is equivalent to x pc.i [n = 10].";
474ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
4750f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixlconst char* PrintCommand::kAliases[] = {"print", "p", NULL};
4760f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixlconst char* PrintCommand::kArguments = "<entity>[.format]";
477ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlconst char* PrintCommand::kHelp =
4780f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    "  Print the given entity according to the given format.\n"
4790f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    "  The format parameter only affects individual registers; it is ignored\n"
4800f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    "  for other entities.\n"
4810f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    "  <entity> can be one of the following:\n"
4820f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    "   * A register name (such as x0, s1, ...).\n"
4830f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    "   * 'regs', to print all integer (W and X) registers.\n"
4840f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    "   * 'fpregs' to print all floating-point (S and D) registers.\n"
4850f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    "   * 'sysregs' to print all system registers (including NZCV).\n"
4860f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    "   * 'pc' to print the current program counter.\n";
4870f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl
4880f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixlconst char* ExamineCommand::kAliases[] = {"m", "mem", "x", NULL};
489f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlconst char* ExamineCommand::kArguments = "<addr>[.format] [n = 10]";
490f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlconst char* ExamineCommand::kHelp =
4910f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    "  Examine memory. Print n items of memory at address <addr> according to\n"
4920f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    "  the given [.format].\n"
4930f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    "  Addr can be an immediate address, a register name or pc.\n"
4940f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    "  Format is made of a type letter: 'x' (hexadecimal), 's' (signed), 'u'\n"
4950f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    "  (unsigned), 'f' (floating point), i (instruction) and a size in bits\n"
4960f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    "  when appropriate (8, 16, 32, 64)\n"
4970f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    "  E.g 'x sp.x64' will print 10 64-bit words from the stack in\n"
4980f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    "  hexadecimal format.";
4990f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl
5000f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixlconst char* RegisterToken::kXAliases[kNumberOfRegisters][kMaxAliasNumber] =
5010f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    {{"x0", NULL},
5020f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"x1", NULL},
5030f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"x2", NULL},
5040f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"x3", NULL},
5050f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"x4", NULL},
5060f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"x5", NULL},
5070f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"x6", NULL},
5080f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"x7", NULL},
5090f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"x8", NULL},
5100f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"x9", NULL},
5110f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"x10", NULL},
5120f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"x11", NULL},
5130f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"x12", NULL},
5140f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"x13", NULL},
5150f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"x14", NULL},
5160f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"x15", NULL},
5170f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"ip0", "x16", NULL},
5180f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"ip1", "x17", NULL},
5190f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"x18", "pr", NULL},
5200f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"x19", NULL},
5210f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"x20", NULL},
5220f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"x21", NULL},
5230f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"x22", NULL},
5240f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"x23", NULL},
5250f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"x24", NULL},
5260f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"x25", NULL},
5270f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"x26", NULL},
5280f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"x27", NULL},
5290f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"x28", NULL},
5300f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"fp", "x29", NULL},
5310f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"lr", "x30", NULL},
5320f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"sp", NULL}};
5330f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl
5340f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixlconst char* RegisterToken::kWAliases[kNumberOfRegisters][kMaxAliasNumber] =
5350f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    {{"w0", NULL},
5360f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"w1", NULL},
5370f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"w2", NULL},
5380f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"w3", NULL},
5390f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"w4", NULL},
5400f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"w5", NULL},
5410f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"w6", NULL},
5420f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"w7", NULL},
5430f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"w8", NULL},
5440f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"w9", NULL},
5450f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"w10", NULL},
5460f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"w11", NULL},
5470f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"w12", NULL},
5480f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"w13", NULL},
5490f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"w14", NULL},
5500f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"w15", NULL},
5510f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"w16", NULL},
5520f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"w17", NULL},
5530f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"w18", NULL},
5540f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"w19", NULL},
5550f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"w20", NULL},
5560f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"w21", NULL},
5570f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"w22", NULL},
5580f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"w23", NULL},
5590f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"w24", NULL},
5600f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"w25", NULL},
5610f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"w26", NULL},
5620f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"w27", NULL},
5630f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"w28", NULL},
5640f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"w29", NULL},
5650f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"w30", NULL},
5660f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl     {"wsp", NULL}};
567ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
568ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
569ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlDebugger::Debugger(Decoder* decoder, FILE* stream)
570ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    : Simulator(decoder, stream),
5710d68001a97c8b59c52fab68fddd46e8591bec15eAlexandre Rames      debugger_active_(false),
572ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      steps_(0),
573ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      last_command_(NULL) {
574ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  disasm_ = new PrintDisassembler(stdout);
575ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  printer_ = new Decoder();
576ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  printer_->AppendVisitor(disasm_);
577ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
578ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
579db6443499376478f5281607a3923e6ffc4c8d8ecarmvixlDebugger::~Debugger() {
580db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl  delete disasm_;
581db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl  delete printer_;
582db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl}
583db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl
584ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
585ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Debugger::Run() {
5860f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  // Flush any written registers before executing anything, so that
5870f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  // manually-set registers are logged _before_ the first instruction.
5880f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  LogAllWrittenRegisters();
5890f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl
590ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  while (pc_ != kEndOfSimAddress) {
5910d68001a97c8b59c52fab68fddd46e8591bec15eAlexandre Rames    if (IsDebuggerActive()) RunDebuggerShell();
592ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    ExecuteInstruction();
593ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
594ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
595ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
596ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
59780497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Ramesvoid Debugger::PrintInstructions(const void* address,
59880497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames                                 int64_t count,
59980497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames                                 const char* prefix) {
600ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (count == 0) {
601ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return;
602ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
603ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
604c68cb64496485710cdb5b8480f8fee287058c93farmvixl  const Instruction* from = Instruction::CastConst(address);
605ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (count < 0) {
606ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    count = -count;
607ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    from -= (count - 1) * kInstructionSize;
608ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
609c68cb64496485710cdb5b8480f8fee287058c93farmvixl  const Instruction* to = from + count * kInstructionSize;
610ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
6110f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  for (const Instruction* current = from; current < to;
61288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois       current = current->GetNextInstruction()) {
61380497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames    printf("%s", prefix);
614ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    printer_->Decode(current);
615ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
616ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
617ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
618ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
619ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Debugger::PrintMemory(const uint8_t* address,
620f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl                           const FormatToken* format,
621f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl                           int64_t count) {
622ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (count == 0) {
623ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return;
624ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
625ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
626ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  const uint8_t* from = address;
627ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  int size = format->SizeOf();
628ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (count < 0) {
629ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    count = -count;
630ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    from -= (count - 1) * size;
631ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
632ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  const uint8_t* to = from + count * size;
633ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
634ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  for (const uint8_t* current = from; current < to; current += size) {
635f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    if (((current - from) % 8) == 0) {
6360f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      printf("\n%p: ", reinterpret_cast<const void*>(current));
637ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
638ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
6395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t data = Memory::Read<uint64_t>(current);
640ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    format->PrintData(&data);
641ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    printf(" ");
642ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
643ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  printf("\n\n");
644ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
645ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
646ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
647f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlvoid Debugger::PrintRegister(const Register& target_reg,
648f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl                             const char* name,
649f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl                             const FormatToken* format) {
65088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  const uint64_t reg_size = target_reg.GetSizeInBits();
651f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  const uint64_t format_size = format->SizeOf() * 8;
652f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  const uint64_t count = reg_size / format_size;
653f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  const uint64_t mask = 0xffffffffffffffff >> (64 - format_size);
6540f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  const uint64_t reg_value =
65588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois      ReadRegister<uint64_t>(target_reg.GetCode(), Reg31IsStackPointer);
656b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl  VIXL_ASSERT(count > 0);
657f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
658f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  printf("%s = ", name);
659f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  for (uint64_t i = 1; i <= count; i++) {
660f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    uint64_t data = reg_value >> (reg_size - (i * format_size));
661f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    data &= mask;
662f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    format->PrintData(&data);
663f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    printf(" ");
664f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  }
665f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  printf("\n");
666f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl}
667f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
668f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
6695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl// TODO(all): fix this for vector registers.
670f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlvoid Debugger::PrintFPRegister(const FPRegister& target_fpreg,
671f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl                               const FormatToken* format) {
67288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  const unsigned fpreg_size = target_fpreg.GetSizeInBits();
673f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  const uint64_t format_size = format->SizeOf() * 8;
674f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  const uint64_t count = fpreg_size / format_size;
675f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  const uint64_t mask = 0xffffffffffffffff >> (64 - format_size);
67688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  const uint64_t fpreg_value =
67788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois      ReadVRegister<uint64_t>(fpreg_size, target_fpreg.GetCode());
678b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl  VIXL_ASSERT(count > 0);
679f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
680f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  if (target_fpreg.Is32Bits()) {
68188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    printf("s%u = ", target_fpreg.GetCode());
682f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  } else {
68388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    printf("d%u = ", target_fpreg.GetCode());
684f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  }
685f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  for (uint64_t i = 1; i <= count; i++) {
686f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    uint64_t data = fpreg_value >> (fpreg_size - (i * format_size));
687f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    data &= mask;
688f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    format->PrintData(&data);
689f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    printf(" ");
690f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  }
691f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  printf("\n");
692f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl}
693f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
694f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
695c68cb64496485710cdb5b8480f8fee287058c93farmvixlvoid Debugger::VisitException(const Instruction* instr) {
696ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  switch (instr->Mask(ExceptionMask)) {
697ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    case BRK:
698ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      DoBreakpoint(instr);
699ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      return;
7006e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    case HLT:
7016e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      VIXL_FALLTHROUGH();
7020f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    default:
7030f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      Simulator::VisitException(instr);
704ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
705ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
706ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
707ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
708ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Read a command. A command will be at most kMaxDebugShellLine char long and
709ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// ends with '\n\0'.
710ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// TODO: Should this be a utility function?
711ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlchar* Debugger::ReadCommandLine(const char* prompt, char* buffer, int length) {
712ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  int fgets_calls = 0;
713ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  char* end = NULL;
714ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
715ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  printf("%s", prompt);
716ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  fflush(stdout);
717ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
718ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  do {
719ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    if (fgets(buffer, length, stdin) == NULL) {
720ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      printf(" ** Error while reading command. **\n");
721ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      return NULL;
722ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
723ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
724ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    fgets_calls++;
725ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    end = strchr(buffer, '\n');
726ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  } while (end == NULL);
727ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
728ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (fgets_calls != 1) {
729ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    printf(" ** Command too long. **\n");
730ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return NULL;
731ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
732ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
733ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Remove the newline from the end of the command.
734b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl  VIXL_ASSERT(end[1] == '\0');
735b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl  VIXL_ASSERT((end - buffer) < (length - 1));
736ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  end[0] = '\0';
737ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
738ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return buffer;
739ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
740ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
741ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
742ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Debugger::RunDebuggerShell() {
7430d68001a97c8b59c52fab68fddd46e8591bec15eAlexandre Rames  if (IsDebuggerActive()) {
744ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    if (steps_ > 0) {
745ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      // Finish stepping first.
746ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      --steps_;
747ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      return;
748ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
749ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
75080497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames    PrintNextInstruction();
751ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    bool done = false;
752ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    while (!done) {
753ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      char buffer[kMaxDebugShellLine];
754ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      char* line = ReadCommandLine("vixl> ", buffer, kMaxDebugShellLine);
755ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
756ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      if (line == NULL) continue;  // An error occurred.
757ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
758ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      DebugCommand* command = DebugCommand::Parse(line);
759ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      if (command != NULL) {
760ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl        last_command_ = command;
761ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      }
762ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
763ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      if (last_command_ != NULL) {
764ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl        done = last_command_->Run(this);
765ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      } else {
766ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl        printf("No previous command to run!\n");
767ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      }
768ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
769ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
770ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
771ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
772ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
773c68cb64496485710cdb5b8480f8fee287058c93farmvixlvoid Debugger::DoBreakpoint(const Instruction* instr) {
774b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl  VIXL_ASSERT(instr->Mask(ExceptionMask) == BRK);
775ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
776c68cb64496485710cdb5b8480f8fee287058c93farmvixl  printf("Hit breakpoint at pc=%p.\n", reinterpret_cast<const void*>(instr));
7770d68001a97c8b59c52fab68fddd46e8591bec15eAlexandre Rames  ActivateDebugger();
778ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
779ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
780ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
781ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlstatic bool StringToUInt64(uint64_t* value, const char* line, int base = 10) {
782ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  char* endptr = NULL;
783ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  errno = 0;  // Reset errors.
784ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  uint64_t parsed = strtoul(line, &endptr, base);
785ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
786ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (errno == ERANGE) {
787ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // Overflow.
788ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return false;
789ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
790ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
791ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (endptr == line) {
792ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // No digits were parsed.
793ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return false;
794ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
795ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
796ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (*endptr != '\0') {
797ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // Non-digit characters present at the end.
798ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return false;
799ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
800ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
801ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  *value = parsed;
802ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return true;
803ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
804ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
805ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
806ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlstatic bool StringToInt64(int64_t* value, const char* line, int base = 10) {
807ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  char* endptr = NULL;
808ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  errno = 0;  // Reset errors.
809ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  int64_t parsed = strtol(line, &endptr, base);
810ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
811ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (errno == ERANGE) {
812ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // Overflow, undeflow.
813ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return false;
814ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
815ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
816ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (endptr == line) {
817ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // No digits were parsed.
818ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return false;
819ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
820ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
821ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (*endptr != '\0') {
822ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // Non-digit characters present at the end.
823ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return false;
824ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
825ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
826ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  *value = parsed;
827ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return true;
828ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
829ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
830ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
831ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlToken* Token::Tokenize(const char* arg) {
832ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if ((arg == NULL) || (*arg == '\0')) {
833ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return NULL;
834ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
835ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
836ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // The order is important. For example Identifier::Tokenize would consider
837ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // any register to be a valid identifier.
838ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
839ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Token* token = RegisterToken::Tokenize(arg);
840ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (token != NULL) {
841ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return token;
842ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
843ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
844ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  token = FPRegisterToken::Tokenize(arg);
845ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (token != NULL) {
846ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return token;
847ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
848ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
849ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  token = IdentifierToken::Tokenize(arg);
850ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (token != NULL) {
851ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return token;
852ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
853ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
854ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  token = AddressToken::Tokenize(arg);
855ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (token != NULL) {
856ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return token;
857ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
858ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
859ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  token = IntegerToken::Tokenize(arg);
860ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (token != NULL) {
861ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return token;
862ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
863ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
864ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return new UnknownToken(arg);
865ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
866ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
867ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
868ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixluint8_t* RegisterToken::ToAddress(Debugger* debugger) const {
869b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl  VIXL_ASSERT(CanAddressMemory());
87088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  uint64_t reg_value =
87188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois      debugger->ReadXRegister(value().GetCode(), Reg31IsStackPointer);
872ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  uint8_t* address = NULL;
873ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  memcpy(&address, &reg_value, sizeof(address));
874ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return address;
875ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
876ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
877ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
878ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid RegisterToken::Print(FILE* out) const {
879b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl  VIXL_ASSERT(value().IsValid());
880ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  fprintf(out, "[Register %s]", Name());
881ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
882ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
883ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
884ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlconst char* RegisterToken::Name() const {
885ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (value().Is32Bits()) {
88688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return kWAliases[value().GetCode()][0];
887ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  } else {
88888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return kXAliases[value().GetCode()][0];
889ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
890ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
891ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
892ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
893ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlToken* RegisterToken::Tokenize(const char* arg) {
894ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  for (unsigned i = 0; i < kNumberOfRegisters; i++) {
895ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // Is it a X register or alias?
896ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    for (const char** current = kXAliases[i]; *current != NULL; current++) {
897ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      if (strcmp(arg, *current) == 0) {
89888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois        return new RegisterToken(Register::GetXRegFromCode(i));
899ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      }
900ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
901ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
902ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // Is it a W register or alias?
903ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    for (const char** current = kWAliases[i]; *current != NULL; current++) {
904ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      if (strcmp(arg, *current) == 0) {
90588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois        return new RegisterToken(Register::GetWRegFromCode(i));
906ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      }
907ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
908ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
909ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
910ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return NULL;
911ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
912ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
913ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
914ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid FPRegisterToken::Print(FILE* out) const {
915b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl  VIXL_ASSERT(value().IsValid());
916ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  char prefix = value().Is32Bits() ? 's' : 'd';
91788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  fprintf(out, "[FPRegister %c%" PRIu32 "]", prefix, value().GetCode());
918ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
919ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
920ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
921ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlToken* FPRegisterToken::Tokenize(const char* arg) {
922ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (strlen(arg) < 2) {
923ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return NULL;
924ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
925ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
926ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  switch (*arg) {
927ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    case 's':
928ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    case 'd':
929ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      const char* cursor = arg + 1;
930ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      uint64_t code = 0;
931ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      if (!StringToUInt64(&code, cursor)) {
932ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl        return NULL;
933ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      }
934ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
935ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      if (code > kNumberOfFPRegisters) {
936ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl        return NULL;
937ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      }
938ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
9395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      VRegister fpreg = NoVReg;
940ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      switch (*arg) {
941db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl        case 's':
94288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois          fpreg = VRegister::GetSRegFromCode(static_cast<unsigned>(code));
943db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl          break;
944db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl        case 'd':
94588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois          fpreg = VRegister::GetDRegFromCode(static_cast<unsigned>(code));
946db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl          break;
9470f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        default:
9480f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          VIXL_UNREACHABLE();
949ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      }
950ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
951ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      return new FPRegisterToken(fpreg);
952ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
953ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
954ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return NULL;
955ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
956ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
957ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
958ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixluint8_t* IdentifierToken::ToAddress(Debugger* debugger) const {
959b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl  VIXL_ASSERT(CanAddressMemory());
96088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  const Instruction* pc_value = debugger->ReadPc();
961ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  uint8_t* address = NULL;
962ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  memcpy(&address, &pc_value, sizeof(address));
963ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return address;
964ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
965ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
966ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid IdentifierToken::Print(FILE* out) const {
967ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  fprintf(out, "[Identifier %s]", value());
968ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
969ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
970ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
971ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlToken* IdentifierToken::Tokenize(const char* arg) {
972ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (!isalpha(arg[0])) {
973ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return NULL;
974ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
975ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
976ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  const char* cursor = arg + 1;
977ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  while ((*cursor != '\0') && isalnum(*cursor)) {
978ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    ++cursor;
979ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
980ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
981ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (*cursor == '\0') {
982ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return new IdentifierToken(arg);
983ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
984ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
985ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return NULL;
986ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
987ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
988ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
989ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixluint8_t* AddressToken::ToAddress(Debugger* debugger) const {
990ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  USE(debugger);
991ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return value();
992ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
993ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
994ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
995ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid AddressToken::Print(FILE* out) const {
9960f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  fprintf(out, "[Address %p]", reinterpret_cast<const void*>(value()));
997ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
998ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
999ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1000ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlToken* AddressToken::Tokenize(const char* arg) {
1001ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if ((strlen(arg) < 3) || (arg[0] != '0') || (arg[1] != 'x')) {
1002ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return NULL;
1003ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1004ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1005ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  uint64_t ptr = 0;
1006ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (!StringToUInt64(&ptr, arg, 16)) {
1007ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return NULL;
1008ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1009ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1010ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  uint8_t* address = reinterpret_cast<uint8_t*>(ptr);
1011ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return new AddressToken(address);
1012ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1013ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1014ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1015ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid IntegerToken::Print(FILE* out) const {
1016ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  fprintf(out, "[Integer %" PRId64 "]", value());
1017ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1018ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1019ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1020ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlToken* IntegerToken::Tokenize(const char* arg) {
1021ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  int64_t value = 0;
1022ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (!StringToInt64(&value, arg)) {
1023ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return NULL;
1024ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1025ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1026ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return new IntegerToken(value);
1027ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1028ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1029ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1030ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlToken* FormatToken::Tokenize(const char* arg) {
1031db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl  size_t length = strlen(arg);
1032f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  switch (arg[0]) {
1033f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    case 'x':
1034f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    case 's':
1035f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    case 'u':
1036f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    case 'f':
1037f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      if (length == 1) return NULL;
1038f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      break;
1039f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    case 'i':
1040f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      if (length == 1) return new Format<uint32_t>("%08" PRIx32, 'i');
10416e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      VIXL_FALLTHROUGH();
10420f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    default:
10430f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      return NULL;
1044f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  }
1045f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
1046f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  char* endptr = NULL;
1047f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  errno = 0;  // Reset errors.
1048f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  uint64_t count = strtoul(arg + 1, &endptr, 10);
1049f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
1050f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  if (errno != 0) {
1051f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    // Overflow, etc.
1052ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return NULL;
1053ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1054ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1055f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  if (endptr == arg) {
1056f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    // No digits were parsed.
1057ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return NULL;
1058ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1059ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1060f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  if (*endptr != '\0') {
1061f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    // There are unexpected (non-digit) characters after the number.
1062f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    return NULL;
1063ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1064ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1065f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  switch (arg[0]) {
1066f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    case 'x':
1067f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      switch (count) {
10680f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        case 8:
10690f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          return new Format<uint8_t>("%02" PRIx8, 'x');
10700f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        case 16:
10710f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          return new Format<uint16_t>("%04" PRIx16, 'x');
10720f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        case 32:
10730f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          return new Format<uint32_t>("%08" PRIx32, 'x');
10740f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        case 64:
10750f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          return new Format<uint64_t>("%016" PRIx64, 'x');
10760f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        default:
10770f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          return NULL;
1078f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      }
1079ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    case 's':
1080f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      switch (count) {
10810f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        case 8:
10820f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          return new Format<int8_t>("%4" PRId8, 's');
10830f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        case 16:
10840f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          return new Format<int16_t>("%6" PRId16, 's');
10850f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        case 32:
10860f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          return new Format<int32_t>("%11" PRId32, 's');
10870f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        case 64:
10880f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          return new Format<int64_t>("%20" PRId64, 's');
10890f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        default:
10900f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          return NULL;
1091ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      }
1092ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    case 'u':
1093f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      switch (count) {
10940f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        case 8:
10950f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          return new Format<uint8_t>("%3" PRIu8, 'u');
10960f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        case 16:
10970f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          return new Format<uint16_t>("%5" PRIu16, 'u');
10980f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        case 32:
10990f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          return new Format<uint32_t>("%10" PRIu32, 'u');
11000f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        case 64:
11010f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          return new Format<uint64_t>("%20" PRIu64, 'u');
11020f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        default:
11030f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          return NULL;
1104ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      }
1105f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    case 'f':
1106f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      switch (count) {
11070f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        case 32:
11080f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          return new Format<float>("%13g", 'f');
11090f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        case 64:
11100f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          return new Format<double>("%13g", 'f');
11110f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        default:
11120f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          return NULL;
1113ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      }
1114f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    default:
1115b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl      VIXL_UNREACHABLE();
1116f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      return NULL;
1117ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1118ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1119ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1120ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
11210f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixltemplate <typename T>
1122ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Format<T>::Print(FILE* out) const {
1123b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl  unsigned size = sizeof(T) * 8;
1124b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl  fprintf(out, "[Format %c%u - %s]", type_code_, size, fmt_);
1125ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1126ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1127ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1128ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid UnknownToken::Print(FILE* out) const {
1129ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  fprintf(out, "[Unknown %s]", unknown_);
1130ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1131ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1132ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
11330f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixlvoid DebugCommand::Print(FILE* out) { fprintf(out, "%s", name()); }
1134ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1135ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1136ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool DebugCommand::Match(const char* name, const char** aliases) {
1137ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  for (const char** current = aliases; *current != NULL; current++) {
1138ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    if (strcmp(name, *current) == 0) {
11390f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      return true;
1140ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
1141ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1142ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1143ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return false;
1144ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1145ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1146ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1147ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlDebugCommand* DebugCommand::Parse(char* line) {
1148ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  std::vector<Token*> args;
1149ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
11500f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  for (char* chunk = strtok(line, " \t"); chunk != NULL;
1151f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl       chunk = strtok(NULL, " \t")) {
1152f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    char* dot = strchr(chunk, '.');
1153f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    if (dot != NULL) {
1154f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      // 'Token.format'.
1155f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      Token* format = FormatToken::Tokenize(dot + 1);
1156f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      if (format != NULL) {
1157f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl        *dot = '\0';
1158f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl        args.push_back(Token::Tokenize(chunk));
1159f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl        args.push_back(format);
1160f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      } else {
1161f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl        // Error while parsing the format, push the UnknownToken so an error
1162f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl        // can be accurately reported.
1163f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl        args.push_back(Token::Tokenize(chunk));
1164f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      }
1165f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    } else {
1166f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      args.push_back(Token::Tokenize(chunk));
1167f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    }
1168ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1169ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1170ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (args.size() == 0) {
1171ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return NULL;
1172ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1173ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1174ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (!args[0]->IsIdentifier()) {
1175f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    return new InvalidCommand(args, 0, "command name is not valid");
1176ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1177ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1178ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  const char* name = IdentifierToken::Cast(args[0])->value();
11790f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl#define RETURN_IF_MATCH(Command)        \
11800f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  if (Match(name, Command::kAliases)) { \
11810f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    return Command::Build(args);        \
1182ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1183ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  DEBUG_COMMAND_LIST(RETURN_IF_MATCH);
11840f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl#undef RETURN_IF_MATCH
1185ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1186ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return new UnknownCommand(args);
1187ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1188ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1189ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1190ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid DebugCommand::PrintHelp(const char** aliases,
1191ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                             const char* args,
1192ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                             const char* help) {
1193b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl  VIXL_ASSERT(aliases[0] != NULL);
1194b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl  VIXL_ASSERT(help != NULL);
1195ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1196ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  printf("\n----\n\n");
1197ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  for (const char** current = aliases; *current != NULL; current++) {
1198ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    if (args != NULL) {
1199ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      printf("%s %s\n", *current, args);
1200ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    } else {
1201ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      printf("%s\n", *current);
1202ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
1203ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1204ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  printf("\n%s\n", help);
1205ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1206ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1207ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1208ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool HelpCommand::Run(Debugger* debugger) {
12090d68001a97c8b59c52fab68fddd46e8591bec15eAlexandre Rames  VIXL_ASSERT(debugger->IsDebuggerActive());
1210ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  USE(debugger);
1211ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
12120f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl#define PRINT_HELP(Command)                    \
12130f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  DebugCommand::PrintHelp(Command::kAliases,   \
12140f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                          Command::kArguments, \
12150f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                          Command::kHelp);
1216ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  DEBUG_COMMAND_LIST(PRINT_HELP);
12170f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl#undef PRINT_HELP
1218ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  printf("\n----\n\n");
1219ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1220ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return false;
1221ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1222ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1223ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1224ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlDebugCommand* HelpCommand::Build(std::vector<Token*> args) {
1225ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (args.size() != 1) {
1226ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return new InvalidCommand(args, -1, "too many arguments");
1227ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1228ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1229ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return new HelpCommand(args[0]);
1230ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1231ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1232ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1233ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool ContinueCommand::Run(Debugger* debugger) {
12340d68001a97c8b59c52fab68fddd46e8591bec15eAlexandre Rames  VIXL_ASSERT(debugger->IsDebuggerActive());
1235ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
12360d68001a97c8b59c52fab68fddd46e8591bec15eAlexandre Rames  debugger->DeactivateDebugger();
1237ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return true;
1238ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1239ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1240ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1241ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlDebugCommand* ContinueCommand::Build(std::vector<Token*> args) {
1242ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (args.size() != 1) {
1243ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return new InvalidCommand(args, -1, "too many arguments");
1244ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1245ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1246ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return new ContinueCommand(args[0]);
1247ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1248ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1249ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1250ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool StepCommand::Run(Debugger* debugger) {
12510d68001a97c8b59c52fab68fddd46e8591bec15eAlexandre Rames  VIXL_ASSERT(debugger->IsDebuggerActive());
1252ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
12534886a725301d6cc426c2a8151bb48fbec3946b3aAlexandre Rames  // To avoid recursive calls to the debugger shell when hitting breakpoints
12544886a725301d6cc426c2a8151bb48fbec3946b3aAlexandre Rames  // while stepping, stepping is implemented by telling the debugger how many
12554886a725301d6cc426c2a8151bb48fbec3946b3aAlexandre Rames  // instructions to execute before starting the shell again.
1256ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  int64_t steps = count();
12574886a725301d6cc426c2a8151bb48fbec3946b3aAlexandre Rames  if (steps <= 0) {
12584886a725301d6cc426c2a8151bb48fbec3946b3aAlexandre Rames    if (steps < 0) {
12594886a725301d6cc426c2a8151bb48fbec3946b3aAlexandre Rames      printf(" ** invalid value for steps: %" PRId64 " (<0) **\n", steps);
12604886a725301d6cc426c2a8151bb48fbec3946b3aAlexandre Rames    }
12614886a725301d6cc426c2a8151bb48fbec3946b3aAlexandre Rames    // Execute nothing and stay in the shell.
12624886a725301d6cc426c2a8151bb48fbec3946b3aAlexandre Rames    return false;
12634886a725301d6cc426c2a8151bb48fbec3946b3aAlexandre Rames  } else {
126488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    debugger->SetSteps(steps - 1);
12654886a725301d6cc426c2a8151bb48fbec3946b3aAlexandre Rames    // Relinquish control to the debugger. It will execute the next instruction,
12664886a725301d6cc426c2a8151bb48fbec3946b3aAlexandre Rames    // followed by `steps - 1` instructions, before starting the shell again.
12674886a725301d6cc426c2a8151bb48fbec3946b3aAlexandre Rames    // (Unless another breakpoint is hit in the meantime.)
12684886a725301d6cc426c2a8151bb48fbec3946b3aAlexandre Rames    return true;
1269ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1270ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1271ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1272ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1273ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid StepCommand::Print(FILE* out) {
1274ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  fprintf(out, "%s %" PRId64 "", name(), count());
1275ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1276ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1277ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1278ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlDebugCommand* StepCommand::Build(std::vector<Token*> args) {
1279ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  IntegerToken* count = NULL;
1280ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  switch (args.size()) {
1281ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    case 1: {  // step [1]
1282ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      count = new IntegerToken(1);
1283ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      break;
1284ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
1285ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    case 2: {  // step n
1286ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      Token* first = args[1];
1287ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      if (!first->IsInteger()) {
1288ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl        return new InvalidCommand(args, 1, "expects int");
1289ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      }
1290ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      count = IntegerToken::Cast(first);
1291ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      break;
1292ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
1293ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    default:
1294ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      return new InvalidCommand(args, -1, "too many arguments");
1295ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1296ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1297ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return new StepCommand(args[0], count);
1298ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1299ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1300ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
130180497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Ramesbool SkipCommand::Run(Debugger* debugger) {
13020d68001a97c8b59c52fab68fddd46e8591bec15eAlexandre Rames  VIXL_ASSERT(debugger->IsDebuggerActive());
130380497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames
130480497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames  int64_t steps = count();
130580497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames  if (steps < 0) {
130680497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames    printf(" ** invalid value for steps: %" PRId64 " (<0) **\n", steps);
130780497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames  } else {
130880497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames    printf("Skipping over %" PRId64 " instructions:\n", steps);
130980497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames    debugger->PrintInstructions(debugger->ReadPc(), steps, "Skip: ");
131080497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames    debugger->WritePc(debugger->ReadPc() + steps * kInstructionSize);
131180497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames    debugger->PrintNextInstruction();
131280497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames  }
131380497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames
131480497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames  return false;
131580497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames}
131680497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames
131780497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames
131880497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Ramesvoid SkipCommand::Print(FILE* out) {
131980497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames  fprintf(out, "%s %" PRId64 "", name(), count());
132080497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames}
132180497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames
132280497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames
132380497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre RamesDebugCommand* SkipCommand::Build(std::vector<Token*> args) {
132480497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames  IntegerToken* count = NULL;
132580497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames  switch (args.size()) {
132680497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames    case 1: {  // step [1]
132780497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames      count = new IntegerToken(1);
132880497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames      break;
132980497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames    }
133080497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames    case 2: {  // step n
133180497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames      Token* first = args[1];
133280497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames      if (!first->IsInteger()) {
133380497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames        return new InvalidCommand(args, 1, "expects int");
133480497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames      }
133580497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames      count = IntegerToken::Cast(first);
133680497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames      break;
133780497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames    }
133880497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames    default:
133980497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames      return new InvalidCommand(args, -1, "too many arguments");
134080497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames  }
134180497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames
134280497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames  return new SkipCommand(args[0], count);
134380497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames}
134480497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames
134580497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames
1346ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlDebugCommand* DisasmCommand::Build(std::vector<Token*> args) {
1347ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  IntegerToken* count = NULL;
1348ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  switch (args.size()) {
1349f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    case 1: {  // disasm [10]
1350f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      count = new IntegerToken(10);
1351ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      break;
1352ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
1353f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    case 2: {  // disasm n
1354ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      Token* first = args[1];
1355f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      if (!first->IsInteger()) {
1356f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl        return new InvalidCommand(args, 1, "expects int");
1357ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      }
1358f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
1359f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      count = IntegerToken::Cast(first);
1360ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      break;
1361ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
1362ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    default:
1363f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      return new InvalidCommand(args, -1, "too many arguments");
1364ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1365ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1366f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  Token* target = new IdentifierToken("pc");
1367f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  FormatToken* format = new Format<uint32_t>("%08" PRIx32, 'i');
1368f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  return new ExamineCommand(args[0], target, format, count);
1369ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1370ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1371ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1372ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid PrintCommand::Print(FILE* out) {
1373ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  fprintf(out, "%s ", name());
1374ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  target()->Print(out);
1375f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  if (format() != NULL) format()->Print(out);
1376ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1377ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1378ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1379ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool PrintCommand::Run(Debugger* debugger) {
13800d68001a97c8b59c52fab68fddd46e8591bec15eAlexandre Rames  VIXL_ASSERT(debugger->IsDebuggerActive());
1381ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1382ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Token* tok = target();
1383ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (tok->IsIdentifier()) {
1384ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    char* identifier = IdentifierToken::Cast(tok)->value();
1385ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    if (strcmp(identifier, "regs") == 0) {
1386330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl      debugger->PrintRegisters();
1387ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    } else if (strcmp(identifier, "fpregs") == 0) {
13885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      debugger->PrintVRegisters();
1389578645f14e122d2b87d907e298cda7e7d0babf1farmvixl    } else if (strcmp(identifier, "sysregs") == 0) {
1390330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl      debugger->PrintSystemRegisters();
1391ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    } else if (strcmp(identifier, "pc") == 0) {
139288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois      printf("pc = %16p\n", reinterpret_cast<const void*>(debugger->ReadPc()));
1393ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    } else {
1394ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      printf(" ** Unknown identifier to print: %s **\n", identifier);
1395ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
1396ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1397ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return false;
1398ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1399ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1400f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  FormatToken* format_tok = format();
1401b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl  VIXL_ASSERT(format_tok != NULL);
1402be0e12aec9f1e1b55004a3d34f80693bf985017fPierre Langlois  if (format_tok->GetTypeCode() == 'i') {
1403f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    // TODO(all): Add support for instruction disassembly.
1404f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    printf(" ** unsupported format: instructions **\n");
1405f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    return false;
1406f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  }
1407f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
1408ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (tok->IsRegister()) {
1409ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    RegisterToken* reg_tok = RegisterToken::Cast(tok);
1410ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    Register reg = reg_tok->value();
1411f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    debugger->PrintRegister(reg, reg_tok->Name(), format_tok);
1412ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return false;
1413ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1414ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1415ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (tok->IsFPRegister()) {
1416ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    FPRegister fpreg = FPRegisterToken::Cast(tok)->value();
1417f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    debugger->PrintFPRegister(fpreg, format_tok);
1418ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return false;
1419ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1420ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1421b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl  VIXL_UNREACHABLE();
1422ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return false;
1423ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1424ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1425ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1426ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlDebugCommand* PrintCommand::Build(std::vector<Token*> args) {
1427f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  if (args.size() < 2) {
1428f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    return new InvalidCommand(args, -1, "too few arguments");
1429f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  }
1430f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
1431f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  Token* target = args[1];
14320f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  if (!target->IsRegister() && !target->IsFPRegister() &&
1433f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      !target->IsIdentifier()) {
1434f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    return new InvalidCommand(args, 1, "expects reg or identifier");
1435f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  }
1436f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
1437f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  FormatToken* format = NULL;
1438f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  int target_size = 0;
1439f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  if (target->IsRegister()) {
1440f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    Register reg = RegisterToken::Cast(target)->value();
144188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    target_size = reg.GetSizeInBytes();
1442f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  } else if (target->IsFPRegister()) {
1443f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    FPRegister fpreg = FPRegisterToken::Cast(target)->value();
144488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    target_size = fpreg.GetSizeInBytes();
1445f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  }
1446f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  // If the target is an identifier there must be no format. This is checked
1447f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  // in the switch statement below.
1448f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
1449ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  switch (args.size()) {
1450ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    case 2: {
1451f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      if (target->IsRegister()) {
1452f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl        switch (target_size) {
14530f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          case 4:
14540f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl            format = new Format<uint32_t>("%08" PRIx32, 'x');
14550f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl            break;
14560f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          case 8:
14570f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl            format = new Format<uint64_t>("%016" PRIx64, 'x');
14580f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl            break;
14590f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          default:
14600f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl            VIXL_UNREACHABLE();
1461f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl        }
1462f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      } else if (target->IsFPRegister()) {
1463f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl        switch (target_size) {
14640f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          case 4:
14650f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl            format = new Format<float>("%8g", 'f');
14660f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl            break;
14670f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          case 8:
14680f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl            format = new Format<double>("%8g", 'f');
14690f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl            break;
14700f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          default:
14710f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl            VIXL_UNREACHABLE();
1472f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl        }
1473ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      }
1474ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      break;
1475ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
1476f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    case 3: {
1477f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      if (target->IsIdentifier()) {
14780f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        return new InvalidCommand(args,
14790f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                  2,
14800f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                  "format is only allowed with registers");
1481f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      }
1482f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
1483f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      Token* second = args[2];
1484f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      if (!second->IsFormat()) {
1485f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl        return new InvalidCommand(args, 2, "expects format");
1486f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      }
1487f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      format = FormatToken::Cast(second);
1488f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
1489f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      if (format->SizeOf() > target_size) {
1490f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl        return new InvalidCommand(args, 2, "format too wide");
1491f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      }
1492f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
1493f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      break;
1494f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    }
1495ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    default:
1496ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      return new InvalidCommand(args, -1, "too many arguments");
1497ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1498ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1499f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  return new PrintCommand(args[0], target, format);
1500ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1501ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1502ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1503f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlbool ExamineCommand::Run(Debugger* debugger) {
15040d68001a97c8b59c52fab68fddd46e8591bec15eAlexandre Rames  VIXL_ASSERT(debugger->IsDebuggerActive());
1505ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1506ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  uint8_t* address = target()->ToAddress(debugger);
15070f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  int64_t amount = count()->value();
1508be0e12aec9f1e1b55004a3d34f80693bf985017fPierre Langlois  if (format()->GetTypeCode() == 'i') {
1509f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    debugger->PrintInstructions(address, amount);
1510f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  } else {
1511f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    debugger->PrintMemory(address, format(), amount);
1512f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  }
1513ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1514ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return false;
1515ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1516ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1517ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1518f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlvoid ExamineCommand::Print(FILE* out) {
1519ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  fprintf(out, "%s ", name());
1520ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  format()->Print(out);
1521f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  target()->Print(out);
1522ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1523ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1524ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1525f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlDebugCommand* ExamineCommand::Build(std::vector<Token*> args) {
1526ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (args.size() < 2) {
1527ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return new InvalidCommand(args, -1, "too few arguments");
1528ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1529ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1530ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Token* target = args[1];
1531ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (!target->CanAddressMemory()) {
1532ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return new InvalidCommand(args, 1, "expects address");
1533ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1534ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1535f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  FormatToken* format = NULL;
1536f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  IntegerToken* count = NULL;
1537f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
1538ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  switch (args.size()) {
1539f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    case 2: {  // mem addr[.x64] [10]
1540f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      format = new Format<uint64_t>("%016" PRIx64, 'x');
1541f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      count = new IntegerToken(10);
1542ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      break;
1543ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
1544f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    case 3: {  // mem addr.format [10]
1545f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl               // mem addr[.x64] n
1546ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      Token* second = args[2];
1547f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      if (second->IsFormat()) {
1548ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl        format = FormatToken::Cast(second);
1549f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl        count = new IntegerToken(10);
1550f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl        break;
1551f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      } else if (second->IsInteger()) {
1552f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl        format = new Format<uint64_t>("%016" PRIx64, 'x');
1553f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl        count = IntegerToken::Cast(second);
1554ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      } else {
1555f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl        return new InvalidCommand(args, 2, "expects format or integer");
1556ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      }
1557b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl      VIXL_UNREACHABLE();
1558ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      break;
1559ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
1560f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    case 4: {  // mem addr.format n
1561ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      Token* second = args[2];
1562ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      Token* third = args[3];
1563f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      if (!second->IsFormat() || !third->IsInteger()) {
1564f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl        return new InvalidCommand(args, -1, "expects addr[.format] [n]");
1565ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      }
1566f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      format = FormatToken::Cast(second);
1567f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      count = IntegerToken::Cast(third);
1568ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      break;
1569ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
1570ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    default:
1571ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      return new InvalidCommand(args, -1, "too many arguments");
1572ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1573ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1574f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  return new ExamineCommand(args[0], target, format, count);
1575ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1576ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1577ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1578ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlUnknownCommand::~UnknownCommand() {
1579db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl  const size_t size = args_.size();
1580db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl  for (size_t i = 0; i < size; ++i) {
1581ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    delete args_[i];
1582ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1583ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1584ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1585ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1586ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool UnknownCommand::Run(Debugger* debugger) {
15870d68001a97c8b59c52fab68fddd46e8591bec15eAlexandre Rames  VIXL_ASSERT(debugger->IsDebuggerActive());
1588ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  USE(debugger);
1589ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1590ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  printf(" ** Unknown Command:");
1591db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl  const size_t size = args_.size();
1592db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl  for (size_t i = 0; i < size; ++i) {
1593ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    printf(" ");
1594ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    args_[i]->Print(stdout);
1595ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1596ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  printf(" **\n");
1597ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1598ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return false;
1599ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1600ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1601ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1602ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlInvalidCommand::~InvalidCommand() {
1603db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl  const size_t size = args_.size();
1604db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl  for (size_t i = 0; i < size; ++i) {
1605ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    delete args_[i];
1606ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1607ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1608ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1609ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1610ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool InvalidCommand::Run(Debugger* debugger) {
16110d68001a97c8b59c52fab68fddd46e8591bec15eAlexandre Rames  VIXL_ASSERT(debugger->IsDebuggerActive());
1612ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  USE(debugger);
1613ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1614ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  printf(" ** Invalid Command:");
1615db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl  const size_t size = args_.size();
1616db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl  for (size_t i = 0; i < size; ++i) {
1617ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    printf(" ");
1618db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl    if (i == static_cast<size_t>(index_)) {
1619ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      printf(">>");
1620ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      args_[i]->Print(stdout);
1621ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      printf("<<");
1622ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    } else {
1623ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      args_[i]->Print(stdout);
1624ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
1625ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1626ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  printf(" **\n");
1627ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  printf(" ** %s\n", cause_);
1628ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1629ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return false;
1630ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1631ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
163288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}  // namespace aarch64
1633ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}  // namespace vixl
1634b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl
16351e85b7f2e8ad2bfb233de29405aade635ed207cePierre Langlois#endif  // VIXL_INCLUDE_SIMULATOR_AARCH64
1636