1b8021494Sopenharmony_ci// Copyright 2015, VIXL authors 2b8021494Sopenharmony_ci// All rights reserved. 3b8021494Sopenharmony_ci// 4b8021494Sopenharmony_ci// Redistribution and use in source and binary forms, with or without 5b8021494Sopenharmony_ci// modification, are permitted provided that the following conditions are met: 6b8021494Sopenharmony_ci// 7b8021494Sopenharmony_ci// * Redistributions of source code must retain the above copyright notice, 8b8021494Sopenharmony_ci// this list of conditions and the following disclaimer. 9b8021494Sopenharmony_ci// * Redistributions in binary form must reproduce the above copyright notice, 10b8021494Sopenharmony_ci// this list of conditions and the following disclaimer in the documentation 11b8021494Sopenharmony_ci// and/or other materials provided with the distribution. 12b8021494Sopenharmony_ci// * Neither the name of ARM Limited nor the names of its contributors may be 13b8021494Sopenharmony_ci// used to endorse or promote products derived from this software without 14b8021494Sopenharmony_ci// specific prior written permission. 15b8021494Sopenharmony_ci// 16b8021494Sopenharmony_ci// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND 17b8021494Sopenharmony_ci// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18b8021494Sopenharmony_ci// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19b8021494Sopenharmony_ci// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 20b8021494Sopenharmony_ci// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21b8021494Sopenharmony_ci// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22b8021494Sopenharmony_ci// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23b8021494Sopenharmony_ci// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24b8021494Sopenharmony_ci// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25b8021494Sopenharmony_ci// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26b8021494Sopenharmony_ci 27b8021494Sopenharmony_ci#include "custom-disassembler.h" 28b8021494Sopenharmony_ci#include "examples.h" 29b8021494Sopenharmony_ci#include "non-const-visitor.h" 30b8021494Sopenharmony_ci#include "test-runner.h" 31b8021494Sopenharmony_ci#include "test-utils.h" 32b8021494Sopenharmony_ci 33b8021494Sopenharmony_ci#include "../test-utils-aarch64.h" 34b8021494Sopenharmony_ci#include "aarch64/macro-assembler-aarch64.h" 35b8021494Sopenharmony_ci#include "aarch64/simulator-aarch64.h" 36b8021494Sopenharmony_ci#define TEST(name) TEST_(EXAMPLE_##name) 37b8021494Sopenharmony_ci 38b8021494Sopenharmony_ciusing namespace vixl; 39b8021494Sopenharmony_ciusing namespace vixl::aarch64; 40b8021494Sopenharmony_ci 41b8021494Sopenharmony_ci 42b8021494Sopenharmony_ciTEST(custom_disassembler) { TestCustomDisassembler(); } 43b8021494Sopenharmony_ci 44b8021494Sopenharmony_ci 45b8021494Sopenharmony_ci// The tests below only work with the simulator. 46b8021494Sopenharmony_ci#ifdef VIXL_INCLUDE_SIMULATOR_AARCH64 47b8021494Sopenharmony_ci 48b8021494Sopenharmony_ciuint64_t FactorialC(uint64_t n) { 49b8021494Sopenharmony_ci uint64_t result = 1; 50b8021494Sopenharmony_ci 51b8021494Sopenharmony_ci while (n != 0) { 52b8021494Sopenharmony_ci result *= n; 53b8021494Sopenharmony_ci n--; 54b8021494Sopenharmony_ci } 55b8021494Sopenharmony_ci 56b8021494Sopenharmony_ci return result; 57b8021494Sopenharmony_ci} 58b8021494Sopenharmony_ci 59b8021494Sopenharmony_ci// Multiply two column-major 4x4 matrices of 32 bit floating point values. 60b8021494Sopenharmony_ci// Return a column-major 4x4 matrix of 32 bit floating point values in 'C'. 61b8021494Sopenharmony_civoid MatrixMultiplyC(float C[16], float A[16], float B[16]) { 62b8021494Sopenharmony_ci C[0] = A[0] * B[0] + A[4] * B[1] + A[8] * B[2] + A[12] * B[3]; 63b8021494Sopenharmony_ci C[1] = A[1] * B[0] + A[5] * B[1] + A[9] * B[2] + A[13] * B[3]; 64b8021494Sopenharmony_ci C[2] = A[2] * B[0] + A[6] * B[1] + A[10] * B[2] + A[14] * B[3]; 65b8021494Sopenharmony_ci C[3] = A[3] * B[0] + A[7] * B[1] + A[11] * B[2] + A[15] * B[3]; 66b8021494Sopenharmony_ci 67b8021494Sopenharmony_ci C[4] = A[0] * B[4] + A[4] * B[5] + A[8] * B[6] + A[12] * B[7]; 68b8021494Sopenharmony_ci C[5] = A[1] * B[4] + A[5] * B[5] + A[9] * B[6] + A[13] * B[7]; 69b8021494Sopenharmony_ci C[6] = A[2] * B[4] + A[6] * B[5] + A[10] * B[6] + A[14] * B[7]; 70b8021494Sopenharmony_ci C[7] = A[3] * B[4] + A[7] * B[5] + A[11] * B[6] + A[15] * B[7]; 71b8021494Sopenharmony_ci 72b8021494Sopenharmony_ci C[8] = A[0] * B[8] + A[4] * B[9] + A[8] * B[10] + A[12] * B[11]; 73b8021494Sopenharmony_ci C[9] = A[1] * B[8] + A[5] * B[9] + A[9] * B[10] + A[13] * B[11]; 74b8021494Sopenharmony_ci C[10] = A[2] * B[8] + A[6] * B[9] + A[10] * B[10] + A[14] * B[11]; 75b8021494Sopenharmony_ci C[11] = A[3] * B[8] + A[7] * B[9] + A[11] * B[10] + A[15] * B[11]; 76b8021494Sopenharmony_ci 77b8021494Sopenharmony_ci C[12] = A[0] * B[12] + A[4] * B[13] + A[8] * B[14] + A[12] * B[15]; 78b8021494Sopenharmony_ci C[13] = A[1] * B[12] + A[5] * B[13] + A[9] * B[14] + A[13] * B[15]; 79b8021494Sopenharmony_ci C[14] = A[2] * B[12] + A[6] * B[13] + A[10] * B[14] + A[14] * B[15]; 80b8021494Sopenharmony_ci C[15] = A[3] * B[12] + A[7] * B[13] + A[11] * B[14] + A[15] * B[15]; 81b8021494Sopenharmony_ci} 82b8021494Sopenharmony_ci 83b8021494Sopenharmony_cidouble Add3DoubleC(double x, double y, double z) { return x + y + z; } 84b8021494Sopenharmony_ci 85b8021494Sopenharmony_cidouble Add4DoubleC(uint64_t a, double b, uint64_t c, double d) { 86b8021494Sopenharmony_ci return static_cast<double>(a) + b + static_cast<double>(c) + d; 87b8021494Sopenharmony_ci} 88b8021494Sopenharmony_ci 89b8021494Sopenharmony_ciuint32_t SumArrayC(uint8_t* array, uint32_t size) { 90b8021494Sopenharmony_ci uint32_t result = 0; 91b8021494Sopenharmony_ci 92b8021494Sopenharmony_ci for (uint32_t i = 0; i < size; ++i) { 93b8021494Sopenharmony_ci result += array[i]; 94b8021494Sopenharmony_ci } 95b8021494Sopenharmony_ci 96b8021494Sopenharmony_ci return result; 97b8021494Sopenharmony_ci} 98b8021494Sopenharmony_ci 99b8021494Sopenharmony_ci 100b8021494Sopenharmony_ci#define TEST_FUNCTION(Func) \ 101b8021494Sopenharmony_ci do { \ 102b8021494Sopenharmony_ci /* Record callee-saved registers, so we can check them after the test. */ \ 103b8021494Sopenharmony_ci int64_t saved_xregs[13]; \ 104b8021494Sopenharmony_ci saved_xregs[0] = simulator.ReadXRegister(19); \ 105b8021494Sopenharmony_ci saved_xregs[1] = simulator.ReadXRegister(20); \ 106b8021494Sopenharmony_ci saved_xregs[2] = simulator.ReadXRegister(21); \ 107b8021494Sopenharmony_ci saved_xregs[3] = simulator.ReadXRegister(22); \ 108b8021494Sopenharmony_ci saved_xregs[4] = simulator.ReadXRegister(23); \ 109b8021494Sopenharmony_ci saved_xregs[5] = simulator.ReadXRegister(24); \ 110b8021494Sopenharmony_ci saved_xregs[6] = simulator.ReadXRegister(25); \ 111b8021494Sopenharmony_ci saved_xregs[7] = simulator.ReadXRegister(26); \ 112b8021494Sopenharmony_ci saved_xregs[8] = simulator.ReadXRegister(27); \ 113b8021494Sopenharmony_ci saved_xregs[9] = simulator.ReadXRegister(28); \ 114b8021494Sopenharmony_ci saved_xregs[10] = simulator.ReadXRegister(29); \ 115b8021494Sopenharmony_ci saved_xregs[11] = simulator.ReadXRegister(30); \ 116b8021494Sopenharmony_ci saved_xregs[12] = simulator.ReadXRegister(31); \ 117b8021494Sopenharmony_ci \ 118b8021494Sopenharmony_ci uint64_t saved_dregs[8]; \ 119b8021494Sopenharmony_ci saved_dregs[0] = simulator.ReadDRegisterBits(8); \ 120b8021494Sopenharmony_ci saved_dregs[1] = simulator.ReadDRegisterBits(9); \ 121b8021494Sopenharmony_ci saved_dregs[2] = simulator.ReadDRegisterBits(10); \ 122b8021494Sopenharmony_ci saved_dregs[3] = simulator.ReadDRegisterBits(11); \ 123b8021494Sopenharmony_ci saved_dregs[4] = simulator.ReadDRegisterBits(12); \ 124b8021494Sopenharmony_ci saved_dregs[5] = simulator.ReadDRegisterBits(13); \ 125b8021494Sopenharmony_ci saved_dregs[6] = simulator.ReadDRegisterBits(14); \ 126b8021494Sopenharmony_ci saved_dregs[7] = simulator.ReadDRegisterBits(15); \ 127b8021494Sopenharmony_ci \ 128b8021494Sopenharmony_ci simulator.WriteXRegister(test_function_reg.GetCode(), \ 129b8021494Sopenharmony_ci masm.GetLabelAddress<uint64_t>(&Func)); \ 130b8021494Sopenharmony_ci simulator.RunFrom(masm.GetLabelAddress<Instruction*>(&test)); \ 131b8021494Sopenharmony_ci \ 132b8021494Sopenharmony_ci /* Check that callee-saved registers are preserved. */ \ 133b8021494Sopenharmony_ci VIXL_CHECK(saved_xregs[0] == simulator.ReadXRegister(19)); \ 134b8021494Sopenharmony_ci VIXL_CHECK(saved_xregs[1] == simulator.ReadXRegister(20)); \ 135b8021494Sopenharmony_ci VIXL_CHECK(saved_xregs[2] == simulator.ReadXRegister(21)); \ 136b8021494Sopenharmony_ci VIXL_CHECK(saved_xregs[3] == simulator.ReadXRegister(22)); \ 137b8021494Sopenharmony_ci VIXL_CHECK(saved_xregs[4] == simulator.ReadXRegister(23)); \ 138b8021494Sopenharmony_ci VIXL_CHECK(saved_xregs[5] == simulator.ReadXRegister(24)); \ 139b8021494Sopenharmony_ci VIXL_CHECK(saved_xregs[6] == simulator.ReadXRegister(25)); \ 140b8021494Sopenharmony_ci VIXL_CHECK(saved_xregs[7] == simulator.ReadXRegister(26)); \ 141b8021494Sopenharmony_ci VIXL_CHECK(saved_xregs[8] == simulator.ReadXRegister(27)); \ 142b8021494Sopenharmony_ci VIXL_CHECK(saved_xregs[9] == simulator.ReadXRegister(28)); \ 143b8021494Sopenharmony_ci VIXL_CHECK(saved_xregs[10] == simulator.ReadXRegister(29)); \ 144b8021494Sopenharmony_ci VIXL_CHECK(saved_xregs[11] == simulator.ReadXRegister(30)); \ 145b8021494Sopenharmony_ci VIXL_CHECK(saved_xregs[12] == simulator.ReadXRegister(31)); \ 146b8021494Sopenharmony_ci \ 147b8021494Sopenharmony_ci VIXL_CHECK(saved_dregs[0] == simulator.ReadDRegisterBits(8)); \ 148b8021494Sopenharmony_ci VIXL_CHECK(saved_dregs[1] == simulator.ReadDRegisterBits(9)); \ 149b8021494Sopenharmony_ci VIXL_CHECK(saved_dregs[2] == simulator.ReadDRegisterBits(10)); \ 150b8021494Sopenharmony_ci VIXL_CHECK(saved_dregs[3] == simulator.ReadDRegisterBits(11)); \ 151b8021494Sopenharmony_ci VIXL_CHECK(saved_dregs[4] == simulator.ReadDRegisterBits(12)); \ 152b8021494Sopenharmony_ci VIXL_CHECK(saved_dregs[5] == simulator.ReadDRegisterBits(13)); \ 153b8021494Sopenharmony_ci VIXL_CHECK(saved_dregs[6] == simulator.ReadDRegisterBits(14)); \ 154b8021494Sopenharmony_ci VIXL_CHECK(saved_dregs[7] == simulator.ReadDRegisterBits(15)); \ 155b8021494Sopenharmony_ci \ 156b8021494Sopenharmony_ci } while (0) 157b8021494Sopenharmony_ci 158b8021494Sopenharmony_ci#define START() \ 159b8021494Sopenharmony_ci MacroAssembler masm; \ 160b8021494Sopenharmony_ci Decoder decoder; \ 161b8021494Sopenharmony_ci Simulator simulator(&decoder); \ 162b8021494Sopenharmony_ci simulator.SetColouredTrace(Test::coloured_trace()); \ 163b8021494Sopenharmony_ci RegisterDump regs; \ 164b8021494Sopenharmony_ci \ 165b8021494Sopenharmony_ci Register test_function_reg = x15; \ 166b8021494Sopenharmony_ci \ 167b8021494Sopenharmony_ci Label test; \ 168b8021494Sopenharmony_ci masm.Bind(&test); \ 169b8021494Sopenharmony_ci { \ 170b8021494Sopenharmony_ci int trace_parameters = 0; \ 171b8021494Sopenharmony_ci if (Test::trace_reg()) trace_parameters |= LOG_STATE; \ 172b8021494Sopenharmony_ci if (Test::trace_write()) trace_parameters |= LOG_WRITE; \ 173b8021494Sopenharmony_ci if (Test::trace_sim()) trace_parameters |= LOG_DISASM; \ 174b8021494Sopenharmony_ci if (Test::trace_branch()) trace_parameters |= LOG_BRANCH; \ 175b8021494Sopenharmony_ci if (trace_parameters != 0) { \ 176b8021494Sopenharmony_ci masm.Trace(static_cast<TraceParameters>(trace_parameters), \ 177b8021494Sopenharmony_ci TRACE_ENABLE); \ 178b8021494Sopenharmony_ci } \ 179b8021494Sopenharmony_ci } \ 180b8021494Sopenharmony_ci masm.Blr(test_function_reg); \ 181b8021494Sopenharmony_ci masm.Trace(LOG_ALL, TRACE_DISABLE); \ 182b8021494Sopenharmony_ci regs.Dump(&masm); \ 183b8021494Sopenharmony_ci masm.Mov(lr, reinterpret_cast<uint64_t>(Simulator::kEndOfSimAddress)); \ 184b8021494Sopenharmony_ci masm.Ret(); \ 185b8021494Sopenharmony_ci masm.FinalizeCode() 186b8021494Sopenharmony_ci 187b8021494Sopenharmony_ci 188b8021494Sopenharmony_ci#define FACTORIAL_DOTEST(N) \ 189b8021494Sopenharmony_ci do { \ 190b8021494Sopenharmony_ci simulator.ResetState(); \ 191b8021494Sopenharmony_ci simulator.WriteXRegister(0, N); \ 192b8021494Sopenharmony_ci TEST_FUNCTION(factorial); \ 193b8021494Sopenharmony_ci VIXL_CHECK(static_cast<uint64_t>(regs.xreg(0)) == FactorialC(N)); \ 194b8021494Sopenharmony_ci } while (0) 195b8021494Sopenharmony_ci 196b8021494Sopenharmony_ciTEST(factorial) { 197b8021494Sopenharmony_ci START(); 198b8021494Sopenharmony_ci 199b8021494Sopenharmony_ci Label factorial; 200b8021494Sopenharmony_ci masm.Bind(&factorial); 201b8021494Sopenharmony_ci GenerateFactorial(&masm); 202b8021494Sopenharmony_ci masm.FinalizeCode(); 203b8021494Sopenharmony_ci 204b8021494Sopenharmony_ci FACTORIAL_DOTEST(0); 205b8021494Sopenharmony_ci FACTORIAL_DOTEST(1); 206b8021494Sopenharmony_ci FACTORIAL_DOTEST(5); 207b8021494Sopenharmony_ci FACTORIAL_DOTEST(10); 208b8021494Sopenharmony_ci FACTORIAL_DOTEST(20); 209b8021494Sopenharmony_ci FACTORIAL_DOTEST(25); 210b8021494Sopenharmony_ci} 211b8021494Sopenharmony_ci 212b8021494Sopenharmony_ci 213b8021494Sopenharmony_ci#define FACTORIAL_REC_DOTEST(N) \ 214b8021494Sopenharmony_ci do { \ 215b8021494Sopenharmony_ci simulator.ResetState(); \ 216b8021494Sopenharmony_ci simulator.WriteXRegister(0, N); \ 217b8021494Sopenharmony_ci TEST_FUNCTION(factorial_rec); \ 218b8021494Sopenharmony_ci VIXL_CHECK(static_cast<uint64_t>(regs.xreg(0)) == FactorialC(N)); \ 219b8021494Sopenharmony_ci } while (0) 220b8021494Sopenharmony_ci 221b8021494Sopenharmony_ciTEST(factorial_rec) { 222b8021494Sopenharmony_ci START(); 223b8021494Sopenharmony_ci 224b8021494Sopenharmony_ci Label factorial_rec; 225b8021494Sopenharmony_ci masm.Bind(&factorial_rec); 226b8021494Sopenharmony_ci GenerateFactorialRec(&masm); 227b8021494Sopenharmony_ci masm.FinalizeCode(); 228b8021494Sopenharmony_ci 229b8021494Sopenharmony_ci FACTORIAL_REC_DOTEST(0); 230b8021494Sopenharmony_ci FACTORIAL_REC_DOTEST(1); 231b8021494Sopenharmony_ci FACTORIAL_REC_DOTEST(5); 232b8021494Sopenharmony_ci FACTORIAL_REC_DOTEST(10); 233b8021494Sopenharmony_ci FACTORIAL_REC_DOTEST(20); 234b8021494Sopenharmony_ci FACTORIAL_REC_DOTEST(25); 235b8021494Sopenharmony_ci} 236b8021494Sopenharmony_ci 237b8021494Sopenharmony_ciTEST(neon_matrix_multiply) { 238b8021494Sopenharmony_ci START(); 239b8021494Sopenharmony_ci 240b8021494Sopenharmony_ci Label neon_matrix_multiply; 241b8021494Sopenharmony_ci masm.Bind(&neon_matrix_multiply); 242b8021494Sopenharmony_ci GenerateNEONMatrixMultiply(&masm); 243b8021494Sopenharmony_ci masm.FinalizeCode(); 244b8021494Sopenharmony_ci 245b8021494Sopenharmony_ci { 246b8021494Sopenharmony_ci const int kRowSize = 4; 247b8021494Sopenharmony_ci const int kColSize = 4; 248b8021494Sopenharmony_ci const int kLength = kRowSize * kColSize; 249b8021494Sopenharmony_ci 250b8021494Sopenharmony_ci float mat1[kLength], mat2[kLength], expected[kLength], output[kLength]; 251b8021494Sopenharmony_ci 252b8021494Sopenharmony_ci // Fill the two input matrices with some 32 bit floating point values. 253b8021494Sopenharmony_ci 254b8021494Sopenharmony_ci mat1[0] = 1.0f; 255b8021494Sopenharmony_ci mat1[4] = 2.0f; 256b8021494Sopenharmony_ci mat1[8] = 3.0f; 257b8021494Sopenharmony_ci mat1[12] = 4.0f; 258b8021494Sopenharmony_ci mat1[1] = 52.03f; 259b8021494Sopenharmony_ci mat1[5] = 12.24f; 260b8021494Sopenharmony_ci mat1[9] = 53.56f; 261b8021494Sopenharmony_ci mat1[13] = 22.22f; 262b8021494Sopenharmony_ci mat1[2] = 4.43f; 263b8021494Sopenharmony_ci mat1[6] = 5.00f; 264b8021494Sopenharmony_ci mat1[10] = 7.00f; 265b8021494Sopenharmony_ci mat1[14] = 3.11f; 266b8021494Sopenharmony_ci mat1[3] = 43.47f; 267b8021494Sopenharmony_ci mat1[7] = 10.97f; 268b8021494Sopenharmony_ci mat1[11] = 37.78f; 269b8021494Sopenharmony_ci mat1[15] = 90.91f; 270b8021494Sopenharmony_ci 271b8021494Sopenharmony_ci mat2[0] = 1.0f; 272b8021494Sopenharmony_ci mat2[4] = 11.24f; 273b8021494Sopenharmony_ci mat2[8] = 21.00f; 274b8021494Sopenharmony_ci mat2[12] = 21.31f; 275b8021494Sopenharmony_ci mat2[1] = 2.0f; 276b8021494Sopenharmony_ci mat2[5] = 2.24f; 277b8021494Sopenharmony_ci mat2[9] = 8.56f; 278b8021494Sopenharmony_ci mat2[13] = 52.03f; 279b8021494Sopenharmony_ci mat2[2] = 3.0f; 280b8021494Sopenharmony_ci mat2[6] = 51.00f; 281b8021494Sopenharmony_ci mat2[10] = 21.00f; 282b8021494Sopenharmony_ci mat2[14] = 33.11f; 283b8021494Sopenharmony_ci mat2[3] = 4.0f; 284b8021494Sopenharmony_ci mat2[7] = 0.00f; 285b8021494Sopenharmony_ci mat2[11] = 84.00f; 286b8021494Sopenharmony_ci mat2[15] = 1.97f; 287b8021494Sopenharmony_ci 288b8021494Sopenharmony_ci MatrixMultiplyC(expected, mat1, mat2); 289b8021494Sopenharmony_ci 290b8021494Sopenharmony_ci simulator.ResetState(); 291b8021494Sopenharmony_ci simulator.WriteXRegister(0, reinterpret_cast<uintptr_t>(output)); 292b8021494Sopenharmony_ci simulator.WriteXRegister(1, reinterpret_cast<uintptr_t>(mat1)); 293b8021494Sopenharmony_ci simulator.WriteXRegister(2, reinterpret_cast<uintptr_t>(mat2)); 294b8021494Sopenharmony_ci TEST_FUNCTION(neon_matrix_multiply); 295b8021494Sopenharmony_ci 296b8021494Sopenharmony_ci // Check that the results match what is expected. 297b8021494Sopenharmony_ci for (int i = 0; i < kLength; i++) { 298b8021494Sopenharmony_ci VIXL_CHECK(output[i] == expected[i]); 299b8021494Sopenharmony_ci } 300b8021494Sopenharmony_ci } 301b8021494Sopenharmony_ci} 302b8021494Sopenharmony_ci 303b8021494Sopenharmony_ciTEST(add2_vectors) { 304b8021494Sopenharmony_ci START(); 305b8021494Sopenharmony_ci 306b8021494Sopenharmony_ci // Create and initialize the assembler and the simulator. 307b8021494Sopenharmony_ci Label add2_vectors; 308b8021494Sopenharmony_ci masm.Bind(&add2_vectors); 309b8021494Sopenharmony_ci GenerateAdd2Vectors(&masm); 310b8021494Sopenharmony_ci masm.FinalizeCode(); 311b8021494Sopenharmony_ci 312b8021494Sopenharmony_ci // Initialize input data for the example function. 313b8021494Sopenharmony_ci uint8_t A[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 200}; 314b8021494Sopenharmony_ci uint8_t B[] = 315b8021494Sopenharmony_ci {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 50}; 316b8021494Sopenharmony_ci uint8_t D[ARRAY_SIZE(A)]; 317b8021494Sopenharmony_ci uintptr_t A_addr = reinterpret_cast<uintptr_t>(A); 318b8021494Sopenharmony_ci uintptr_t B_addr = reinterpret_cast<uintptr_t>(B); 319b8021494Sopenharmony_ci 320b8021494Sopenharmony_ci // Check whether number of elements in vectors match. 321b8021494Sopenharmony_ci VIXL_STATIC_ASSERT(ARRAY_SIZE(A) == ARRAY_SIZE(B)); 322b8021494Sopenharmony_ci VIXL_STATIC_ASSERT(ARRAY_SIZE(A) == ARRAY_SIZE(D)); 323b8021494Sopenharmony_ci 324b8021494Sopenharmony_ci // Compute vector sum for comparison later. 325b8021494Sopenharmony_ci for (unsigned i = 0; i < ARRAY_SIZE(A); i++) { 326b8021494Sopenharmony_ci D[i] = A[i] + B[i]; 327b8021494Sopenharmony_ci } 328b8021494Sopenharmony_ci 329b8021494Sopenharmony_ci // Set up simulator and run example function. 330b8021494Sopenharmony_ci simulator.ResetState(); 331b8021494Sopenharmony_ci simulator.WriteXRegister(0, A_addr); 332b8021494Sopenharmony_ci simulator.WriteXRegister(1, B_addr); 333b8021494Sopenharmony_ci simulator.WriteXRegister(2, ARRAY_SIZE(A)); 334b8021494Sopenharmony_ci TEST_FUNCTION(add2_vectors); 335b8021494Sopenharmony_ci 336b8021494Sopenharmony_ci // Compare vectors to ensure sums are equal. 337b8021494Sopenharmony_ci for (unsigned i = 0; i < ARRAY_SIZE(A); i++) { 338b8021494Sopenharmony_ci VIXL_CHECK(A[i] == D[i]); 339b8021494Sopenharmony_ci } 340b8021494Sopenharmony_ci} 341b8021494Sopenharmony_ci 342b8021494Sopenharmony_ci#define ADD3_DOUBLE_DOTEST(A, B, C) \ 343b8021494Sopenharmony_ci do { \ 344b8021494Sopenharmony_ci simulator.ResetState(); \ 345b8021494Sopenharmony_ci simulator.WriteDRegister(0, A); \ 346b8021494Sopenharmony_ci simulator.WriteDRegister(1, B); \ 347b8021494Sopenharmony_ci simulator.WriteDRegister(2, C); \ 348b8021494Sopenharmony_ci TEST_FUNCTION(add3_double); \ 349b8021494Sopenharmony_ci VIXL_CHECK(regs.dreg(0) == Add3DoubleC(A, B, C)); \ 350b8021494Sopenharmony_ci } while (0) 351b8021494Sopenharmony_ci 352b8021494Sopenharmony_ciTEST(add3_double) { 353b8021494Sopenharmony_ci START(); 354b8021494Sopenharmony_ci 355b8021494Sopenharmony_ci Label add3_double; 356b8021494Sopenharmony_ci masm.Bind(&add3_double); 357b8021494Sopenharmony_ci GenerateAdd3Double(&masm); 358b8021494Sopenharmony_ci masm.FinalizeCode(); 359b8021494Sopenharmony_ci 360b8021494Sopenharmony_ci ADD3_DOUBLE_DOTEST(0.0, 0.0, 0.0); 361b8021494Sopenharmony_ci ADD3_DOUBLE_DOTEST(457.698, 14.36, 2.00025); 362b8021494Sopenharmony_ci ADD3_DOUBLE_DOTEST(-45.55, -98.9, -0.354); 363b8021494Sopenharmony_ci ADD3_DOUBLE_DOTEST(.55, .9, .12); 364b8021494Sopenharmony_ci} 365b8021494Sopenharmony_ci 366b8021494Sopenharmony_ci 367b8021494Sopenharmony_ci#define ADD4_DOUBLE_DOTEST(A, B, C, D) \ 368b8021494Sopenharmony_ci do { \ 369b8021494Sopenharmony_ci simulator.ResetState(); \ 370b8021494Sopenharmony_ci simulator.WriteXRegister(0, A); \ 371b8021494Sopenharmony_ci simulator.WriteDRegister(0, B); \ 372b8021494Sopenharmony_ci simulator.WriteXRegister(1, C); \ 373b8021494Sopenharmony_ci simulator.WriteDRegister(1, D); \ 374b8021494Sopenharmony_ci TEST_FUNCTION(add4_double); \ 375b8021494Sopenharmony_ci VIXL_CHECK(regs.dreg(0) == Add4DoubleC(A, B, C, D)); \ 376b8021494Sopenharmony_ci } while (0) 377b8021494Sopenharmony_ci 378b8021494Sopenharmony_ciTEST(add4_double) { 379b8021494Sopenharmony_ci START(); 380b8021494Sopenharmony_ci 381b8021494Sopenharmony_ci Label add4_double; 382b8021494Sopenharmony_ci masm.Bind(&add4_double); 383b8021494Sopenharmony_ci GenerateAdd4Double(&masm); 384b8021494Sopenharmony_ci masm.FinalizeCode(); 385b8021494Sopenharmony_ci 386b8021494Sopenharmony_ci ADD4_DOUBLE_DOTEST(0, 0, 0, 0); 387b8021494Sopenharmony_ci ADD4_DOUBLE_DOTEST(4, 3.287, 6, 13.48); 388b8021494Sopenharmony_ci ADD4_DOUBLE_DOTEST(56, 665.368, 0, -4932.4697); 389b8021494Sopenharmony_ci ADD4_DOUBLE_DOTEST(56, 0, 546, 0); 390b8021494Sopenharmony_ci ADD4_DOUBLE_DOTEST(0, 0.658, 0, 0.00000011540026); 391b8021494Sopenharmony_ci} 392b8021494Sopenharmony_ci 393b8021494Sopenharmony_ci 394b8021494Sopenharmony_ci#define SUM_ARRAY_DOTEST(Array) \ 395b8021494Sopenharmony_ci do { \ 396b8021494Sopenharmony_ci simulator.ResetState(); \ 397b8021494Sopenharmony_ci uintptr_t addr = reinterpret_cast<uintptr_t>(Array); \ 398b8021494Sopenharmony_ci simulator.WriteXRegister(0, addr); \ 399b8021494Sopenharmony_ci simulator.WriteXRegister(1, ARRAY_SIZE(Array)); \ 400b8021494Sopenharmony_ci TEST_FUNCTION(sum_array); \ 401b8021494Sopenharmony_ci VIXL_CHECK(regs.xreg(0) == SumArrayC(Array, ARRAY_SIZE(Array))); \ 402b8021494Sopenharmony_ci } while (0) 403b8021494Sopenharmony_ci 404b8021494Sopenharmony_ciTEST(sum_array) { 405b8021494Sopenharmony_ci START(); 406b8021494Sopenharmony_ci 407b8021494Sopenharmony_ci Label sum_array; 408b8021494Sopenharmony_ci masm.Bind(&sum_array); 409b8021494Sopenharmony_ci GenerateSumArray(&masm); 410b8021494Sopenharmony_ci masm.FinalizeCode(); 411b8021494Sopenharmony_ci 412b8021494Sopenharmony_ci uint8_t data1[] = {4, 9, 13, 3, 2, 6, 5}; 413b8021494Sopenharmony_ci SUM_ARRAY_DOTEST(data1); 414b8021494Sopenharmony_ci 415b8021494Sopenharmony_ci uint8_t data2[] = {42}; 416b8021494Sopenharmony_ci SUM_ARRAY_DOTEST(data2); 417b8021494Sopenharmony_ci 418b8021494Sopenharmony_ci uint8_t data3[1000]; 419b8021494Sopenharmony_ci for (unsigned int i = 0; i < ARRAY_SIZE(data3); ++i) data3[i] = 255; 420b8021494Sopenharmony_ci SUM_ARRAY_DOTEST(data3); 421b8021494Sopenharmony_ci} 422b8021494Sopenharmony_ci 423b8021494Sopenharmony_ci 424b8021494Sopenharmony_ci#define ABS_DOTEST(X) \ 425b8021494Sopenharmony_ci do { \ 426b8021494Sopenharmony_ci simulator.ResetState(); \ 427b8021494Sopenharmony_ci simulator.WriteXRegister(0, X); \ 428b8021494Sopenharmony_ci TEST_FUNCTION(func_abs); \ 429b8021494Sopenharmony_ci VIXL_CHECK(regs.xreg(0) == abs(X)); \ 430b8021494Sopenharmony_ci } while (0) 431b8021494Sopenharmony_ci 432b8021494Sopenharmony_ciTEST(abs) { 433b8021494Sopenharmony_ci START(); 434b8021494Sopenharmony_ci 435b8021494Sopenharmony_ci Label func_abs; 436b8021494Sopenharmony_ci masm.Bind(&func_abs); 437b8021494Sopenharmony_ci GenerateAbs(&masm); 438b8021494Sopenharmony_ci masm.FinalizeCode(); 439b8021494Sopenharmony_ci 440b8021494Sopenharmony_ci ABS_DOTEST(-42); 441b8021494Sopenharmony_ci ABS_DOTEST(0); 442b8021494Sopenharmony_ci ABS_DOTEST(545); 443b8021494Sopenharmony_ci ABS_DOTEST(-428751489); 444b8021494Sopenharmony_ci} 445b8021494Sopenharmony_ci 446b8021494Sopenharmony_ci 447b8021494Sopenharmony_ciTEST(crc32) { 448b8021494Sopenharmony_ci START(); 449b8021494Sopenharmony_ci 450b8021494Sopenharmony_ci Label crc32; 451b8021494Sopenharmony_ci masm.Bind(&crc32); 452b8021494Sopenharmony_ci GenerateCrc32(&masm); 453b8021494Sopenharmony_ci masm.FinalizeCode(); 454b8021494Sopenharmony_ci 455b8021494Sopenharmony_ci const char* msg = "Hello World!"; 456b8021494Sopenharmony_ci uintptr_t msg_addr = reinterpret_cast<uintptr_t>(msg); 457b8021494Sopenharmony_ci size_t msg_size = strlen(msg); 458b8021494Sopenharmony_ci int64_t chksum = INT64_C(0xe3d6e35c); 459b8021494Sopenharmony_ci simulator.WriteXRegister(0, msg_addr); 460b8021494Sopenharmony_ci simulator.WriteXRegister(1, msg_size); 461b8021494Sopenharmony_ci TEST_FUNCTION(crc32); 462b8021494Sopenharmony_ci VIXL_CHECK(regs.xreg(0) == chksum); 463b8021494Sopenharmony_ci} 464b8021494Sopenharmony_ci 465b8021494Sopenharmony_ci 466b8021494Sopenharmony_ciTEST(swap4) { 467b8021494Sopenharmony_ci START(); 468b8021494Sopenharmony_ci 469b8021494Sopenharmony_ci Label swap4; 470b8021494Sopenharmony_ci masm.Bind(&swap4); 471b8021494Sopenharmony_ci GenerateSwap4(&masm); 472b8021494Sopenharmony_ci masm.FinalizeCode(); 473b8021494Sopenharmony_ci 474b8021494Sopenharmony_ci int64_t a = 15; 475b8021494Sopenharmony_ci int64_t b = 26; 476b8021494Sopenharmony_ci int64_t c = 46; 477b8021494Sopenharmony_ci int64_t d = 79; 478b8021494Sopenharmony_ci 479b8021494Sopenharmony_ci simulator.WriteXRegister(0, a); 480b8021494Sopenharmony_ci simulator.WriteXRegister(1, b); 481b8021494Sopenharmony_ci simulator.WriteXRegister(2, c); 482b8021494Sopenharmony_ci simulator.WriteXRegister(3, d); 483b8021494Sopenharmony_ci TEST_FUNCTION(swap4); 484b8021494Sopenharmony_ci VIXL_CHECK(regs.xreg(0) == d); 485b8021494Sopenharmony_ci VIXL_CHECK(regs.xreg(1) == c); 486b8021494Sopenharmony_ci VIXL_CHECK(regs.xreg(2) == b); 487b8021494Sopenharmony_ci VIXL_CHECK(regs.xreg(3) == a); 488b8021494Sopenharmony_ci} 489b8021494Sopenharmony_ci 490b8021494Sopenharmony_ci 491b8021494Sopenharmony_ciTEST(swap_int32) { 492b8021494Sopenharmony_ci START(); 493b8021494Sopenharmony_ci 494b8021494Sopenharmony_ci Label swap_int32; 495b8021494Sopenharmony_ci masm.Bind(&swap_int32); 496b8021494Sopenharmony_ci GenerateSwapInt32(&masm); 497b8021494Sopenharmony_ci masm.FinalizeCode(); 498b8021494Sopenharmony_ci 499b8021494Sopenharmony_ci int32_t x = 168; 500b8021494Sopenharmony_ci int32_t y = 246; 501b8021494Sopenharmony_ci simulator.WriteWRegister(0, x); 502b8021494Sopenharmony_ci simulator.WriteWRegister(1, y); 503b8021494Sopenharmony_ci TEST_FUNCTION(swap_int32); 504b8021494Sopenharmony_ci VIXL_CHECK(regs.wreg(0) == y); 505b8021494Sopenharmony_ci VIXL_CHECK(regs.wreg(1) == x); 506b8021494Sopenharmony_ci} 507b8021494Sopenharmony_ci 508b8021494Sopenharmony_ci 509b8021494Sopenharmony_ci#define CHECKBOUNDS_DOTEST(Value, Low, High) \ 510b8021494Sopenharmony_ci do { \ 511b8021494Sopenharmony_ci simulator.ResetState(); \ 512b8021494Sopenharmony_ci simulator.WriteXRegister(0, Value); \ 513b8021494Sopenharmony_ci simulator.WriteXRegister(1, Low); \ 514b8021494Sopenharmony_ci simulator.WriteXRegister(2, High); \ 515b8021494Sopenharmony_ci TEST_FUNCTION(check_bounds); \ 516b8021494Sopenharmony_ci VIXL_CHECK(regs.xreg(0) == ((Low <= Value) && (Value <= High))); \ 517b8021494Sopenharmony_ci } while (0) 518b8021494Sopenharmony_ci 519b8021494Sopenharmony_ciTEST(check_bounds) { 520b8021494Sopenharmony_ci START(); 521b8021494Sopenharmony_ci 522b8021494Sopenharmony_ci Label check_bounds; 523b8021494Sopenharmony_ci masm.Bind(&check_bounds); 524b8021494Sopenharmony_ci GenerateCheckBounds(&masm); 525b8021494Sopenharmony_ci masm.FinalizeCode(); 526b8021494Sopenharmony_ci 527b8021494Sopenharmony_ci CHECKBOUNDS_DOTEST(0, 100, 200); 528b8021494Sopenharmony_ci CHECKBOUNDS_DOTEST(58, 100, 200); 529b8021494Sopenharmony_ci CHECKBOUNDS_DOTEST(99, 100, 200); 530b8021494Sopenharmony_ci CHECKBOUNDS_DOTEST(100, 100, 200); 531b8021494Sopenharmony_ci CHECKBOUNDS_DOTEST(101, 100, 200); 532b8021494Sopenharmony_ci CHECKBOUNDS_DOTEST(150, 100, 200); 533b8021494Sopenharmony_ci CHECKBOUNDS_DOTEST(199, 100, 200); 534b8021494Sopenharmony_ci CHECKBOUNDS_DOTEST(200, 100, 200); 535b8021494Sopenharmony_ci CHECKBOUNDS_DOTEST(201, 100, 200); 536b8021494Sopenharmony_ci} 537b8021494Sopenharmony_ci 538b8021494Sopenharmony_ci 539b8021494Sopenharmony_ci#define GETTING_STARTED_DOTEST(Value) \ 540b8021494Sopenharmony_ci do { \ 541b8021494Sopenharmony_ci simulator.ResetState(); \ 542b8021494Sopenharmony_ci simulator.WriteXRegister(0, Value); \ 543b8021494Sopenharmony_ci TEST_FUNCTION(demo_function); \ 544b8021494Sopenharmony_ci VIXL_CHECK(regs.xreg(0) == (Value & 0x1122334455667788)); \ 545b8021494Sopenharmony_ci } while (0) 546b8021494Sopenharmony_ci 547b8021494Sopenharmony_ciTEST(getting_started) { 548b8021494Sopenharmony_ci START(); 549b8021494Sopenharmony_ci 550b8021494Sopenharmony_ci Label demo_function; 551b8021494Sopenharmony_ci masm.Bind(&demo_function); 552b8021494Sopenharmony_ci GenerateDemoFunction(&masm); 553b8021494Sopenharmony_ci masm.FinalizeCode(); 554b8021494Sopenharmony_ci 555b8021494Sopenharmony_ci GETTING_STARTED_DOTEST(0x8899aabbccddeeff); 556b8021494Sopenharmony_ci GETTING_STARTED_DOTEST(0x1122334455667788); 557b8021494Sopenharmony_ci GETTING_STARTED_DOTEST(0x0000000000000000); 558b8021494Sopenharmony_ci GETTING_STARTED_DOTEST(0xffffffffffffffff); 559b8021494Sopenharmony_ci GETTING_STARTED_DOTEST(0x5a5a5a5a5a5a5a5a); 560b8021494Sopenharmony_ci} 561b8021494Sopenharmony_ci 562b8021494Sopenharmony_ci 563b8021494Sopenharmony_ciTEST(non_const_visitor) { 564b8021494Sopenharmony_ci MacroAssembler masm; 565b8021494Sopenharmony_ci 566b8021494Sopenharmony_ci Label code_start, code_end; 567b8021494Sopenharmony_ci masm.Bind(&code_start); 568b8021494Sopenharmony_ci GenerateNonConstVisitorTestCode(&masm); 569b8021494Sopenharmony_ci masm.Bind(&code_end); 570b8021494Sopenharmony_ci masm.FinalizeCode(); 571b8021494Sopenharmony_ci Instruction* instr_start = masm.GetLabelAddress<Instruction*>(&code_start); 572b8021494Sopenharmony_ci Instruction* instr_end = masm.GetLabelAddress<Instruction*>(&code_end); 573b8021494Sopenharmony_ci 574b8021494Sopenharmony_ci int64_t res_orig = RunNonConstVisitorTestGeneratedCode(instr_start); 575b8021494Sopenharmony_ci 576b8021494Sopenharmony_ci ModifyNonConstVisitorTestGeneratedCode(instr_start, instr_end); 577b8021494Sopenharmony_ci 578b8021494Sopenharmony_ci int64_t res_mod = RunNonConstVisitorTestGeneratedCode(instr_start); 579b8021494Sopenharmony_ci VIXL_CHECK(res_orig == -res_mod); 580b8021494Sopenharmony_ci} 581b8021494Sopenharmony_ci 582b8021494Sopenharmony_ci 583b8021494Sopenharmony_ciTEST(literal_example) { 584b8021494Sopenharmony_ci VIXL_ASSERT(LiteralExample(1, 2) == 3); 585b8021494Sopenharmony_ci VIXL_ASSERT(LiteralExample(INT64_C(0x100000000), 0x1) == 586b8021494Sopenharmony_ci INT64_C(0x100000001)); 587b8021494Sopenharmony_ci} 588b8021494Sopenharmony_ci 589b8021494Sopenharmony_ci 590b8021494Sopenharmony_ci#ifdef VIXL_HAS_SIMULATED_RUNTIME_CALL_SUPPORT 591b8021494Sopenharmony_ci 592b8021494Sopenharmony_ci// This is an approximation of the result that works for the ranges tested 593b8021494Sopenharmony_ci// below. 594b8021494Sopenharmony_ci#define RUNTIME_CALLS_EXPECTED(A, B) ((A + B) * 4) 595b8021494Sopenharmony_ci 596b8021494Sopenharmony_ci#define RUNTIME_CALLS_DOTEST(A, B) \ 597b8021494Sopenharmony_ci do { \ 598b8021494Sopenharmony_ci simulator.ResetState(); \ 599b8021494Sopenharmony_ci simulator.WriteWRegister(0, A); \ 600b8021494Sopenharmony_ci simulator.WriteWRegister(1, B); \ 601b8021494Sopenharmony_ci TEST_FUNCTION(start); \ 602b8021494Sopenharmony_ci VIXL_CHECK(regs.wreg(0) == RUNTIME_CALLS_EXPECTED(A, B)); \ 603b8021494Sopenharmony_ci } while (0) 604b8021494Sopenharmony_ci 605b8021494Sopenharmony_ciTEST(runtime_calls) { 606b8021494Sopenharmony_ci START(); 607b8021494Sopenharmony_ci 608b8021494Sopenharmony_ci Label start; 609b8021494Sopenharmony_ci masm.Bind(&start); 610b8021494Sopenharmony_ci GenerateRuntimeCallExamples(&masm); 611b8021494Sopenharmony_ci masm.FinalizeCode(); 612b8021494Sopenharmony_ci 613b8021494Sopenharmony_ci RUNTIME_CALLS_DOTEST(0, 0); 614b8021494Sopenharmony_ci RUNTIME_CALLS_DOTEST(1, -2); 615b8021494Sopenharmony_ci RUNTIME_CALLS_DOTEST(123, 456); 616b8021494Sopenharmony_ci} 617b8021494Sopenharmony_ci 618b8021494Sopenharmony_ci#endif // VIXL_HAS_SIMULATED_RUNTIME_CALL_SUPPORT 619b8021494Sopenharmony_ci 620b8021494Sopenharmony_ciTEST(sve_strlen) { 621b8021494Sopenharmony_ci START(); 622b8021494Sopenharmony_ci 623b8021494Sopenharmony_ci CPUFeatures cpu_features(CPUFeatures::kSVE); 624b8021494Sopenharmony_ci masm.SetCPUFeatures(cpu_features); 625b8021494Sopenharmony_ci 626b8021494Sopenharmony_ci Label sve_strlen; 627b8021494Sopenharmony_ci masm.Bind(&sve_strlen); 628b8021494Sopenharmony_ci GenerateSVEStrlen(&masm); 629b8021494Sopenharmony_ci masm.FinalizeCode(); 630b8021494Sopenharmony_ci 631b8021494Sopenharmony_ci if (CanRun(cpu_features)) { 632b8021494Sopenharmony_ci const char* inputs[] = 633b8021494Sopenharmony_ci {"Exactly 15 chrs", 634b8021494Sopenharmony_ci "Exactly 16 chars", 635b8021494Sopenharmony_ci "Exactly 17 chars.", 636b8021494Sopenharmony_ci 637b8021494Sopenharmony_ci "This string is very long and will require multiple iterations, even " 638b8021494Sopenharmony_ci "with the maximum VL (256 bytes). This string is very long and will " 639b8021494Sopenharmony_ci "require multiple iterations, even with the maximum VL (256 bytes). " 640b8021494Sopenharmony_ci "This string is very long and will require multiple iterations, even " 641b8021494Sopenharmony_ci "with the maximum VL (256 bytes)."}; 642b8021494Sopenharmony_ci 643b8021494Sopenharmony_ci for (size_t i = 0; i < ArrayLength(inputs); i++) { 644b8021494Sopenharmony_ci simulator.ResetState(); 645b8021494Sopenharmony_ci simulator.WriteXRegister(0, reinterpret_cast<uintptr_t>(inputs[i])); 646b8021494Sopenharmony_ci TEST_FUNCTION(sve_strlen); 647b8021494Sopenharmony_ci VIXL_CHECK(static_cast<size_t>(regs.xreg(0)) == strlen(inputs[i])); 648b8021494Sopenharmony_ci } 649b8021494Sopenharmony_ci } 650b8021494Sopenharmony_ci} 651b8021494Sopenharmony_ci 652b8021494Sopenharmony_ci#endif // VIXL_INCLUDE_SIMULATOR_AARCH64 653