1ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Copyright 2013, ARM Limited 2ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// All rights reserved. 3ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// 4ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Redistribution and use in source and binary forms, with or without 5ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// modification, are permitted provided that the following conditions are met: 6ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// 7ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// * Redistributions of source code must retain the above copyright notice, 8ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// this list of conditions and the following disclaimer. 9ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// * Redistributions in binary form must reproduce the above copyright notice, 10ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// this list of conditions and the following disclaimer in the documentation 11ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// and/or other materials provided with the distribution. 12ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// * Neither the name of ARM Limited nor the names of its contributors may be 13ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// used to endorse or promote products derived from this software without 14ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// specific prior written permission. 15ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// 16ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND 17ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 20ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 27ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#ifndef VIXL_A64_TEST_UTILS_A64_H_ 28ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#define VIXL_A64_TEST_UTILS_A64_H_ 29ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 30ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#include "cctest.h" 31ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#include "a64/macro-assembler-a64.h" 32ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#include "a64/simulator-a64.h" 33ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#include "a64/disasm-a64.h" 34ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#include "a64/cpu-a64.h" 35ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 36ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlnamespace vixl { 37ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 38ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// RegisterDump: Object allowing integer, floating point and flags registers 39ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// to be saved to itself for future reference. 40ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass RegisterDump { 41ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public: 42ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl RegisterDump() : completed_(false) { 431123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(sizeof(dump_.d_[0]) == kDRegSizeInBytes); 441123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(sizeof(dump_.s_[0]) == kSRegSizeInBytes); 451123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(sizeof(dump_.d_[0]) == kXRegSizeInBytes); 461123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(sizeof(dump_.s_[0]) == kWRegSizeInBytes); 471123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(sizeof(dump_.x_[0]) == kXRegSizeInBytes); 481123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(sizeof(dump_.w_[0]) == kWRegSizeInBytes); 49ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 50ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 51ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // The Dump method generates code to store a snapshot of the register values. 52ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // It needs to be able to use the stack temporarily, and requires that the 53ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // current stack pointer is sp, and is properly aligned. 54ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // 55ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // The dumping code is generated though the given MacroAssembler. No registers 56ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // are corrupted in the process, but the stack is used briefly. The flags will 57ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // be corrupted during this call. 58ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl void Dump(MacroAssembler* assm); 59ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 60ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Register accessors. 61ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl inline int32_t wreg(unsigned code) const { 62ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (code == kSPRegInternalCode) { 63ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return wspreg(); 64ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 651123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(RegAliasesMatch(code)); 66ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return dump_.w_[code]; 67ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 68ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 69ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl inline int64_t xreg(unsigned code) const { 70ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (code == kSPRegInternalCode) { 71ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return spreg(); 72ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 731123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(RegAliasesMatch(code)); 74ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return dump_.x_[code]; 75ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 76ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 77ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // FPRegister accessors. 78ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl inline uint32_t sreg_bits(unsigned code) const { 791123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(FPRegAliasesMatch(code)); 80ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return dump_.s_[code]; 81ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 82ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 83ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl inline float sreg(unsigned code) const { 84ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return rawbits_to_float(sreg_bits(code)); 85ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 86ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 87ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl inline uint64_t dreg_bits(unsigned code) const { 881123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(FPRegAliasesMatch(code)); 89ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return dump_.d_[code]; 90ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 91ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 92ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl inline double dreg(unsigned code) const { 93ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return rawbits_to_double(dreg_bits(code)); 94ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 95ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 96ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Stack pointer accessors. 97ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl inline int64_t spreg() const { 981123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(SPRegAliasesMatch()); 99ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return dump_.sp_; 100ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 101ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 102ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl inline int64_t wspreg() const { 1031123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(SPRegAliasesMatch()); 104ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return dump_.wsp_; 105ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 106ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 107ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Flags accessors. 108ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl inline uint64_t flags_nzcv() const { 1091123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(IsComplete()); 1101123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT((dump_.flags_ & ~Flags_mask) == 0); 111ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return dump_.flags_ & Flags_mask; 112ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 113ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 114ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl inline bool IsComplete() const { 115ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return completed_; 116ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 117ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 118ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl private: 119ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Indicate whether the dump operation has been completed. 120ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl bool completed_; 121ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 122ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Check that the lower 32 bits of x<code> exactly match the 32 bits of 123ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // w<code>. A failure of this test most likely represents a failure in the 124ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // ::Dump method, or a failure in the simulator. 125ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl bool RegAliasesMatch(unsigned code) const { 1261123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(IsComplete()); 1271123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(code < kNumberOfRegisters); 128ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return ((dump_.x_[code] & kWRegMask) == dump_.w_[code]); 129ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 130ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 131ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // As RegAliasesMatch, but for the stack pointer. 132ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl bool SPRegAliasesMatch() const { 1331123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(IsComplete()); 134ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return ((dump_.sp_ & kWRegMask) == dump_.wsp_); 135ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 136ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 137ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // As RegAliasesMatch, but for floating-point registers. 138ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl bool FPRegAliasesMatch(unsigned code) const { 1391123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(IsComplete()); 1401123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(code < kNumberOfFPRegisters); 141ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return (dump_.d_[code] & kSRegMask) == dump_.s_[code]; 142ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 143ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 144ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Store all the dumped elements in a simple struct so the implementation can 145ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // use offsetof to quickly find the correct field. 146ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl struct dump_t { 147ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Core registers. 148ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl uint64_t x_[kNumberOfRegisters]; 149ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl uint32_t w_[kNumberOfRegisters]; 150ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 151ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Floating-point registers, as raw bits. 152ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl uint64_t d_[kNumberOfFPRegisters]; 153ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl uint32_t s_[kNumberOfFPRegisters]; 154ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 155ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // The stack pointer. 156ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl uint64_t sp_; 157ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl uint64_t wsp_; 158ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 159ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // NZCV flags, stored in bits 28 to 31. 160ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // bit[31] : Negative 161ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // bit[30] : Zero 162ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // bit[29] : Carry 163ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // bit[28] : oVerflow 164ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl uint64_t flags_; 165ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } dump_; 166ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}; 167ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 168ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Some of these methods don't use the RegisterDump argument, but they have to 169ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// accept them so that they can overload those that take register arguments. 170ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool Equal32(uint32_t expected, const RegisterDump*, uint32_t result); 171ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool Equal64(uint64_t expected, const RegisterDump*, uint64_t result); 172ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 173ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool EqualFP32(float expected, const RegisterDump*, float result); 174ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool EqualFP64(double expected, const RegisterDump*, double result); 175ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 176ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool Equal32(uint32_t expected, const RegisterDump* core, const Register& reg); 177ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool Equal64(uint64_t expected, const RegisterDump* core, const Register& reg); 178ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 179ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool EqualFP32(float expected, const RegisterDump* core, 180ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const FPRegister& fpreg); 181ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool EqualFP64(double expected, const RegisterDump* core, 182ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const FPRegister& fpreg); 183ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 184ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool Equal64(const Register& reg0, const RegisterDump* core, 185ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& reg1); 186ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 187ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool EqualNzcv(uint32_t expected, uint32_t result); 188ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 189ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool EqualRegisters(const RegisterDump* a, const RegisterDump* b); 190ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 191ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Populate the w, x and r arrays with registers from the 'allowed' mask. The 192ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// r array will be populated with <reg_size>-sized registers, 193ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// 194ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// This allows for tests which use large, parameterized blocks of registers 195ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// (such as the push and pop tests), but where certain registers must be 196ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// avoided as they are used for other purposes. 197ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// 198ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Any of w, x, or r can be NULL if they are not required. 199ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// 200ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// The return value is a RegList indicating which registers were allocated. 201ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlRegList PopulateRegisterArray(Register* w, Register* x, Register* r, 202ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int reg_size, int reg_count, RegList allowed); 203ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 204ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// As PopulateRegisterArray, but for floating-point registers. 205ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlRegList PopulateFPRegisterArray(FPRegister* s, FPRegister* d, FPRegister* v, 206ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int reg_size, int reg_count, RegList allowed); 207ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 208ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Ovewrite the contents of the specified registers. This enables tests to 209ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// check that register contents are written in cases where it's likely that the 210ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// correct outcome could already be stored in the register. 211ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// 212ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// This always overwrites X-sized registers. If tests are operating on W 213ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// registers, a subsequent write into an aliased W register should clear the 214ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// top word anyway, so clobbering the full X registers should make tests more 215ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// rigorous. 216ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Clobber(MacroAssembler* masm, RegList reg_list, 2171123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl uint64_t const value = 0xfedcba9876543210); 218ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 219ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// As Clobber, but for FP registers. 220ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid ClobberFP(MacroAssembler* masm, RegList reg_list, 221ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl double const value = kFP64SignallingNaN); 222ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 223ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// As Clobber, but for a CPURegList with either FP or integer registers. When 224ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// using this method, the clobber value is always the default for the basic 225ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Clobber or ClobberFP functions. 226ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Clobber(MacroAssembler* masm, CPURegList reg_list); 227ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 228ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 229ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} // namespace vixl 230ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 231ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#endif // VIXL_A64_TEST_UTILS_A64_H_ 232