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