10cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// Copyright 2014, ARM Limited
2ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// All rights reserved.
3ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//
4ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Redistribution and use in source and binary forms, with or without
5ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// modification, are permitted provided that the following conditions are met:
6ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//
7ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//   * Redistributions of source code must retain the above copyright notice,
8ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//     this list of conditions and the following disclaimer.
9ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//   * Redistributions in binary form must reproduce the above copyright notice,
10ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//     this list of conditions and the following disclaimer in the documentation
11ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//     and/or other materials provided with the distribution.
12ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//   * Neither the name of ARM Limited nor the names of its contributors may be
13ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//     used to endorse or promote products derived from this software without
14ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//     specific prior written permission.
15ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//
16ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
27ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#ifndef VIXL_A64_TEST_UTILS_A64_H_
28ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#define VIXL_A64_TEST_UTILS_A64_H_
29ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
304a06316541258e3c058792321295ee36d409f419armvixl#include "test-runner.h"
310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#include "vixl/a64/macro-assembler-a64.h"
320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#include "vixl/a64/simulator-a64.h"
330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#include "vixl/a64/disasm-a64.h"
340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#include "vixl/a64/cpu-a64.h"
35ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
36ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlnamespace vixl {
37ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
384a06316541258e3c058792321295ee36d409f419armvixl// Signalling and quiet NaNs in double format, constructed such that the bottom
394a06316541258e3c058792321295ee36d409f419armvixl// 32 bits look like a signalling or quiet NaN (as appropriate) when interpreted
404a06316541258e3c058792321295ee36d409f419armvixl// as a float. These values are not architecturally significant, but they're
414a06316541258e3c058792321295ee36d409f419armvixl// useful in tests for initialising registers.
424a06316541258e3c058792321295ee36d409f419armvixlextern const double kFP64SignallingNaN;
434a06316541258e3c058792321295ee36d409f419armvixlextern const double kFP64QuietNaN;
444a06316541258e3c058792321295ee36d409f419armvixl
454a06316541258e3c058792321295ee36d409f419armvixl// Signalling and quiet NaNs in float format.
464a06316541258e3c058792321295ee36d409f419armvixlextern const float kFP32SignallingNaN;
474a06316541258e3c058792321295ee36d409f419armvixlextern const float kFP32QuietNaN;
484a06316541258e3c058792321295ee36d409f419armvixl
490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// Structure representing Q registers in a RegisterDump.
500cc8b6ece4b3e757e11a906a81ece292437713abarmvixlstruct vec128_t {
510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t l;
520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t h;
530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl};
540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
55ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// RegisterDump: Object allowing integer, floating point and flags registers
56ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// to be saved to itself for future reference.
57ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass RegisterDump {
58ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public:
59ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  RegisterDump() : completed_(false) {
601123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(sizeof(dump_.d_[0]) == kDRegSizeInBytes);
611123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(sizeof(dump_.s_[0]) == kSRegSizeInBytes);
621123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(sizeof(dump_.d_[0]) == kXRegSizeInBytes);
631123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(sizeof(dump_.s_[0]) == kWRegSizeInBytes);
641123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(sizeof(dump_.x_[0]) == kXRegSizeInBytes);
651123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(sizeof(dump_.w_[0]) == kWRegSizeInBytes);
660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(sizeof(dump_.q_[0]) == kQRegSizeInBytes);
67ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
68ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
69ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // The Dump method generates code to store a snapshot of the register values.
70ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // It needs to be able to use the stack temporarily, and requires that the
71ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // current stack pointer is sp, and is properly aligned.
72ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //
73ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // The dumping code is generated though the given MacroAssembler. No registers
74ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // are corrupted in the process, but the stack is used briefly. The flags will
75ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // be corrupted during this call.
76ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Dump(MacroAssembler* assm);
77ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
78ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Register accessors.
79ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  inline int32_t wreg(unsigned code) const {
80ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    if (code == kSPRegInternalCode) {
81ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      return wspreg();
82ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
831123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(RegAliasesMatch(code));
84ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return dump_.w_[code];
85ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
86ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
87ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  inline int64_t xreg(unsigned code) const {
88ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    if (code == kSPRegInternalCode) {
89ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      return spreg();
90ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
911123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(RegAliasesMatch(code));
92ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return dump_.x_[code];
93ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
94ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
95ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // FPRegister accessors.
96ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  inline uint32_t sreg_bits(unsigned code) const {
971123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(FPRegAliasesMatch(code));
98ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return dump_.s_[code];
99ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
100ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
101ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  inline float sreg(unsigned code) const {
102ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return rawbits_to_float(sreg_bits(code));
103ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
104ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
105ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  inline uint64_t dreg_bits(unsigned code) const {
1061123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(FPRegAliasesMatch(code));
107ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return dump_.d_[code];
108ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
109ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
110ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  inline double dreg(unsigned code) const {
111ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return rawbits_to_double(dreg_bits(code));
112ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
113ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  inline vec128_t qreg(unsigned code) const {
1150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return dump_.q_[code];
1160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
1170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
118ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Stack pointer accessors.
119ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  inline int64_t spreg() const {
1201123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(SPRegAliasesMatch());
121ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return dump_.sp_;
122ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
123ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
124ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  inline int64_t wspreg() const {
1251123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(SPRegAliasesMatch());
126ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return dump_.wsp_;
127ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
128ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
129ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Flags accessors.
130ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  inline uint64_t flags_nzcv() const {
1311123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(IsComplete());
1321123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT((dump_.flags_ & ~Flags_mask) == 0);
133ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return dump_.flags_ & Flags_mask;
134ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
135ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
136ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  inline bool IsComplete() const {
137ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return completed_;
138ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
139ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
140ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl private:
141ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Indicate whether the dump operation has been completed.
142ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  bool completed_;
143ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
144ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Check that the lower 32 bits of x<code> exactly match the 32 bits of
145ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // w<code>. A failure of this test most likely represents a failure in the
146ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // ::Dump method, or a failure in the simulator.
147ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  bool RegAliasesMatch(unsigned code) const {
1481123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(IsComplete());
1491123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(code < kNumberOfRegisters);
150ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return ((dump_.x_[code] & kWRegMask) == dump_.w_[code]);
151ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
152ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
153ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // As RegAliasesMatch, but for the stack pointer.
154ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  bool SPRegAliasesMatch() const {
1551123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(IsComplete());
156ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return ((dump_.sp_ & kWRegMask) == dump_.wsp_);
157ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
158ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
159ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // As RegAliasesMatch, but for floating-point registers.
160ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  bool FPRegAliasesMatch(unsigned code) const {
1611123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(IsComplete());
1621123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(code < kNumberOfFPRegisters);
163ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return (dump_.d_[code] & kSRegMask) == dump_.s_[code];
164ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
165ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
166ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Store all the dumped elements in a simple struct so the implementation can
167ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // use offsetof to quickly find the correct field.
168ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  struct dump_t {
169ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // Core registers.
170ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    uint64_t x_[kNumberOfRegisters];
171ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    uint32_t w_[kNumberOfRegisters];
172ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
173ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // Floating-point registers, as raw bits.
174ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    uint64_t d_[kNumberOfFPRegisters];
175ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    uint32_t s_[kNumberOfFPRegisters];
176ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // Vector registers.
1780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    vec128_t q_[kNumberOfVRegisters];
1790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
180ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // The stack pointer.
181ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    uint64_t sp_;
182ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    uint64_t wsp_;
183ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
184ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // NZCV flags, stored in bits 28 to 31.
185ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // bit[31] : Negative
186ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // bit[30] : Zero
187ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // bit[29] : Carry
188ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // bit[28] : oVerflow
189ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    uint64_t flags_;
190ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  } dump_;
191ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl};
192ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
193ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Some of these methods don't use the RegisterDump argument, but they have to
194ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// accept them so that they can overload those that take register arguments.
195ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool Equal32(uint32_t expected, const RegisterDump*, uint32_t result);
196ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool Equal64(uint64_t expected, const RegisterDump*, uint64_t result);
197ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
198ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool EqualFP32(float expected, const RegisterDump*, float result);
199ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool EqualFP64(double expected, const RegisterDump*, double result);
200ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
201ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool Equal32(uint32_t expected, const RegisterDump* core, const Register& reg);
202ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool Equal64(uint64_t expected, const RegisterDump* core, const Register& reg);
203ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
204ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool EqualFP32(float expected, const RegisterDump* core,
205ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl               const FPRegister& fpreg);
206ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool EqualFP64(double expected, const RegisterDump* core,
207ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl               const FPRegister& fpreg);
208ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
209ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool Equal64(const Register& reg0, const RegisterDump* core,
210ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl             const Register& reg1);
2110cc8b6ece4b3e757e11a906a81ece292437713abarmvixlbool Equal128(uint64_t expected_h, uint64_t expected_l,
2120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              const RegisterDump* core, const VRegister& reg);
213ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
214ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool EqualNzcv(uint32_t expected, uint32_t result);
215ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
216ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool EqualRegisters(const RegisterDump* a, const RegisterDump* b);
217ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
218ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Populate the w, x and r arrays with registers from the 'allowed' mask. The
219ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// r array will be populated with <reg_size>-sized registers,
220ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//
221ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// This allows for tests which use large, parameterized blocks of registers
222ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// (such as the push and pop tests), but where certain registers must be
223ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// avoided as they are used for other purposes.
224ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//
225ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Any of w, x, or r can be NULL if they are not required.
226ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//
227ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// The return value is a RegList indicating which registers were allocated.
228ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlRegList PopulateRegisterArray(Register* w, Register* x, Register* r,
229ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                              int reg_size, int reg_count, RegList allowed);
230ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
231ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// As PopulateRegisterArray, but for floating-point registers.
232ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlRegList PopulateFPRegisterArray(FPRegister* s, FPRegister* d, FPRegister* v,
233ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                int reg_size, int reg_count, RegList allowed);
234ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
235ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Ovewrite the contents of the specified registers. This enables tests to
236ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// check that register contents are written in cases where it's likely that the
237ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// correct outcome could already be stored in the register.
238ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//
239ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// This always overwrites X-sized registers. If tests are operating on W
240ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// registers, a subsequent write into an aliased W register should clear the
241ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// top word anyway, so clobbering the full X registers should make tests more
242ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// rigorous.
243ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Clobber(MacroAssembler* masm, RegList reg_list,
2441123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl             uint64_t const value = 0xfedcba9876543210);
245ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
246ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// As Clobber, but for FP registers.
247ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid ClobberFP(MacroAssembler* masm, RegList reg_list,
248ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl               double const value = kFP64SignallingNaN);
249ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
250ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// As Clobber, but for a CPURegList with either FP or integer registers. When
251ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// using this method, the clobber value is always the default for the basic
252ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Clobber or ClobberFP functions.
253ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Clobber(MacroAssembler* masm, CPURegList reg_list);
254ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
255ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}  // namespace vixl
256ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
257ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#endif  // VIXL_A64_TEST_UTILS_A64_H_
258