test-utils-aarch64.cc revision 23703a72b1cd9a49428bcd850429f7be381c1e63
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 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 276e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl#include <cmath> 28ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 29330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl#include "test-runner.h" 30d3832965c62a8ad461b9ea9eb0994ca6b0a3da2cAlexandre Rames#include "test-utils-aarch64.h" 31b68bacb75c1ab265fc539afa93964c7f51f35589Alexandre Rames 32d3832965c62a8ad461b9ea9eb0994ca6b0a3da2cAlexandre Rames#include "aarch64/cpu-aarch64.h" 33d3832965c62a8ad461b9ea9eb0994ca6b0a3da2cAlexandre Rames#include "aarch64/disasm-aarch64.h" 34d3832965c62a8ad461b9ea9eb0994ca6b0a3da2cAlexandre Rames#include "aarch64/macro-assembler-aarch64.h" 35d3832965c62a8ad461b9ea9eb0994ca6b0a3da2cAlexandre Rames#include "aarch64/simulator-aarch64.h" 36ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 37ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#define __ masm-> 38ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 39ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlnamespace vixl { 4088c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisnamespace aarch64 { 41ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 42330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl 43330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl// This value is a signalling NaN as both a double and as a float (taking the 44330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl// least-significant word). 45330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixlconst double kFP64SignallingNaN = 4688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois RawbitsToDouble(UINT64_C(0x7ff000007f800001)); 4788c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisconst float kFP32SignallingNaN = RawbitsToFloat(0x7f800001); 48330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl 49330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl// A similar value, but as a quiet NaN. 5088c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisconst double kFP64QuietNaN = RawbitsToDouble(UINT64_C(0x7ff800007fc00001)); 5188c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisconst float kFP32QuietNaN = RawbitsToFloat(0x7fc00001); 52330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl 53330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl 54ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool Equal32(uint32_t expected, const RegisterDump*, uint32_t result) { 55ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (result != expected) { 56ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl printf("Expected 0x%08" PRIx32 "\t Found 0x%08" PRIx32 "\n", 57ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl expected, result); 58ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 59ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 60ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return expected == result; 61ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 62ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 63ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 64ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool Equal64(uint64_t expected, const RegisterDump*, uint64_t result) { 65ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (result != expected) { 66ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl printf("Expected 0x%016" PRIx64 "\t Found 0x%016" PRIx64 "\n", 67ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl expected, result); 68ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 69ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 70ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return expected == result; 71ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 72ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 73ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlbool Equal128(vec128_t expected, const RegisterDump*, vec128_t result) { 755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl if ((result.h != expected.h) || (result.l != expected.l)) { 765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl printf("Expected 0x%016" PRIx64 "%016" PRIx64 "\t " 775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl "Found 0x%016" PRIx64 "%016" PRIx64 "\n", 785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl expected.h, expected.l, result.h, result.l); 795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl } 805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl 815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl return ((expected.h == result.h) && (expected.l == result.l)); 825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl} 835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl 845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl 85ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool EqualFP32(float expected, const RegisterDump*, float result) { 8688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (FloatToRawbits(expected) == FloatToRawbits(result)) { 87578645f14e122d2b87d907e298cda7e7d0babf1farmvixl return true; 88578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } else { 896e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl if (std::isnan(expected) || (expected == 0.0)) { 90578645f14e122d2b87d907e298cda7e7d0babf1farmvixl printf("Expected 0x%08" PRIx32 "\t Found 0x%08" PRIx32 "\n", 9188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois FloatToRawbits(expected), FloatToRawbits(result)); 92578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } else { 93578645f14e122d2b87d907e298cda7e7d0babf1farmvixl printf("Expected %.9f (0x%08" PRIx32 ")\t " 94578645f14e122d2b87d907e298cda7e7d0babf1farmvixl "Found %.9f (0x%08" PRIx32 ")\n", 9588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois expected, FloatToRawbits(expected), 9688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois result, FloatToRawbits(result)); 97578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 98578645f14e122d2b87d907e298cda7e7d0babf1farmvixl return false; 99ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 100ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 101ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 102ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 103ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool EqualFP64(double expected, const RegisterDump*, double result) { 10488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (DoubleToRawbits(expected) == DoubleToRawbits(result)) { 105578645f14e122d2b87d907e298cda7e7d0babf1farmvixl return true; 106ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 107ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1086e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl if (std::isnan(expected) || (expected == 0.0)) { 109578645f14e122d2b87d907e298cda7e7d0babf1farmvixl printf("Expected 0x%016" PRIx64 "\t Found 0x%016" PRIx64 "\n", 11088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DoubleToRawbits(expected), DoubleToRawbits(result)); 111578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } else { 112578645f14e122d2b87d907e298cda7e7d0babf1farmvixl printf("Expected %.17f (0x%016" PRIx64 ")\t " 113578645f14e122d2b87d907e298cda7e7d0babf1farmvixl "Found %.17f (0x%016" PRIx64 ")\n", 11488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois expected, DoubleToRawbits(expected), 11588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois result, DoubleToRawbits(result)); 116578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 117578645f14e122d2b87d907e298cda7e7d0babf1farmvixl return false; 118ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 119ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 120ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 121ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool Equal32(uint32_t expected, const RegisterDump* core, const Register& reg) { 122b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT(reg.Is32Bits()); 123ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Retrieve the corresponding X register so we can check that the upper part 124ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // was properly cleared. 12588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int64_t result_x = core->xreg(reg.GetCode()); 126b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl if ((result_x & 0xffffffff00000000) != 0) { 127ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl printf("Expected 0x%08" PRIx32 "\t Found 0x%016" PRIx64 "\n", 128ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl expected, result_x); 129ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return false; 130ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 13188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t result_w = core->wreg(reg.GetCode()); 132ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return Equal32(expected, core, result_w); 133ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 134ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 135ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlbool Equal64(uint64_t expected, const RegisterDump* core, const Register& reg) { 137b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT(reg.Is64Bits()); 13888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint64_t result = core->xreg(reg.GetCode()); 139ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return Equal64(expected, core, result); 140ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 141ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 142ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlbool Equal128(uint64_t expected_h, 1445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl uint64_t expected_l, 1455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl const RegisterDump* core, 1465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl const VRegister& vreg) { 1475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl VIXL_ASSERT(vreg.Is128Bits()); 1485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl vec128_t expected = {expected_l, expected_h}; 14988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois vec128_t result = core->qreg(vreg.GetCode()); 1505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl return Equal128(expected, core, result); 1515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl} 1525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl 1535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl 154ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool EqualFP32(float expected, 155ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const RegisterDump* core, 156ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const FPRegister& fpreg) { 157b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT(fpreg.Is32Bits()); 158ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Retrieve the corresponding D register so we can check that the upper part 159ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // was properly cleared. 16088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint64_t result_64 = core->dreg_bits(fpreg.GetCode()); 161b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl if ((result_64 & 0xffffffff00000000) != 0) { 162ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl printf("Expected 0x%08" PRIx32 " (%f)\t Found 0x%016" PRIx64 "\n", 16388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois FloatToRawbits(expected), expected, result_64); 164ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return false; 165ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 166578645f14e122d2b87d907e298cda7e7d0babf1farmvixl 16788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return EqualFP32(expected, core, core->sreg(fpreg.GetCode())); 168ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 169ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 170ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 171ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool EqualFP64(double expected, 172ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const RegisterDump* core, 173ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const FPRegister& fpreg) { 174b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT(fpreg.Is64Bits()); 17588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return EqualFP64(expected, core, core->dreg(fpreg.GetCode())); 176ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 177ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 178ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 179ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool Equal64(const Register& reg0, 180ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const RegisterDump* core, 181ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& reg1) { 182b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT(reg0.Is64Bits() && reg1.Is64Bits()); 18388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int64_t expected = core->xreg(reg0.GetCode()); 18488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int64_t result = core->xreg(reg1.GetCode()); 185ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return Equal64(expected, core, result); 186ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 187ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 188ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 18923703a72b1cd9a49428bcd850429f7be381c1e63Pierre Langloisbool Equal64(uint64_t expected, 19023703a72b1cd9a49428bcd850429f7be381c1e63Pierre Langlois const RegisterDump* core, 19123703a72b1cd9a49428bcd850429f7be381c1e63Pierre Langlois const VRegister& vreg) { 19223703a72b1cd9a49428bcd850429f7be381c1e63Pierre Langlois VIXL_ASSERT(vreg.Is64Bits()); 19323703a72b1cd9a49428bcd850429f7be381c1e63Pierre Langlois uint64_t result = core->dreg_bits(vreg.GetCode()); 19423703a72b1cd9a49428bcd850429f7be381c1e63Pierre Langlois return Equal64(expected, core, result); 19523703a72b1cd9a49428bcd850429f7be381c1e63Pierre Langlois} 19623703a72b1cd9a49428bcd850429f7be381c1e63Pierre Langlois 19723703a72b1cd9a49428bcd850429f7be381c1e63Pierre Langlois 198ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlstatic char FlagN(uint32_t flags) { 199ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return (flags & NFlag) ? 'N' : 'n'; 200ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 201ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 202ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 203ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlstatic char FlagZ(uint32_t flags) { 204ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return (flags & ZFlag) ? 'Z' : 'z'; 205ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 206ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 207ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 208ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlstatic char FlagC(uint32_t flags) { 209ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return (flags & CFlag) ? 'C' : 'c'; 210ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 211ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 212ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 213ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlstatic char FlagV(uint32_t flags) { 214ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return (flags & VFlag) ? 'V' : 'v'; 215ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 216ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 217ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 218ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool EqualNzcv(uint32_t expected, uint32_t result) { 219b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT((expected & ~NZCVFlag) == 0); 220b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT((result & ~NZCVFlag) == 0); 221ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (result != expected) { 222ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl printf("Expected: %c%c%c%c\t Found: %c%c%c%c\n", 223ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FlagN(expected), FlagZ(expected), FlagC(expected), FlagV(expected), 224ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FlagN(result), FlagZ(result), FlagC(result), FlagV(result)); 225578645f14e122d2b87d907e298cda7e7d0babf1farmvixl return false; 226ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 227ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 228578645f14e122d2b87d907e298cda7e7d0babf1farmvixl return true; 229ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 230ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 231ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 232ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool EqualRegisters(const RegisterDump* a, const RegisterDump* b) { 233ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl for (unsigned i = 0; i < kNumberOfRegisters; i++) { 234ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (a->xreg(i) != b->xreg(i)) { 235ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl printf("x%d\t Expected 0x%016" PRIx64 "\t Found 0x%016" PRIx64 "\n", 236ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl i, a->xreg(i), b->xreg(i)); 237ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return false; 238ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 239ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 240ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 241ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl for (unsigned i = 0; i < kNumberOfFPRegisters; i++) { 242ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl uint64_t a_bits = a->dreg_bits(i); 243ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl uint64_t b_bits = b->dreg_bits(i); 244ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (a_bits != b_bits) { 245ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl printf("d%d\t Expected 0x%016" PRIx64 "\t Found 0x%016" PRIx64 "\n", 246ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl i, a_bits, b_bits); 247ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return false; 248ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 249ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 250ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 251ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return true; 252ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 253ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 254ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 255ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlRegList PopulateRegisterArray(Register* w, Register* x, Register* r, 256ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int reg_size, int reg_count, RegList allowed) { 257ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl RegList list = 0; 258ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int i = 0; 259ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl for (unsigned n = 0; (n < kNumberOfRegisters) && (i < reg_count); n++) { 260b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl if (((UINT64_C(1) << n) & allowed) != 0) { 261ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Only assign allowed registers. 262ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (r) { 263ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl r[i] = Register(n, reg_size); 264ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 265ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (x) { 266ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl x[i] = Register(n, kXRegSize); 267ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 268ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (w) { 269ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl w[i] = Register(n, kWRegSize); 270ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 271b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl list |= (UINT64_C(1) << n); 272ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl i++; 273ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 274ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 275ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Check that we got enough registers. 276b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT(CountSetBits(list, kNumberOfRegisters) == reg_count); 277ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 278ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return list; 279ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 280ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 281ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 282ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlRegList PopulateFPRegisterArray(FPRegister* s, FPRegister* d, FPRegister* v, 283ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int reg_size, int reg_count, RegList allowed) { 284ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl RegList list = 0; 285ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int i = 0; 286ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl for (unsigned n = 0; (n < kNumberOfFPRegisters) && (i < reg_count); n++) { 287b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl if (((UINT64_C(1) << n) & allowed) != 0) { 288ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Only assigned allowed registers. 289ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (v) { 290ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl v[i] = FPRegister(n, reg_size); 291ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 292ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (d) { 293ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl d[i] = FPRegister(n, kDRegSize); 294ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 295ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (s) { 296ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl s[i] = FPRegister(n, kSRegSize); 297ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 298b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl list |= (UINT64_C(1) << n); 299ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl i++; 300ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 301ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 302ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Check that we got enough registers. 303b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT(CountSetBits(list, kNumberOfFPRegisters) == reg_count); 304ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 305ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return list; 306ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 307ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 308ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 309ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Clobber(MacroAssembler* masm, RegList reg_list, uint64_t const value) { 310ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Register first = NoReg; 311ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl for (unsigned i = 0; i < kNumberOfRegisters; i++) { 312b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl if (reg_list & (UINT64_C(1) << i)) { 313ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Register xn(i, kXRegSize); 314ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // We should never write into sp here. 315b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT(!xn.Is(sp)); 316ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (!xn.IsZero()) { 317ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (!first.IsValid()) { 318ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // This is the first register we've hit, so construct the literal. 319ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Mov(xn, value); 320ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl first = xn; 321ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 322ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // We've already loaded the literal, so re-use the value already 323ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // loaded into the first register we hit. 324ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Mov(xn, first); 325ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 326ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 327ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 328ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 329ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 330ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 331ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 332ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid ClobberFP(MacroAssembler* masm, RegList reg_list, double const value) { 333ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FPRegister first = NoFPReg; 334ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl for (unsigned i = 0; i < kNumberOfFPRegisters; i++) { 335b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl if (reg_list & (UINT64_C(1) << i)) { 336ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FPRegister dn(i, kDRegSize); 337ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (!first.IsValid()) { 338ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // This is the first register we've hit, so construct the literal. 339ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Fmov(dn, value); 340ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl first = dn; 341ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 342ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // We've already loaded the literal, so re-use the value already loaded 343ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // into the first register we hit. 344ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Fmov(dn, first); 345ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 346ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 347ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 348ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 349ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 350ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 351ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Clobber(MacroAssembler* masm, CPURegList reg_list) { 35288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (reg_list.GetType() == CPURegister::kRegister) { 353ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // This will always clobber X registers. 35488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Clobber(masm, reg_list.GetList()); 35588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } else if (reg_list.GetType() == CPURegister::kVRegister) { 356ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // This will always clobber D registers. 35788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ClobberFP(masm, reg_list.GetList()); 358ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 359b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_UNREACHABLE(); 360ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 361ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 362ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 363ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 364ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid RegisterDump::Dump(MacroAssembler* masm) { 365b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT(__ StackPointer().Is(sp)); 366ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 367ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Ensure that we don't unintentionally clobber any registers. 368b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl UseScratchRegisterScope temps(masm); 369b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl temps.ExcludeAll(); 370ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 371ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Preserve some temporary registers. 372ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Register dump_base = x0; 373ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Register dump = x1; 374ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Register tmp = x2; 375ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Register dump_base_w = dump_base.W(); 376ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Register dump_w = dump.W(); 377ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Register tmp_w = tmp.W(); 378ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 379ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Offsets into the dump_ structure. 380ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const int x_offset = offsetof(dump_t, x_); 381ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const int w_offset = offsetof(dump_t, w_); 382ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const int d_offset = offsetof(dump_t, d_); 383ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const int s_offset = offsetof(dump_t, s_); 3845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl const int q_offset = offsetof(dump_t, q_); 385ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const int sp_offset = offsetof(dump_t, sp_); 386ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const int wsp_offset = offsetof(dump_t, wsp_); 387ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const int flags_offset = offsetof(dump_t, flags_); 388ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 389ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Push(xzr, dump_base, dump, tmp); 390ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 391ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Load the address where we will dump the state. 392b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl __ Mov(dump_base, reinterpret_cast<uintptr_t>(&dump_)); 393ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 394ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Dump the stack pointer (sp and wsp). 395ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // The stack pointer cannot be stored directly; it needs to be moved into 396ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // another register first. Also, we pushed four X registers, so we need to 397ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // compensate here. 398ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Add(tmp, sp, 4 * kXRegSizeInBytes); 399ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Str(tmp, MemOperand(dump_base, sp_offset)); 400ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Add(tmp_w, wsp, 4 * kXRegSizeInBytes); 401ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Str(tmp_w, MemOperand(dump_base, wsp_offset)); 402ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 403ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Dump X registers. 404ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Add(dump, dump_base, x_offset); 405ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl for (unsigned i = 0; i < kNumberOfRegisters; i += 2) { 40688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois __ Stp(Register::GetXRegFromCode(i), Register::GetXRegFromCode(i + 1), 407ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl MemOperand(dump, i * kXRegSizeInBytes)); 408ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 409ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 410ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Dump W registers. 411ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Add(dump, dump_base, w_offset); 412ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl for (unsigned i = 0; i < kNumberOfRegisters; i += 2) { 41388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois __ Stp(Register::GetWRegFromCode(i), Register::GetWRegFromCode(i + 1), 414ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl MemOperand(dump, i * kWRegSizeInBytes)); 415ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 416ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 417ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Dump D registers. 418ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Add(dump, dump_base, d_offset); 419ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl for (unsigned i = 0; i < kNumberOfFPRegisters; i += 2) { 42088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois __ Stp(FPRegister::GetDRegFromCode(i), FPRegister::GetDRegFromCode(i + 1), 421ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl MemOperand(dump, i * kDRegSizeInBytes)); 422ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 423ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 424ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Dump S registers. 425ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Add(dump, dump_base, s_offset); 426ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl for (unsigned i = 0; i < kNumberOfFPRegisters; i += 2) { 42788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois __ Stp(FPRegister::GetSRegFromCode(i), FPRegister::GetSRegFromCode(i + 1), 428ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl MemOperand(dump, i * kSRegSizeInBytes)); 429ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 430ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 4315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl // Dump Q registers. 4325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl __ Add(dump, dump_base, q_offset); 4335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl for (unsigned i = 0; i < kNumberOfVRegisters; i += 2) { 43488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois __ Stp(VRegister::GetQRegFromCode(i), VRegister::GetQRegFromCode(i + 1), 4355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl MemOperand(dump, i * kQRegSizeInBytes)); 4365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl } 4375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl 438ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Dump the flags. 439ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Mrs(tmp, NZCV); 440ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Str(tmp, MemOperand(dump_base, flags_offset)); 441ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 442ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // To dump the values that were in tmp amd dump, we need a new scratch 4430f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl // register. We can use any of the already dumped registers since we can 444ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // easily restore them. 445ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Register dump2_base = x10; 446ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Register dump2 = x11; 447b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT(!AreAliased(dump_base, dump, tmp, dump2_base, dump2)); 448ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 449ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Don't lose the dump_ address. 450ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Mov(dump2_base, dump_base); 451ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 452ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Pop(tmp, dump, dump_base, xzr); 453ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 454ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Add(dump2, dump2_base, w_offset); 45588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois __ Str(dump_base_w, 45688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois MemOperand(dump2, dump_base.GetCode() * kWRegSizeInBytes)); 45788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois __ Str(dump_w, MemOperand(dump2, dump.GetCode() * kWRegSizeInBytes)); 45888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois __ Str(tmp_w, MemOperand(dump2, tmp.GetCode() * kWRegSizeInBytes)); 459ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 460ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Add(dump2, dump2_base, x_offset); 46188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois __ Str(dump_base, MemOperand(dump2, dump_base.GetCode() * kXRegSizeInBytes)); 46288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois __ Str(dump, MemOperand(dump2, dump.GetCode() * kXRegSizeInBytes)); 46388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois __ Str(tmp, MemOperand(dump2, tmp.GetCode() * kXRegSizeInBytes)); 464ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 465ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Finally, restore dump2_base and dump2. 46688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois __ Ldr(dump2_base, 46788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois MemOperand(dump2, dump2_base.GetCode() * kXRegSizeInBytes)); 46888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois __ Ldr(dump2, MemOperand(dump2, dump2.GetCode() * kXRegSizeInBytes)); 469ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 470ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl completed_ = true; 471ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 472ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 47388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} // namespace aarch64 474ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} // namespace vixl 475