10cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// Copyright 2015, 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 270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#include "vixl/a64/macro-assembler-a64.h" 280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#include "vixl/a64/debugger-a64.h" 290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#include "vixl/a64/simulator-a64.h" 30ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#include "examples.h" 3139ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl#include "non-const-visitor.h" 3239ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl#include "custom-disassembler.h" 33ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#include "../test-utils-a64.h" 34ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 354a06316541258e3c058792321295ee36d409f419armvixl#include "../test-runner.h" 36ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 3739ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl#define TEST(name) TEST_(EXAMPLE_##name) 38ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 39ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlusing namespace vixl; 40ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 41ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 4239ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixlTEST(custom_disassembler) { 4339ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl TestCustomDisassembler(); 4439ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl} 4539ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl 4639ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl 4739ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl// The tests below only work with the simulator. 4839ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl#ifdef USE_SIMULATOR 4939ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl 5039ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl#define ARRAY_SIZE(Array) (sizeof(Array) / sizeof((Array)[0])) 5139ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl#define BUF_SIZE (4096) 5239ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl#define __ masm-> 5339ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl 54ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixluint64_t FactorialC(uint64_t n) { 55ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl uint64_t result = 1; 56ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 57ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl while (n != 0) { 58ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl result *= n; 59ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl n--; 60ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 61ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 62ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return result; 63ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 64ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// Multiply two column-major 4x4 matrices of 32 bit floating point values. 660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// Return a column-major 4x4 matrix of 32 bit floating point values in 'C'. 670cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid MatrixMultiplyC(float C[16], float A[16], float B[16]) { 680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl C[ 0] = A[ 0]*B[ 0] + A[ 4]*B[ 1] + A[ 8]*B[ 2] + A[12]*B[ 3]; 690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl C[ 1] = A[ 1]*B[ 0] + A[ 5]*B[ 1] + A[ 9]*B[ 2] + A[13]*B[ 3]; 700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl C[ 2] = A[ 2]*B[ 0] + A[ 6]*B[ 1] + A[10]*B[ 2] + A[14]*B[ 3]; 710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl C[ 3] = A[ 3]*B[ 0] + A[ 7]*B[ 1] + A[11]*B[ 2] + A[15]*B[ 3]; 720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl 730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl C[ 4] = A[ 0]*B[ 4] + A[ 4]*B[ 5] + A[ 8]*B[ 6] + A[12]*B[ 7]; 740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl C[ 5] = A[ 1]*B[ 4] + A[ 5]*B[ 5] + A[ 9]*B[ 6] + A[13]*B[ 7]; 750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl C[ 6] = A[ 2]*B[ 4] + A[ 6]*B[ 5] + A[10]*B[ 6] + A[14]*B[ 7]; 760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl C[ 7] = A[ 3]*B[ 4] + A[ 7]*B[ 5] + A[11]*B[ 6] + A[15]*B[ 7]; 770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl 780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl C[ 8] = A[ 0]*B[ 8] + A[ 4]*B[ 9] + A[ 8]*B[10] + A[12]*B[11]; 790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl C[ 9] = A[ 1]*B[ 8] + A[ 5]*B[ 9] + A[ 9]*B[10] + A[13]*B[11]; 800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl C[10] = A[ 2]*B[ 8] + A[ 6]*B[ 9] + A[10]*B[10] + A[14]*B[11]; 810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl C[11] = A[ 3]*B[ 8] + A[ 7]*B[ 9] + A[11]*B[10] + A[15]*B[11]; 820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl 830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl C[12] = A[ 0]*B[12] + A[ 4]*B[13] + A[ 8]*B[14] + A[12]*B[15]; 840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl C[13] = A[ 1]*B[12] + A[ 5]*B[13] + A[ 9]*B[14] + A[13]*B[15]; 850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl C[14] = A[ 2]*B[12] + A[ 6]*B[13] + A[10]*B[14] + A[14]*B[15]; 860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl C[15] = A[ 3]*B[12] + A[ 7]*B[13] + A[11]*B[14] + A[15]*B[15]; 870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl} 880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl 89ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixldouble Add3DoubleC(double x, double y, double z) { 90ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return x + y + z; 91ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 92ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 93ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixldouble Add4DoubleC(uint64_t a, double b, uint64_t c, double d) { 94ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return static_cast<double>(a) + b + static_cast<double>(c) + d; 95ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 96ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 97ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixluint32_t SumArrayC(uint8_t* array, uint32_t size) { 98ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl uint32_t result = 0; 99ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 100ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl for (uint32_t i = 0; i < size; ++i) { 101ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl result += array[i]; 102ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 103ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 104ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return result; 105ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 106ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 107ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 108ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid GenerateTestWrapper(MacroAssembler* masm, RegisterDump *regs) { 109ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Push(xzr, lr); 110ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Blr(x15); 111ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl regs->Dump(masm); 112ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Pop(lr, xzr); 113ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl __ Ret(); 114ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 115ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 116ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 117ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#define TEST_FUNCTION(Func) \ 118ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl do { \ 119ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int64_t saved_xregs[13]; \ 120ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl saved_xregs[0] = simulator.xreg(19); \ 121ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl saved_xregs[1] = simulator.xreg(20); \ 122ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl saved_xregs[2] = simulator.xreg(21); \ 123ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl saved_xregs[3] = simulator.xreg(22); \ 124ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl saved_xregs[4] = simulator.xreg(23); \ 125ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl saved_xregs[5] = simulator.xreg(24); \ 126ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl saved_xregs[6] = simulator.xreg(25); \ 127ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl saved_xregs[7] = simulator.xreg(26); \ 128ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl saved_xregs[8] = simulator.xreg(27); \ 129ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl saved_xregs[9] = simulator.xreg(28); \ 130ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl saved_xregs[10] = simulator.xreg(29); \ 131ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl saved_xregs[11] = simulator.xreg(30); \ 132ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl saved_xregs[12] = simulator.xreg(31); \ 133ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl \ 134ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl uint64_t saved_dregs[8]; \ 135ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl saved_dregs[0] = simulator.dreg_bits(8); \ 136ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl saved_dregs[1] = simulator.dreg_bits(9); \ 137ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl saved_dregs[2] = simulator.dreg_bits(10); \ 138ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl saved_dregs[3] = simulator.dreg_bits(11); \ 139ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl saved_dregs[4] = simulator.dreg_bits(12); \ 140ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl saved_dregs[5] = simulator.dreg_bits(13); \ 141ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl saved_dregs[6] = simulator.dreg_bits(14); \ 142ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl saved_dregs[7] = simulator.dreg_bits(15); \ 143ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl \ 14490b0414b6c794be58f34813f84c2c06e6a15be91armvixl simulator.set_xreg(15, masm.GetLabelAddress<uint64_t>(&Func)); \ 14590b0414b6c794be58f34813f84c2c06e6a15be91armvixl simulator.RunFrom(masm.GetLabelAddress<Instruction*>(&test)); \ 146ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl \ 147ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl assert(saved_xregs[0] == simulator.xreg(19)); \ 148ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl assert(saved_xregs[1] == simulator.xreg(20)); \ 149ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl assert(saved_xregs[2] == simulator.xreg(21)); \ 150ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl assert(saved_xregs[3] == simulator.xreg(22)); \ 151ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl assert(saved_xregs[4] == simulator.xreg(23)); \ 152ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl assert(saved_xregs[5] == simulator.xreg(24)); \ 153ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl assert(saved_xregs[6] == simulator.xreg(25)); \ 154ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl assert(saved_xregs[7] == simulator.xreg(26)); \ 155ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl assert(saved_xregs[8] == simulator.xreg(27)); \ 156ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl assert(saved_xregs[9] == simulator.xreg(28)); \ 157ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl assert(saved_xregs[10] == simulator.xreg(29)); \ 158ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl assert(saved_xregs[11] == simulator.xreg(30)); \ 159ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl assert(saved_xregs[12] == simulator.xreg(31)); \ 160ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl \ 161ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl assert(saved_dregs[0] == simulator.dreg_bits(8)); \ 162ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl assert(saved_dregs[1] == simulator.dreg_bits(9)); \ 163ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl assert(saved_dregs[2] == simulator.dreg_bits(10)); \ 164ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl assert(saved_dregs[3] == simulator.dreg_bits(11)); \ 165ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl assert(saved_dregs[4] == simulator.dreg_bits(12)); \ 166ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl assert(saved_dregs[5] == simulator.dreg_bits(13)); \ 167ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl assert(saved_dregs[6] == simulator.dreg_bits(14)); \ 168ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl assert(saved_dregs[7] == simulator.dreg_bits(15)); \ 169ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl \ 170ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } while (0) 171ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 172ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#define START() \ 17339ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl MacroAssembler masm(BUF_SIZE); \ 174ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Decoder decoder; \ 175ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Debugger simulator(&decoder); \ 1764a06316541258e3c058792321295ee36d409f419armvixl simulator.set_coloured_trace(Test::coloured_trace()); \ 177ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl PrintDisassembler* pdis = NULL; \ 178578645f14e122d2b87d907e298cda7e7d0babf1farmvixl Instrument* inst = NULL; \ 1794a06316541258e3c058792321295ee36d409f419armvixl if (Test::trace_sim()) { \ 180ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl pdis = new PrintDisassembler(stdout); \ 181ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl decoder.PrependVisitor(pdis); \ 182ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } \ 1834a06316541258e3c058792321295ee36d409f419armvixl if (Test::instruction_stats()) { \ 184578645f14e122d2b87d907e298cda7e7d0babf1farmvixl inst = new Instrument("vixl_stats.csv", 10); \ 185578645f14e122d2b87d907e298cda7e7d0babf1farmvixl inst->Enable(); \ 186578645f14e122d2b87d907e298cda7e7d0babf1farmvixl decoder.AppendVisitor(inst); \ 187578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } \ 188ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl RegisterDump regs; \ 189ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl \ 190ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Label test; \ 191ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl masm.Bind(&test); \ 192ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl GenerateTestWrapper(&masm, ®s); \ 193ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl masm.FinalizeCode() 194ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 195ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 196ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 197ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#define FACTORIAL_DOTEST(N) \ 198ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl do { \ 199ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl simulator.ResetState(); \ 200ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl simulator.set_xreg(0, N); \ 201ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl TEST_FUNCTION(factorial); \ 202ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl assert(static_cast<uint64_t>(regs.xreg(0)) == FactorialC(N)); \ 203ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } while (0) 204ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 205ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlTEST(factorial) { 206ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl START(); 207ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 208ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Label factorial; 209ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl masm.Bind(&factorial); 210ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl GenerateFactorial(&masm); 211ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl masm.FinalizeCode(); 212ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 213ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FACTORIAL_DOTEST(0); 214ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FACTORIAL_DOTEST(1); 215ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FACTORIAL_DOTEST(5); 216ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FACTORIAL_DOTEST(10); 217ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FACTORIAL_DOTEST(20); 218ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FACTORIAL_DOTEST(25); 219ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 220ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 221ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 222ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#define FACTORIAL_REC_DOTEST(N) \ 223ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl do { \ 224ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl simulator.ResetState(); \ 225ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl simulator.set_xreg(0, N); \ 226ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl TEST_FUNCTION(factorial_rec); \ 227ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl assert(static_cast<uint64_t>(regs.xreg(0)) == FactorialC(N)); \ 228ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } while (0) 229ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 230ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlTEST(factorial_rec) { 231ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl START(); 232ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 233ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Label factorial_rec; 234ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl masm.Bind(&factorial_rec); 235ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl GenerateFactorialRec(&masm); 236ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl masm.FinalizeCode(); 237ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 238ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FACTORIAL_REC_DOTEST(0); 239ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FACTORIAL_REC_DOTEST(1); 240ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FACTORIAL_REC_DOTEST(5); 241ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FACTORIAL_REC_DOTEST(10); 242ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FACTORIAL_REC_DOTEST(20); 243ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FACTORIAL_REC_DOTEST(25); 244ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 245ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 2460cc8b6ece4b3e757e11a906a81ece292437713abarmvixlTEST(neon_matrix_multiply) { 2470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl START(); 2480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl 2490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl Label neon_matrix_multiply; 2500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl masm.Bind(&neon_matrix_multiply); 2510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl GenerateNEONMatrixMultiply(&masm); 2520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl masm.FinalizeCode(); 2530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl 2540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl { 2550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl const int kRowSize = 4; 2560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl const int kColSize = 4; 2570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl const int kLength = kRowSize * kColSize; 2580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl 2590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl float mat1[kLength], mat2[kLength], expected[kLength], output[kLength]; 2600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl 2610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl // Fill the two input matrices with some 32 bit floating point values. 2620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl 2630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl mat1[0] = 1.0f; mat1[4] = 2.0f; mat1[ 8] = 3.0f; mat1[12] = 4.0f; 2640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl mat1[1] = 52.03f; mat1[5] = 12.24f; mat1[ 9] = 53.56f; mat1[13] = 22.22f; 2650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl mat1[2] = 4.43f; mat1[6] = 5.00f; mat1[10] = 7.00f; mat1[14] = 3.11f; 2660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl mat1[3] = 43.47f; mat1[7] = 10.97f; mat1[11] = 37.78f; mat1[15] = 90.91f; 2670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl 2680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl mat2[0] = 1.0f; mat2[4] = 11.24f; mat2[ 8] = 21.00f; mat2[12] = 21.31f; 2690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl mat2[1] = 2.0f; mat2[5] = 2.24f; mat2[ 9] = 8.56f; mat2[13] = 52.03f; 2700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl mat2[2] = 3.0f; mat2[6] = 51.00f; mat2[10] = 21.00f; mat2[14] = 33.11f; 2710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl mat2[3] = 4.0f; mat2[7] = 0.00f; mat2[11] = 84.00f; mat2[15] = 1.97f; 2720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl 2730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl MatrixMultiplyC(expected, mat1, mat2); 2740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl 2750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl simulator.ResetState(); 2760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl simulator.set_xreg(0, reinterpret_cast<uintptr_t>(output)); 2770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl simulator.set_xreg(1, reinterpret_cast<uintptr_t>(mat1)); 2780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl simulator.set_xreg(2, reinterpret_cast<uintptr_t>(mat2)); 2790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl TEST_FUNCTION(neon_matrix_multiply); 2800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl 2810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl // Check that the results match what is expected. 2820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl for (int i = 0; i < kLength; i++) { 2830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl assert(output[i] == expected[i]); 2840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 2850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 2860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl} 2870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl 2880cc8b6ece4b3e757e11a906a81ece292437713abarmvixlTEST(add2_vectors) { 2890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl START(); 2900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl 2910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl // Create and initialize the assembler and the simulator. 2920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl Label add2_vectors; 2930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl masm.Bind(&add2_vectors); 2940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl GenerateAdd2Vectors(&masm); 2950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl masm.FinalizeCode(); 2960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl 2970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl // Initialize input data for the example function. 2980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl uint8_t A[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 200}; 2990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl uint8_t B[] = {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, \ 3000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl 30, 31, 50}; 3010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl uint8_t D[ARRAY_SIZE(A)]; 3020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl uintptr_t A_addr = reinterpret_cast<uintptr_t>(A); 3030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl uintptr_t B_addr = reinterpret_cast<uintptr_t>(B); 3040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl 3050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl // Check whether number of elements in vectors match. 3060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VIXL_STATIC_ASSERT(ARRAY_SIZE(A) == ARRAY_SIZE(B)); 3070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VIXL_STATIC_ASSERT(ARRAY_SIZE(A) == ARRAY_SIZE(D)); 3080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl 3090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl // Compute vector sum for comparison later. 3100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl for (unsigned i = 0; i < ARRAY_SIZE(A); i++) { 3110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl D[i] = A[i] + B[i]; 3120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 3130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl 3140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl // Set up simulator and run example function. 3150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl simulator.ResetState(); 3160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl simulator.set_xreg(0, A_addr); 3170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl simulator.set_xreg(1, B_addr); 3180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl simulator.set_xreg(2, ARRAY_SIZE(A)); 3190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl TEST_FUNCTION(add2_vectors); 3200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl 3210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl // Compare vectors to ensure sums are equal. 3220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl for (unsigned i = 0; i < ARRAY_SIZE(A); i++) { 3230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl assert(A[i] == D[i]); 3240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 3250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl} 326ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 327ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#define ADD3_DOUBLE_DOTEST(A, B, C) \ 328ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl do { \ 329ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl simulator.ResetState(); \ 330ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl simulator.set_dreg(0, A); \ 331ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl simulator.set_dreg(1, B); \ 332ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl simulator.set_dreg(2, C); \ 333ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl TEST_FUNCTION(add3_double); \ 334ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl assert(regs.dreg(0) == Add3DoubleC(A, B, C)); \ 335ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } while (0) 336ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 337ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlTEST(add3_double) { 338ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl START(); 339ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 340ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Label add3_double; 341ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl masm.Bind(&add3_double); 342ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl GenerateAdd3Double(&masm); 343ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl masm.FinalizeCode(); 344ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 345ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ADD3_DOUBLE_DOTEST(0.0, 0.0, 0.0); 346ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ADD3_DOUBLE_DOTEST(457.698, 14.36, 2.00025); 347ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ADD3_DOUBLE_DOTEST(-45.55, -98.9, -0.354); 348ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ADD3_DOUBLE_DOTEST(.55, .9, .12); 349ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 350ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 351ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 352ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#define ADD4_DOUBLE_DOTEST(A, B, C, D) \ 353ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl do { \ 354ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl simulator.ResetState(); \ 355ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl simulator.set_xreg(0, A); \ 356ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl simulator.set_dreg(0, B); \ 357ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl simulator.set_xreg(1, C); \ 358ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl simulator.set_dreg(1, D); \ 359ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl TEST_FUNCTION(add4_double); \ 360ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl assert(regs.dreg(0) == Add4DoubleC(A, B, C, D)); \ 361ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } while (0) 362ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 363ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlTEST(add4_double) { 364ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl START(); 365ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 366ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Label add4_double; 367ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl masm.Bind(&add4_double); 368ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl GenerateAdd4Double(&masm); 369ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl masm.FinalizeCode(); 370ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 371ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ADD4_DOUBLE_DOTEST(0, 0, 0, 0); 372ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ADD4_DOUBLE_DOTEST(4, 3.287, 6, 13.48); 373ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ADD4_DOUBLE_DOTEST(56, 665.368, 0, -4932.4697); 374ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ADD4_DOUBLE_DOTEST(56, 0, 546, 0); 375ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ADD4_DOUBLE_DOTEST(0, 0.658, 0, 0.00000011540026); 376ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 377ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 378ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 379ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#define SUM_ARRAY_DOTEST(Array) \ 380ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl do { \ 381ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl simulator.ResetState(); \ 382ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl uintptr_t addr = reinterpret_cast<uintptr_t>(Array); \ 383ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl simulator.set_xreg(0, addr); \ 384ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl simulator.set_xreg(1, ARRAY_SIZE(Array)); \ 385ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl TEST_FUNCTION(sum_array); \ 386ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl assert(regs.xreg(0) == SumArrayC(Array, ARRAY_SIZE(Array))); \ 387ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } while (0) 388ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 389ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlTEST(sum_array) { 390ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl START(); 391ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 392ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Label sum_array; 393ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl masm.Bind(&sum_array); 394ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl GenerateSumArray(&masm); 395ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl masm.FinalizeCode(); 396ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 397ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl uint8_t data1[] = { 4, 9, 13, 3, 2, 6, 5 }; 398ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl SUM_ARRAY_DOTEST(data1); 399ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 400ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl uint8_t data2[] = { 42 }; 401ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl SUM_ARRAY_DOTEST(data2); 402ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 403ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl uint8_t data3[1000]; 404ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl for (unsigned int i = 0; i < ARRAY_SIZE(data3); ++i) 405ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl data3[i] = 255; 406ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl SUM_ARRAY_DOTEST(data3); 407ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 408ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 409ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 410ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#define ABS_DOTEST(X) \ 411ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl do { \ 412ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl simulator.ResetState(); \ 413ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl simulator.set_xreg(0, X); \ 414ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl TEST_FUNCTION(func_abs); \ 415ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl assert(regs.xreg(0) == abs(X)); \ 416ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } while (0) 417ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 418ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlTEST(abs) { 419ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl START(); 420ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 421ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Label func_abs; 422ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl masm.Bind(&func_abs); 423ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl GenerateAbs(&masm); 424ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl masm.FinalizeCode(); 425ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 426ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ABS_DOTEST(-42); 427ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ABS_DOTEST(0); 428ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ABS_DOTEST(545); 429ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ABS_DOTEST(-428751489); 430ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 431ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 432ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 4330cc8b6ece4b3e757e11a906a81ece292437713abarmvixlTEST(crc32) { 4340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl START(); 4350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl 4360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl Label crc32; 4370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl masm.Bind(&crc32); 4380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl GenerateCrc32(&masm); 4390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl masm.FinalizeCode(); 4400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl 4410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl const char *msg = "Hello World!"; 4420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl uintptr_t msg_addr = reinterpret_cast<uintptr_t>(msg); 4430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl size_t msg_size = strlen(msg); 4440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl int64_t chksum = INT64_C(0xe3d6e35c); 4450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl simulator.set_xreg(0, msg_addr); 4460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl simulator.set_xreg(1, msg_size); 4470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl TEST_FUNCTION(crc32); 4480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl assert(regs.xreg(0) == chksum); 4490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl} 4500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl 4510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl 452ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlTEST(swap4) { 453ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl START(); 454ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 455ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Label swap4; 456ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl masm.Bind(&swap4); 457ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl GenerateSwap4(&masm); 458ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl masm.FinalizeCode(); 459ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 460ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int64_t a = 15; 461ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int64_t b = 26; 462ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int64_t c = 46; 463ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int64_t d = 79; 464ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 465ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl simulator.set_xreg(0, a); 466ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl simulator.set_xreg(1, b); 467ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl simulator.set_xreg(2, c); 468ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl simulator.set_xreg(3, d); 469ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl TEST_FUNCTION(swap4); 470ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl assert(regs.xreg(0) == d); 471ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl assert(regs.xreg(1) == c); 472ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl assert(regs.xreg(2) == b); 473ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl assert(regs.xreg(3) == a); 474ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 475ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 476ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 477ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlTEST(swap_int32) { 478ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl START(); 479ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 480ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Label swap_int32; 481ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl masm.Bind(&swap_int32); 482ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl GenerateSwapInt32(&masm); 483ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl masm.FinalizeCode(); 484ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 485ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int32_t x = 168; 486ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int32_t y = 246; 487ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl simulator.set_wreg(0, x); 488ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl simulator.set_wreg(1, y); 489ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl TEST_FUNCTION(swap_int32); 490ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl assert(regs.wreg(0) == y); 491ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl assert(regs.wreg(1) == x); 492ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 493ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 494ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 495ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#define CHECKBOUNDS_DOTEST(Value, Low, High) \ 496ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl do { \ 497ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl simulator.ResetState(); \ 498ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl simulator.set_xreg(0, Value); \ 499ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl simulator.set_xreg(1, Low); \ 500ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl simulator.set_xreg(2, High); \ 501ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl TEST_FUNCTION(check_bounds); \ 502ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl assert(regs.xreg(0) == ((Low <= Value) && (Value <= High))); \ 503ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } while (0) 504ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 505ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlTEST(check_bounds) { 506ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl START(); 507ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 508ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Label check_bounds; 509ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl masm.Bind(&check_bounds); 510ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl GenerateCheckBounds(&masm); 511ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl masm.FinalizeCode(); 512ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 513ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl CHECKBOUNDS_DOTEST(0, 100, 200); 514ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl CHECKBOUNDS_DOTEST(58, 100, 200); 515ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl CHECKBOUNDS_DOTEST(99, 100, 200); 516ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl CHECKBOUNDS_DOTEST(100, 100, 200); 517ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl CHECKBOUNDS_DOTEST(101, 100, 200); 518ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl CHECKBOUNDS_DOTEST(150, 100, 200); 519ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl CHECKBOUNDS_DOTEST(199, 100, 200); 520ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl CHECKBOUNDS_DOTEST(200, 100, 200); 521ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl CHECKBOUNDS_DOTEST(201, 100, 200); 522ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 523ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 524ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 525ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#define GETTING_STARTED_DOTEST(Value) \ 526ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl do { \ 527ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl simulator.ResetState(); \ 528ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl simulator.set_xreg(0, Value); \ 529ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl TEST_FUNCTION(demo_function); \ 530ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl assert(regs.xreg(0) == (Value & 0x1122334455667788)); \ 531ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } while (0) 532ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 533ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlTEST(getting_started) { 534ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl START(); 535ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 536ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Label demo_function; 537ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl masm.Bind(&demo_function); 538ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl GenerateDemoFunction(&masm); 539ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl masm.FinalizeCode(); 540ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 541ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl GETTING_STARTED_DOTEST(0x8899aabbccddeeff); 542ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl GETTING_STARTED_DOTEST(0x1122334455667788); 543ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl GETTING_STARTED_DOTEST(0x0000000000000000); 544ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl GETTING_STARTED_DOTEST(0xffffffffffffffff); 545ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl GETTING_STARTED_DOTEST(0x5a5a5a5a5a5a5a5a); 546ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 5471123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 54839ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl 54939ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixlTEST(non_const_visitor) { 55039ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl byte assm_buf[BUF_SIZE]; 55139ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl MacroAssembler masm(assm_buf, BUF_SIZE); 55239ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl 55339ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl Label code_start, code_end; 55439ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl masm.Bind(&code_start); 55539ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl GenerateNonConstVisitorTestCode(&masm); 55639ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl masm.Bind(&code_end); 55739ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl masm.FinalizeCode(); 55839ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl Instruction* instr_start = masm.GetLabelAddress<Instruction*>(&code_start); 55939ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl Instruction* instr_end = masm.GetLabelAddress<Instruction*>(&code_end); 56039ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl 56139ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl int64_t res_orig = RunNonConstVisitorTestGeneratedCode(instr_start); 56239ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl 56339ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl ModifyNonConstVisitorTestGeneratedCode(instr_start, instr_end); 56439ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl 56539ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl int64_t res_mod = RunNonConstVisitorTestGeneratedCode(instr_start); 56639ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl assert(res_orig == -res_mod); 56739ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl} 56839ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl 5691123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl#endif // USE_SIMULATOR 570