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). 45bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langloisconst double kFP64SignallingNaN = RawbitsToDouble(UINT64_C(0x7ff000007f800001)); 4688c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisconst float kFP32SignallingNaN = RawbitsToFloat(0x7f800001); 47330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl 48330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl// A similar value, but as a quiet NaN. 4988c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisconst double kFP64QuietNaN = RawbitsToDouble(UINT64_C(0x7ff800007fc00001)); 5088c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisconst float kFP32QuietNaN = RawbitsToFloat(0x7fc00001); 51330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl 52330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl 53ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool Equal32(uint32_t expected, const RegisterDump*, uint32_t result) { 54ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (result != expected) { 55ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl printf("Expected 0x%08" PRIx32 "\t Found 0x%08" PRIx32 "\n", 56bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois expected, 57bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois 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", 67bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois expected, 68bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois result); 69ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 70ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 71ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return expected == result; 72ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 73ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 74ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlbool Equal128(vec128_t expected, const RegisterDump*, vec128_t result) { 765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl if ((result.h != expected.h) || (result.l != expected.l)) { 77bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois printf("Expected 0x%016" PRIx64 "%016" PRIx64 78bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois "\t " 795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl "Found 0x%016" PRIx64 "%016" PRIx64 "\n", 80bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois expected.h, 81bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois expected.l, 82bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois result.h, 83bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois result.l); 845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl } 855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl 865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl return ((expected.h == result.h) && (expected.l == result.l)); 875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl} 885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl 895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl 90ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool EqualFP32(float expected, const RegisterDump*, float result) { 9188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (FloatToRawbits(expected) == FloatToRawbits(result)) { 92578645f14e122d2b87d907e298cda7e7d0babf1farmvixl return true; 93578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } else { 946e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl if (std::isnan(expected) || (expected == 0.0)) { 95578645f14e122d2b87d907e298cda7e7d0babf1farmvixl printf("Expected 0x%08" PRIx32 "\t Found 0x%08" PRIx32 "\n", 96bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois FloatToRawbits(expected), 97bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois FloatToRawbits(result)); 98578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } else { 99bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois printf("Expected %.9f (0x%08" PRIx32 100bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois ")\t " 101578645f14e122d2b87d907e298cda7e7d0babf1farmvixl "Found %.9f (0x%08" PRIx32 ")\n", 102bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois expected, 103bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois FloatToRawbits(expected), 104bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois result, 105bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois FloatToRawbits(result)); 106578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 107578645f14e122d2b87d907e298cda7e7d0babf1farmvixl return false; 108ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 109ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 110ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 111ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 112ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool EqualFP64(double expected, const RegisterDump*, double result) { 11388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (DoubleToRawbits(expected) == DoubleToRawbits(result)) { 114578645f14e122d2b87d907e298cda7e7d0babf1farmvixl return true; 115ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 116ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1176e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl if (std::isnan(expected) || (expected == 0.0)) { 118578645f14e122d2b87d907e298cda7e7d0babf1farmvixl printf("Expected 0x%016" PRIx64 "\t Found 0x%016" PRIx64 "\n", 119bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois DoubleToRawbits(expected), 120bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois DoubleToRawbits(result)); 121578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } else { 122bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois printf("Expected %.17f (0x%016" PRIx64 123bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois ")\t " 124578645f14e122d2b87d907e298cda7e7d0babf1farmvixl "Found %.17f (0x%016" PRIx64 ")\n", 125bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois expected, 126bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois DoubleToRawbits(expected), 127bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois result, 128bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois DoubleToRawbits(result)); 129578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 130578645f14e122d2b87d907e298cda7e7d0babf1farmvixl return false; 131ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 132ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 133ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 134ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool Equal32(uint32_t expected, const RegisterDump* core, const Register& reg) { 135b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT(reg.Is32Bits()); 136ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Retrieve the corresponding X register so we can check that the upper part 137ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // was properly cleared. 13888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int64_t result_x = core->xreg(reg.GetCode()); 139b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl if ((result_x & 0xffffffff00000000) != 0) { 140ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl printf("Expected 0x%08" PRIx32 "\t Found 0x%016" PRIx64 "\n", 141bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois expected, 142bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois result_x); 143ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return false; 144ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 14588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t result_w = core->wreg(reg.GetCode()); 146ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return Equal32(expected, core, result_w); 147ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 148ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 149ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlbool Equal64(uint64_t expected, const RegisterDump* core, const Register& reg) { 151b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT(reg.Is64Bits()); 15288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint64_t result = core->xreg(reg.GetCode()); 153ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return Equal64(expected, core, result); 154ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 155ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 156ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlbool Equal128(uint64_t expected_h, 1585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl uint64_t expected_l, 1595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl const RegisterDump* core, 1605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl const VRegister& vreg) { 1615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl VIXL_ASSERT(vreg.Is128Bits()); 1625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl vec128_t expected = {expected_l, expected_h}; 16388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois vec128_t result = core->qreg(vreg.GetCode()); 1645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl return Equal128(expected, core, result); 1655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl} 1665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl 1675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl 168ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool EqualFP32(float expected, 169ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const RegisterDump* core, 170ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const FPRegister& fpreg) { 171b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT(fpreg.Is32Bits()); 172ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Retrieve the corresponding D register so we can check that the upper part 173ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // was properly cleared. 17488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint64_t result_64 = core->dreg_bits(fpreg.GetCode()); 175b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl if ((result_64 & 0xffffffff00000000) != 0) { 176ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl printf("Expected 0x%08" PRIx32 " (%f)\t Found 0x%016" PRIx64 "\n", 177bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois FloatToRawbits(expected), 178bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois expected, 179bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois result_64); 180ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return false; 181ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 182578645f14e122d2b87d907e298cda7e7d0babf1farmvixl 18388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return EqualFP32(expected, core, core->sreg(fpreg.GetCode())); 184ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 185ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 186ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 187ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool EqualFP64(double expected, 188ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const RegisterDump* core, 189ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const FPRegister& fpreg) { 190b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT(fpreg.Is64Bits()); 19188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return EqualFP64(expected, core, core->dreg(fpreg.GetCode())); 192ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 193ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 194ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 195ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool Equal64(const Register& reg0, 196ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const RegisterDump* core, 197ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const Register& reg1) { 198b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT(reg0.Is64Bits() && reg1.Is64Bits()); 19988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int64_t expected = core->xreg(reg0.GetCode()); 20088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int64_t result = core->xreg(reg1.GetCode()); 201ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return Equal64(expected, core, result); 202ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 203ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 204ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 20523703a72b1cd9a49428bcd850429f7be381c1e63Pierre Langloisbool Equal64(uint64_t expected, 20623703a72b1cd9a49428bcd850429f7be381c1e63Pierre Langlois const RegisterDump* core, 20723703a72b1cd9a49428bcd850429f7be381c1e63Pierre Langlois const VRegister& vreg) { 20823703a72b1cd9a49428bcd850429f7be381c1e63Pierre Langlois VIXL_ASSERT(vreg.Is64Bits()); 20923703a72b1cd9a49428bcd850429f7be381c1e63Pierre Langlois uint64_t result = core->dreg_bits(vreg.GetCode()); 21023703a72b1cd9a49428bcd850429f7be381c1e63Pierre Langlois return Equal64(expected, core, result); 21123703a72b1cd9a49428bcd850429f7be381c1e63Pierre Langlois} 21223703a72b1cd9a49428bcd850429f7be381c1e63Pierre Langlois 21323703a72b1cd9a49428bcd850429f7be381c1e63Pierre Langlois 214bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langloisstatic char FlagN(uint32_t flags) { return (flags & NFlag) ? 'N' : 'n'; } 215ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 216ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 217bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langloisstatic char FlagZ(uint32_t flags) { return (flags & ZFlag) ? 'Z' : 'z'; } 218ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 219ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 220bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langloisstatic char FlagC(uint32_t flags) { return (flags & CFlag) ? 'C' : 'c'; } 221ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 222ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 223bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langloisstatic char FlagV(uint32_t flags) { return (flags & VFlag) ? 'V' : 'v'; } 224ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 225ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 226ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool EqualNzcv(uint32_t expected, uint32_t result) { 227b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT((expected & ~NZCVFlag) == 0); 228b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT((result & ~NZCVFlag) == 0); 229ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (result != expected) { 230ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl printf("Expected: %c%c%c%c\t Found: %c%c%c%c\n", 231bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois FlagN(expected), 232bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois FlagZ(expected), 233bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois FlagC(expected), 234bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois FlagV(expected), 235bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois FlagN(result), 236bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois FlagZ(result), 237bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois FlagC(result), 238bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois FlagV(result)); 239578645f14e122d2b87d907e298cda7e7d0babf1farmvixl return false; 240ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 241ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 242578645f14e122d2b87d907e298cda7e7d0babf1farmvixl return true; 243ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 244ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 245ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 246ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool EqualRegisters(const RegisterDump* a, const RegisterDump* b) { 247ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl for (unsigned i = 0; i < kNumberOfRegisters; i++) { 248ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (a->xreg(i) != b->xreg(i)) { 249ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl printf("x%d\t Expected 0x%016" PRIx64 "\t Found 0x%016" PRIx64 "\n", 250bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois i, 251bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois a->xreg(i), 252bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois b->xreg(i)); 253ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return false; 254ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 255ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 256ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 257ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl for (unsigned i = 0; i < kNumberOfFPRegisters; i++) { 258ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl uint64_t a_bits = a->dreg_bits(i); 259ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl uint64_t b_bits = b->dreg_bits(i); 260ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (a_bits != b_bits) { 261ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl printf("d%d\t Expected 0x%016" PRIx64 "\t Found 0x%016" PRIx64 "\n", 262bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois i, 263bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois a_bits, 264bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois b_bits); 265ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return false; 266ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 267ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 268ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 269ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return true; 270ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 271ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 272ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 273bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre LangloisRegList PopulateRegisterArray(Register* w, 274bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois Register* x, 275bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois Register* r, 276bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois int reg_size, 277bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois int reg_count, 278bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois RegList allowed) { 279ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl RegList list = 0; 280ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int i = 0; 281ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl for (unsigned n = 0; (n < kNumberOfRegisters) && (i < reg_count); n++) { 282b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl if (((UINT64_C(1) << n) & allowed) != 0) { 283ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Only assign allowed registers. 284ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (r) { 285ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl r[i] = Register(n, reg_size); 286ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 287ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (x) { 288ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl x[i] = Register(n, kXRegSize); 289ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 290ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (w) { 291ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl w[i] = Register(n, kWRegSize); 292ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 293b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl list |= (UINT64_C(1) << n); 294ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl i++; 295ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 296ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 297ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Check that we got enough registers. 298b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT(CountSetBits(list, kNumberOfRegisters) == reg_count); 299ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 300ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return list; 301ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 302ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 303ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 304bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre LangloisRegList PopulateFPRegisterArray(FPRegister* s, 305bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois FPRegister* d, 306bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois FPRegister* v, 307bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois int reg_size, 308bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois int reg_count, 309bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois RegList allowed) { 310ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl RegList list = 0; 311ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int i = 0; 312ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl for (unsigned n = 0; (n < kNumberOfFPRegisters) && (i < reg_count); n++) { 313b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl if (((UINT64_C(1) << n) & allowed) != 0) { 314ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Only assigned allowed registers. 315ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (v) { 316ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl v[i] = FPRegister(n, reg_size); 317ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 318ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (d) { 319ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl d[i] = FPRegister(n, kDRegSize); 320ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 321ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (s) { 322ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl s[i] = FPRegister(n, kSRegSize); 323ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 324b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl list |= (UINT64_C(1) << n); 325ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl i++; 326ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 327ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 328ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Check that we got enough registers. 329b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT(CountSetBits(list, kNumberOfFPRegisters) == reg_count); 330ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 331ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return list; 332ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 333ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 334ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 335ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Clobber(MacroAssembler* masm, RegList reg_list, uint64_t const value) { 336ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Register first = NoReg; 337ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl for (unsigned i = 0; i < kNumberOfRegisters; i++) { 338b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl if (reg_list & (UINT64_C(1) << i)) { 339ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Register xn(i, kXRegSize); 340ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // We should never write into sp here. 341b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT(!xn.Is(sp)); 342ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (!xn.IsZero()) { 343ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (!first.IsValid()) { 344ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // This is the first register we've hit, so construct the literal. 345ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Mov(xn, value); 346ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl first = xn; 347ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 348ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // We've already loaded the literal, so re-use the value already 349ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // loaded into the first register we hit. 350ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Mov(xn, first); 351ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 352ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 353ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 354ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 355ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 356ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 357ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 358ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid ClobberFP(MacroAssembler* masm, RegList reg_list, double const value) { 359ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FPRegister first = NoFPReg; 360ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl for (unsigned i = 0; i < kNumberOfFPRegisters; i++) { 361b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl if (reg_list & (UINT64_C(1) << i)) { 362ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FPRegister dn(i, kDRegSize); 363ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (!first.IsValid()) { 364ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // This is the first register we've hit, so construct the literal. 365ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Fmov(dn, value); 366ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl first = dn; 367ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 368ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // We've already loaded the literal, so re-use the value already loaded 369ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // into the first register we hit. 370ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Fmov(dn, first); 371ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 372ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 373ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 374ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 375ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 376ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 377ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Clobber(MacroAssembler* masm, CPURegList reg_list) { 37888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (reg_list.GetType() == CPURegister::kRegister) { 379ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // This will always clobber X registers. 38088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Clobber(masm, reg_list.GetList()); 38188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } else if (reg_list.GetType() == CPURegister::kVRegister) { 382ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // This will always clobber D registers. 38388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ClobberFP(masm, reg_list.GetList()); 384ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 385b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_UNREACHABLE(); 386ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 387ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 388ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 389ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 390ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid RegisterDump::Dump(MacroAssembler* masm) { 391b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT(__ StackPointer().Is(sp)); 392ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 393ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Ensure that we don't unintentionally clobber any registers. 394b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl UseScratchRegisterScope temps(masm); 395b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl temps.ExcludeAll(); 396ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 397ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Preserve some temporary registers. 398ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Register dump_base = x0; 399ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Register dump = x1; 400ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Register tmp = x2; 401ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Register dump_base_w = dump_base.W(); 402ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Register dump_w = dump.W(); 403ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Register tmp_w = tmp.W(); 404ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 405ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Offsets into the dump_ structure. 406ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const int x_offset = offsetof(dump_t, x_); 407ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const int w_offset = offsetof(dump_t, w_); 408ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const int d_offset = offsetof(dump_t, d_); 409ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const int s_offset = offsetof(dump_t, s_); 4105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl const int q_offset = offsetof(dump_t, q_); 411ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const int sp_offset = offsetof(dump_t, sp_); 412ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const int wsp_offset = offsetof(dump_t, wsp_); 413ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const int flags_offset = offsetof(dump_t, flags_); 414ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 415ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Push(xzr, dump_base, dump, tmp); 416ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 417ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Load the address where we will dump the state. 418b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl __ Mov(dump_base, reinterpret_cast<uintptr_t>(&dump_)); 419ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 420ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Dump the stack pointer (sp and wsp). 421ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // The stack pointer cannot be stored directly; it needs to be moved into 422ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // another register first. Also, we pushed four X registers, so we need to 423ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // compensate here. 424ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Add(tmp, sp, 4 * kXRegSizeInBytes); 425ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Str(tmp, MemOperand(dump_base, sp_offset)); 426ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Add(tmp_w, wsp, 4 * kXRegSizeInBytes); 427ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Str(tmp_w, MemOperand(dump_base, wsp_offset)); 428ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 429ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Dump X registers. 430ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Add(dump, dump_base, x_offset); 431ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl for (unsigned i = 0; i < kNumberOfRegisters; i += 2) { 432bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois __ Stp(Register::GetXRegFromCode(i), 433bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois Register::GetXRegFromCode(i + 1), 434ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl MemOperand(dump, i * kXRegSizeInBytes)); 435ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 436ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 437ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Dump W registers. 438ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Add(dump, dump_base, w_offset); 439ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl for (unsigned i = 0; i < kNumberOfRegisters; i += 2) { 440bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois __ Stp(Register::GetWRegFromCode(i), 441bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois Register::GetWRegFromCode(i + 1), 442ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl MemOperand(dump, i * kWRegSizeInBytes)); 443ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 444ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 445ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Dump D registers. 446ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Add(dump, dump_base, d_offset); 447ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl for (unsigned i = 0; i < kNumberOfFPRegisters; i += 2) { 448bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois __ Stp(FPRegister::GetDRegFromCode(i), 449bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois FPRegister::GetDRegFromCode(i + 1), 450ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl MemOperand(dump, i * kDRegSizeInBytes)); 451ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 452ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 453ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Dump S registers. 454ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Add(dump, dump_base, s_offset); 455ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl for (unsigned i = 0; i < kNumberOfFPRegisters; i += 2) { 456bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois __ Stp(FPRegister::GetSRegFromCode(i), 457bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois FPRegister::GetSRegFromCode(i + 1), 458ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl MemOperand(dump, i * kSRegSizeInBytes)); 459ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 460ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 4615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl // Dump Q registers. 4625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl __ Add(dump, dump_base, q_offset); 4635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl for (unsigned i = 0; i < kNumberOfVRegisters; i += 2) { 464bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois __ Stp(VRegister::GetQRegFromCode(i), 465bde2e4b5ce376456d50a972b6f3aaee3475f8786Pierre Langlois VRegister::GetQRegFromCode(i + 1), 4665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl MemOperand(dump, i * kQRegSizeInBytes)); 4675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl } 4685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl 469ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Dump the flags. 470ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Mrs(tmp, NZCV); 471ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Str(tmp, MemOperand(dump_base, flags_offset)); 472ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 473ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // To dump the values that were in tmp amd dump, we need a new scratch 4740f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl // register. We can use any of the already dumped registers since we can 475ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // easily restore them. 476ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Register dump2_base = x10; 477ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Register dump2 = x11; 478b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT(!AreAliased(dump_base, dump, tmp, dump2_base, dump2)); 479ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 480ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Don't lose the dump_ address. 481ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Mov(dump2_base, dump_base); 482ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 483ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Pop(tmp, dump, dump_base, xzr); 484ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 485ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Add(dump2, dump2_base, w_offset); 48688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois __ Str(dump_base_w, 48788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois MemOperand(dump2, dump_base.GetCode() * kWRegSizeInBytes)); 48888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois __ Str(dump_w, MemOperand(dump2, dump.GetCode() * kWRegSizeInBytes)); 48988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois __ Str(tmp_w, MemOperand(dump2, tmp.GetCode() * kWRegSizeInBytes)); 490ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 491ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Add(dump2, dump2_base, x_offset); 49288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois __ Str(dump_base, MemOperand(dump2, dump_base.GetCode() * kXRegSizeInBytes)); 49388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois __ Str(dump, MemOperand(dump2, dump.GetCode() * kXRegSizeInBytes)); 49488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois __ Str(tmp, MemOperand(dump2, tmp.GetCode() * kXRegSizeInBytes)); 495ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 496ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Finally, restore dump2_base and dump2. 49788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois __ Ldr(dump2_base, 49888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois MemOperand(dump2, dump2_base.GetCode() * kXRegSizeInBytes)); 49988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois __ Ldr(dump2, MemOperand(dump2, dump2.GetCode() * kXRegSizeInBytes)); 500ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 501ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl completed_ = true; 502ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 503ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 50488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} // namespace aarch64 505ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} // namespace vixl 506