11123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// Copyright 2014, ARM Limited 21123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// All rights reserved. 31123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// 41123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// Redistribution and use in source and binary forms, with or without 51123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// modification, are permitted provided that the following conditions are met: 61123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// 71123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// * Redistributions of source code must retain the above copyright notice, 81123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// this list of conditions and the following disclaimer. 91123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// * Redistributions in binary form must reproduce the above copyright notice, 101123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// this list of conditions and the following disclaimer in the documentation 111123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// and/or other materials provided with the distribution. 121123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// * Neither the name of ARM Limited nor the names of its contributors may be 131123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// used to endorse or promote products derived from this software without 141123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// specific prior written permission. 151123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// 161123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND 171123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 181123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 191123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 201123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 211123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 221123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 231123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 241123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 251123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 261123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 271123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl#include <stdio.h> 281123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl#include <float.h> 291123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 301123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl#include "cctest.h" 311123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl#include "test-utils-a64.h" 321123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl#include "test-simulator-inputs-a64.h" 331123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl#include "test-simulator-traces-a64.h" 341123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl#include "a64/macro-assembler-a64.h" 351123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl#include "a64/simulator-a64.h" 361123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 371123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixlnamespace vixl { 381123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 391123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// ==== Simulator Tests ==== 401123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// 411123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// These simulator tests check instruction behaviour against a trace taken from 421123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// real AArch64 hardware. The same test code is used to generate the trace; the 431123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// results are printed to stdout when the test is run with --sim_test_trace. 441123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// 451123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// The input lists and expected results are stored in 461123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// test/test-simulator-traces-a64.h. The expected results can be regenerated 471123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// using tools/generate_simulator_traces.py. 481123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 491123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl#define __ masm. 501123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl#define TEST(name) TEST_(SIM_##name) 511123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 521123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl#define BUF_SIZE (256) 531123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 541123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl#ifdef USE_SIMULATOR 551123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 561123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl#define SETUP() \ 571123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl byte* buf = new byte[BUF_SIZE]; \ 581123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl MacroAssembler masm(buf, BUF_SIZE); \ 591123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl Decoder decoder; \ 601123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl Simulator* simulator = NULL; \ 611123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl if (Cctest::run_debugger()) { \ 621123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl simulator = new Debugger(&decoder); \ 631123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } else { \ 641123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl simulator = new Simulator(&decoder); \ 651123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl simulator->set_disasm_trace(Cctest::trace_sim()); \ 661123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } \ 671123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl simulator->set_coloured_trace(Cctest::coloured_trace()); \ 681123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl simulator->set_instruction_stats(Cctest::instruction_stats()); 691123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 701123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl#define START() \ 711123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl masm.Reset(); \ 721123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl simulator->ResetState(); \ 731123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ PushCalleeSavedRegisters(); \ 741123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl if (Cctest::run_debugger()) { \ 751123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl if (Cctest::trace_reg()) { \ 761123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ Trace(LOG_STATE, TRACE_ENABLE); \ 771123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } \ 781123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl if (Cctest::trace_sim()) { \ 791123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ Trace(LOG_DISASM, TRACE_ENABLE); \ 801123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } \ 811123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } \ 821123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl if (Cctest::instruction_stats()) { \ 831123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ EnableInstrumentation(); \ 841123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } 851123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 861123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl#define END() \ 871123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl if (Cctest::instruction_stats()) { \ 881123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ DisableInstrumentation(); \ 891123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } \ 901123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl if (Cctest::run_debugger()) { \ 911123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ Trace(LOG_ALL, TRACE_DISABLE); \ 921123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } \ 931123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ PopCalleeSavedRegisters(); \ 941123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ Ret(); \ 951123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl masm.FinalizeCode() 961123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 971123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl#define RUN() \ 981123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl simulator->RunFrom(reinterpret_cast<Instruction*>(buf)) 991123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 1001123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl#define TEARDOWN() \ 1011123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl delete simulator; \ 1021123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl delete[] buf; 1031123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 1041123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl#else // USE_SIMULATOR 1051123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 1061123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl#define SETUP() \ 1071123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl byte* buf = new byte[BUF_SIZE]; \ 1081123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl MacroAssembler masm(buf, BUF_SIZE); \ 1091123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl CPU::SetUp() 1101123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 1111123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl#define START() \ 1121123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl masm.Reset(); \ 1131123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ PushCalleeSavedRegisters() 1141123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 1151123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl#define END() \ 1161123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ PopCalleeSavedRegisters(); \ 1171123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ Ret(); \ 1181123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl masm.FinalizeCode() 1191123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 1201123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl#define RUN() \ 1211123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl CPU::EnsureIAndDCacheCoherency(buf, BUF_SIZE); \ 1221123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl { \ 1231123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl void (*test_function)(void); \ 1241123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(sizeof(buf) == sizeof(test_function)); \ 1251123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl memcpy(&test_function, &buf, sizeof(buf)); \ 1261123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl test_function(); \ 1271123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } 1281123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 1291123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl#define TEARDOWN() \ 1301123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl delete[] buf; 1311123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 1321123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl#endif // USE_SIMULATOR 1331123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 1341123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 1351123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// The maximum number of errors to report in detail for each test. 1361123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixlstatic const unsigned kErrorReportLimit = 8; 1371123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 1381123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 139ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// Overloaded versions of rawbits_to_double and rawbits_to_float for use in the 140ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// templated test functions. 141ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlstatic float rawbits_to_fp(uint32_t bits) { 142ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl return rawbits_to_float(bits); 143ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl} 144ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 145ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlstatic double rawbits_to_fp(uint64_t bits) { 146ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl return rawbits_to_double(bits); 147ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl} 148ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 149ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 1501123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// MacroAssembler member function pointers to pass to the test dispatchers. 1511123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixltypedef void (MacroAssembler::*Test1OpFPHelper_t)(const FPRegister& fd, 1521123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl const FPRegister& fn); 1531123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixltypedef void (MacroAssembler::*Test2OpFPHelper_t)(const FPRegister& fd, 1541123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl const FPRegister& fn, 1551123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl const FPRegister& fm); 1561123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixltypedef void (MacroAssembler::*Test3OpFPHelper_t)(const FPRegister& fd, 1571123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl const FPRegister& fn, 1581123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl const FPRegister& fm, 1591123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl const FPRegister& fa); 160ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixltypedef void (MacroAssembler::*TestFPCmpHelper_t)(const FPRegister& fn, 161ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const FPRegister& fm); 162ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixltypedef void (MacroAssembler::*TestFPCmpZeroHelper_t)(const FPRegister& fn, 163ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl double value); 164ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixltypedef void (MacroAssembler::*TestFPToIntHelper_t)(const Register& rd, 165ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const FPRegister& fn); 166ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixltypedef void (MacroAssembler::*TestFixedToFPHelper_t)(const FPRegister& fd, 167ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const Register& rn, 168ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl unsigned fbits); 1691123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 1701123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// Standard test dispatchers. 1711123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 1721123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 173ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlstatic void Test1Op_Helper(Test1OpFPHelper_t helper, uintptr_t inputs, 174ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl unsigned inputs_length, uintptr_t results, 175ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl unsigned d_size, unsigned n_size) { 176ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl VIXL_ASSERT((d_size == kDRegSize) || (d_size == kSRegSize)); 177ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl VIXL_ASSERT((n_size == kDRegSize) || (n_size == kSRegSize)); 1781123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 1791123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl SETUP(); 1801123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl START(); 1811123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 1821123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // Roll up the loop to keep the code size down. 183ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl Label loop_n; 1841123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 1851123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl Register out = x0; 1861123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl Register inputs_base = x1; 1871123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl Register length = w2; 1881123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl Register index_n = w3; 1891123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 190ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const int n_index_shift = 191ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl (n_size == kDRegSize) ? kDRegSizeInBytesLog2 : kSRegSizeInBytesLog2; 1921123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 193ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl FPRegister fd = (d_size == kDRegSize) ? d0 : s0; 194ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl FPRegister fn = (n_size == kDRegSize) ? d1 : s1; 1951123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 1961123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ Mov(out, results); 1971123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ Mov(inputs_base, inputs); 1981123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ Mov(length, inputs_length); 1991123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 2001123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ Mov(index_n, 0); 2011123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ Bind(&loop_n); 202ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Ldr(fn, MemOperand(inputs_base, index_n, UXTW, n_index_shift)); 2031123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 204ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl (masm.*helper)(fd, fn); 2051123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ Str(fd, MemOperand(out, fd.SizeInBytes(), PostIndex)); 2061123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 2071123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ Add(index_n, index_n, 1); 2081123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ Cmp(index_n, inputs_length); 2091123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ B(lo, &loop_n); 2101123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 2111123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl END(); 2121123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl RUN(); 2131123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl TEARDOWN(); 2141123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl} 2151123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 2161123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 217ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// Test FP instructions. The inputs[] and expected[] arrays should be arrays of 218ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// rawbits representations of doubles or floats. This ensures that exact bit 2191123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// comparisons can be performed. 220ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixltemplate <typename Tn, typename Td> 221ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlstatic void Test1Op(const char * name, Test1OpFPHelper_t helper, 222ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const Tn inputs[], unsigned inputs_length, 223ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const Td expected[], unsigned expected_length) { 2241123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(inputs_length > 0); 2251123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 226ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const unsigned results_length = inputs_length; 227ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl Td * results = new Td[results_length]; 2281123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 229ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const unsigned d_bits = sizeof(Td) * 8; 230ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const unsigned n_bits = sizeof(Tn) * 8; 231ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 232ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl Test1Op_Helper(helper, reinterpret_cast<uintptr_t>(inputs), inputs_length, 233ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl reinterpret_cast<uintptr_t>(results), d_bits, n_bits); 2341123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 2351123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl if (Cctest::sim_test_trace()) { 2361123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // Print the results. 237ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf("const uint%u_t kExpected_%s[] = {\n", d_bits, name); 2381123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl for (unsigned d = 0; d < results_length; d++) { 239ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf(" 0x%0*" PRIx64 ",\n", 240ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl d_bits / 4, static_cast<uint64_t>(results[d])); 2411123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } 2421123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl printf("};\n"); 243ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf("const unsigned kExpectedCount_%s = %u;\n", name, results_length); 2441123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } else { 2451123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // Check the results. 2461123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_CHECK(expected_length == results_length); 2471123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl unsigned error_count = 0; 2481123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl unsigned d = 0; 249ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl for (unsigned n = 0; n < inputs_length; n++, d++) { 250ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl if (results[d] != expected[d]) { 251ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl if (++error_count > kErrorReportLimit) continue; 252ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 253ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf("%s 0x%0*" PRIx64 " (%s %g):\n", 254ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl name, n_bits / 4, static_cast<uint64_t>(inputs[n]), 255ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl name, rawbits_to_fp(inputs[n])); 256ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf(" Expected: 0x%0*" PRIx64 " (%g)\n", 257ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl d_bits / 4, static_cast<uint64_t>(expected[d]), 258ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl rawbits_to_fp(expected[d])); 259ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf(" Found: 0x%0*" PRIx64 " (%g)\n", 260ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl d_bits / 4, static_cast<uint64_t>(results[d]), 261ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl rawbits_to_fp(results[d])); 262ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf("\n"); 2631123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } 2641123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } 2651123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(d == expected_length); 2661123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl if (error_count > kErrorReportLimit) { 2671123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl printf("%u other errors follow.\n", error_count - kErrorReportLimit); 2681123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } 2691123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_CHECK(error_count == 0); 2701123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } 2711123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl delete[] results; 2721123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl} 2731123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 2741123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 275ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlstatic void Test2Op_Helper(Test2OpFPHelper_t helper, 276ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl uintptr_t inputs, unsigned inputs_length, 277ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl uintptr_t results, unsigned reg_size) { 278ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl VIXL_ASSERT((reg_size == kDRegSize) || (reg_size == kSRegSize)); 279ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 280ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl SETUP(); 281ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl START(); 282ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 283ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl // Roll up the loop to keep the code size down. 284ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl Label loop_n, loop_m; 285ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 286ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl Register out = x0; 287ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl Register inputs_base = x1; 288ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl Register length = w2; 289ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl Register index_n = w3; 290ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl Register index_m = w4; 291ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 292ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl bool double_op = reg_size == kDRegSize; 293ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const int index_shift = 294ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl double_op ? kDRegSizeInBytesLog2 : kSRegSizeInBytesLog2; 295ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 296ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl FPRegister fd = double_op ? d0 : s0; 297ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl FPRegister fn = double_op ? d1 : s1; 298ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl FPRegister fm = double_op ? d2 : s2; 299ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 300ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Mov(out, results); 301ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Mov(inputs_base, inputs); 302ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Mov(length, inputs_length); 303ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 304ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Mov(index_n, 0); 305ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Bind(&loop_n); 306ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Ldr(fn, MemOperand(inputs_base, index_n, UXTW, index_shift)); 307ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 308ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Mov(index_m, 0); 309ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Bind(&loop_m); 310ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Ldr(fm, MemOperand(inputs_base, index_m, UXTW, index_shift)); 311ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 312ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl (masm.*helper)(fd, fn, fm); 313ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Str(fd, MemOperand(out, fd.SizeInBytes(), PostIndex)); 314ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 315ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Add(index_m, index_m, 1); 316ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Cmp(index_m, inputs_length); 317ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ B(lo, &loop_m); 318ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 319ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Add(index_n, index_n, 1); 320ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Cmp(index_n, inputs_length); 321ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ B(lo, &loop_n); 322ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 323ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl END(); 324ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl RUN(); 325ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl TEARDOWN(); 326ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl} 327ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 328ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 329ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// Test FP instructions. The inputs[] and expected[] arrays should be arrays of 330ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// rawbits representations of doubles or floats. This ensures that exact bit 3311123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// comparisons can be performed. 332ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixltemplate <typename T> 3331123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixlstatic void Test2Op(const char * name, Test2OpFPHelper_t helper, 334ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const T inputs[], unsigned inputs_length, 335ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const T expected[], unsigned expected_length) { 3361123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(inputs_length > 0); 3371123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 338ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const unsigned results_length = inputs_length * inputs_length; 339ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl T * results = new T[results_length]; 340ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 341ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const unsigned bits = sizeof(T) * 8; 3421123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 3431123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl Test2Op_Helper(helper, reinterpret_cast<uintptr_t>(inputs), inputs_length, 344ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl reinterpret_cast<uintptr_t>(results), bits); 3451123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 3461123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl if (Cctest::sim_test_trace()) { 3471123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // Print the results. 348ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf("const uint%u_t kExpected_%s[] = {\n", bits, name); 3491123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl for (unsigned d = 0; d < results_length; d++) { 350ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf(" 0x%0*" PRIx64 ",\n", 351ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl bits / 4, static_cast<uint64_t>(results[d])); 3521123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } 3531123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl printf("};\n"); 354ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf("const unsigned kExpectedCount_%s = %u;\n", name, results_length); 3551123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } else { 3561123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // Check the results. 3571123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_CHECK(expected_length == results_length); 3581123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl unsigned error_count = 0; 3591123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl unsigned d = 0; 3601123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl for (unsigned n = 0; n < inputs_length; n++) { 3611123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl for (unsigned m = 0; m < inputs_length; m++, d++) { 3621123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl if (results[d] != expected[d]) { 3631123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl if (++error_count > kErrorReportLimit) continue; 3641123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 365ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf("%s 0x%0*" PRIx64 ", 0x%0*" PRIx64 " (%s %g %g):\n", 3661123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl name, 367ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl bits / 4, static_cast<uint64_t>(inputs[n]), 368ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl bits / 4, static_cast<uint64_t>(inputs[m]), 369ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl name, 370ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl rawbits_to_fp(inputs[n]), 371ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl rawbits_to_fp(inputs[m])); 372ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf(" Expected: 0x%0*" PRIx64 " (%g)\n", 373ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl bits / 4, static_cast<uint64_t>(expected[d]), 374ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl rawbits_to_fp(expected[d])); 375ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf(" Found: 0x%0*" PRIx64 " (%g)\n", 376ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl bits / 4, static_cast<uint64_t>(results[d]), 377ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl rawbits_to_fp(results[d])); 3781123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl printf("\n"); 3791123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } 3801123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } 3811123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } 3821123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(d == expected_length); 3831123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl if (error_count > kErrorReportLimit) { 3841123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl printf("%u other errors follow.\n", error_count - kErrorReportLimit); 3851123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } 3861123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_CHECK(error_count == 0); 3871123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } 3881123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl delete[] results; 3891123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl} 3901123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 3911123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 3921123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixlstatic void Test3Op_Helper(Test3OpFPHelper_t helper, 3931123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl uintptr_t inputs, unsigned inputs_length, 3941123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl uintptr_t results, unsigned reg_size) { 3951123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT((reg_size == kDRegSize) || (reg_size == kSRegSize)); 3961123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 3971123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl SETUP(); 3981123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl START(); 3991123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 4001123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // Roll up the loop to keep the code size down. 4011123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl Label loop_n, loop_m, loop_a; 4021123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 4031123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl Register out = x0; 4041123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl Register inputs_base = x1; 4051123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl Register length = w2; 4061123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl Register index_n = w3; 4071123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl Register index_m = w4; 4081123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl Register index_a = w5; 4091123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 4101123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl bool double_op = reg_size == kDRegSize; 4111123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl const int index_shift = 4121123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl double_op ? kDRegSizeInBytesLog2 : kSRegSizeInBytesLog2; 4131123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 4141123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl FPRegister fd = double_op ? d0 : s0; 4151123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl FPRegister fn = double_op ? d1 : s1; 4161123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl FPRegister fm = double_op ? d2 : s2; 4171123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl FPRegister fa = double_op ? d3 : s3; 4181123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 4191123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ Mov(out, results); 4201123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ Mov(inputs_base, inputs); 4211123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ Mov(length, inputs_length); 4221123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 4231123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ Mov(index_n, 0); 4241123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ Bind(&loop_n); 4251123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ Ldr(fn, MemOperand(inputs_base, index_n, UXTW, index_shift)); 4261123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 4271123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ Mov(index_m, 0); 4281123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ Bind(&loop_m); 4291123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ Ldr(fm, MemOperand(inputs_base, index_m, UXTW, index_shift)); 4301123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 4311123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ Mov(index_a, 0); 4321123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ Bind(&loop_a); 4331123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ Ldr(fa, MemOperand(inputs_base, index_a, UXTW, index_shift)); 4341123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 4351123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl (masm.*helper)(fd, fn, fm, fa); 4361123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ Str(fd, MemOperand(out, fd.SizeInBytes(), PostIndex)); 4371123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 4381123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ Add(index_a, index_a, 1); 4391123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ Cmp(index_a, inputs_length); 4401123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ B(lo, &loop_a); 4411123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 4421123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ Add(index_m, index_m, 1); 4431123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ Cmp(index_m, inputs_length); 4441123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ B(lo, &loop_m); 4451123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 4461123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ Add(index_n, index_n, 1); 4471123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ Cmp(index_n, inputs_length); 4481123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl __ B(lo, &loop_n); 4491123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 4501123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl END(); 4511123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl RUN(); 4521123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl TEARDOWN(); 4531123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl} 4541123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 4551123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 456ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// Test FP instructions. The inputs[] and expected[] arrays should be arrays of 457ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// rawbits representations of doubles or floats. This ensures that exact bit 4581123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// comparisons can be performed. 459ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixltemplate <typename T> 4601123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixlstatic void Test3Op(const char * name, Test3OpFPHelper_t helper, 461ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const T inputs[], unsigned inputs_length, 462ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const T expected[], unsigned expected_length) { 4631123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(inputs_length > 0); 4641123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 465ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const unsigned results_length = inputs_length * inputs_length * inputs_length; 466ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl T * results = new T[results_length]; 467ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 468ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const unsigned bits = sizeof(T) * 8; 4691123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 4701123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl Test3Op_Helper(helper, reinterpret_cast<uintptr_t>(inputs), inputs_length, 471ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl reinterpret_cast<uintptr_t>(results), bits); 4721123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 4731123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl if (Cctest::sim_test_trace()) { 4741123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // Print the results. 475ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf("const uint%u_t kExpected_%s[] = {\n", bits, name); 4761123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl for (unsigned d = 0; d < results_length; d++) { 477ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf(" 0x%0*" PRIx64 ",\n", 478ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl bits / 4, static_cast<uint64_t>(results[d])); 4791123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } 4801123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl printf("};\n"); 481ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf("const unsigned kExpectedCount_%s = %u;\n", name, results_length); 4821123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } else { 4831123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // Check the results. 4841123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_CHECK(expected_length == results_length); 4851123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl unsigned error_count = 0; 4861123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl unsigned d = 0; 4871123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl for (unsigned n = 0; n < inputs_length; n++) { 4881123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl for (unsigned m = 0; m < inputs_length; m++) { 4891123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl for (unsigned a = 0; a < inputs_length; a++, d++) { 4901123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl if (results[d] != expected[d]) { 4911123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl if (++error_count > kErrorReportLimit) continue; 4921123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 493ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf("%s 0x%0*" PRIx64 ", 0x%0*" PRIx64 ", 0x%0*" PRIx64 494ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl " (%s %g %g %g):\n", 4951123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl name, 496ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl bits / 4, static_cast<uint64_t>(inputs[n]), 497ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl bits / 4, static_cast<uint64_t>(inputs[m]), 498ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl bits / 4, static_cast<uint64_t>(inputs[a]), 499ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl name, 500ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl rawbits_to_fp(inputs[n]), 501ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl rawbits_to_fp(inputs[m]), 502ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl rawbits_to_fp(inputs[a])); 503ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf(" Expected: 0x%0*" PRIx64 " (%g)\n", 504ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl bits / 4, static_cast<uint64_t>(expected[d]), 505ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl rawbits_to_fp(expected[d])); 506ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf(" Found: 0x%0*" PRIx64 " (%g)\n", 507ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl bits / 4, static_cast<uint64_t>(results[d]), 508ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl rawbits_to_fp(results[d])); 5091123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl printf("\n"); 5101123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } 5111123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } 5121123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } 5131123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } 5141123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(d == expected_length); 5151123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl if (error_count > kErrorReportLimit) { 5161123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl printf("%u other errors follow.\n", error_count - kErrorReportLimit); 5171123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } 5181123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_CHECK(error_count == 0); 5191123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } 5201123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl delete[] results; 5211123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl} 5221123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 5231123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 524ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlstatic void TestCmp_Helper(TestFPCmpHelper_t helper, 525ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl uintptr_t inputs, unsigned inputs_length, 526ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl uintptr_t results, unsigned reg_size) { 527ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl VIXL_ASSERT((reg_size == kDRegSize) || (reg_size == kSRegSize)); 528ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 529ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl SETUP(); 530ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl START(); 531ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 532ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl // Roll up the loop to keep the code size down. 533ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl Label loop_n, loop_m; 534ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 535ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl Register out = x0; 536ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl Register inputs_base = x1; 537ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl Register length = w2; 538ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl Register index_n = w3; 539ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl Register index_m = w4; 540ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl Register flags = x5; 541ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 542ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl bool double_op = reg_size == kDRegSize; 543ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const int index_shift = 544ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl double_op ? kDRegSizeInBytesLog2 : kSRegSizeInBytesLog2; 545ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 546ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl FPRegister fn = double_op ? d1 : s1; 547ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl FPRegister fm = double_op ? d2 : s2; 548ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 549ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Mov(out, results); 550ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Mov(inputs_base, inputs); 551ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Mov(length, inputs_length); 552ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 553ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Mov(index_n, 0); 554ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Bind(&loop_n); 555ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Ldr(fn, MemOperand(inputs_base, index_n, UXTW, index_shift)); 556ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 557ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Mov(index_m, 0); 558ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Bind(&loop_m); 559ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Ldr(fm, MemOperand(inputs_base, index_m, UXTW, index_shift)); 560ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 561ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl (masm.*helper)(fn, fm); 562ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Mrs(flags, NZCV); 563ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Ubfx(flags, flags, 28, 4); 564ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Strb(flags, MemOperand(out, 1, PostIndex)); 565ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 566ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Add(index_m, index_m, 1); 567ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Cmp(index_m, inputs_length); 568ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ B(lo, &loop_m); 569ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 570ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Add(index_n, index_n, 1); 571ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Cmp(index_n, inputs_length); 572ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ B(lo, &loop_n); 573ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 574ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl END(); 575ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl RUN(); 576ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl TEARDOWN(); 577ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl} 578ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 579ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 580ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// Test FP instructions. The inputs[] and expected[] arrays should be arrays of 581ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// rawbits representations of doubles or floats. This ensures that exact bit 5821123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// comparisons can be performed. 583ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixltemplate <typename T> 584ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlstatic void TestCmp(const char * name, TestFPCmpHelper_t helper, 585ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const T inputs[], unsigned inputs_length, 586ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const uint8_t expected[], unsigned expected_length) { 5871123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(inputs_length > 0); 5881123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 589ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const unsigned results_length = inputs_length * inputs_length; 590ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl uint8_t * results = new uint8_t[results_length]; 5911123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 592ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const unsigned bits = sizeof(T) * 8; 593ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 594ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl TestCmp_Helper(helper, reinterpret_cast<uintptr_t>(inputs), inputs_length, 595ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl reinterpret_cast<uintptr_t>(results), bits); 5961123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 5971123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl if (Cctest::sim_test_trace()) { 5981123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // Print the results. 599ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf("const uint8_t kExpected_%s[] = {\n", name); 6001123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl for (unsigned d = 0; d < results_length; d++) { 601ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl // Each NZCV result only requires 4 bits. 602ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl VIXL_ASSERT((results[d] & 0xf) == results[d]); 603ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf(" 0x%" PRIx8 ",\n", results[d]); 6041123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } 6051123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl printf("};\n"); 606ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf("const unsigned kExpectedCount_%s = %u;\n", name, results_length); 6071123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } else { 6081123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl // Check the results. 6091123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_CHECK(expected_length == results_length); 6101123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl unsigned error_count = 0; 6111123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl unsigned d = 0; 6121123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl for (unsigned n = 0; n < inputs_length; n++) { 613ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl for (unsigned m = 0; m < inputs_length; m++, d++) { 614ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl if (results[d] != expected[d]) { 615ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl if (++error_count > kErrorReportLimit) continue; 6161123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 617ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf("%s 0x%0*" PRIx64 ", 0x%0*" PRIx64 " (%s %g %g):\n", 618ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl name, 619ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl bits / 4, static_cast<uint64_t>(inputs[n]), 620ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl bits / 4, static_cast<uint64_t>(inputs[m]), 621ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl name, 622ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl rawbits_to_fp(inputs[n]), 623ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl rawbits_to_fp(inputs[m])); 624ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf(" Expected: %c%c%c%c (0x%" PRIx8 ")\n", 625ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl (expected[d] & 0x8) ? 'N' : 'n', 626ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl (expected[d] & 0x4) ? 'Z' : 'z', 627ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl (expected[d] & 0x2) ? 'C' : 'c', 628ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl (expected[d] & 0x1) ? 'V' : 'v', 629ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl expected[d]); 630ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf(" Found: %c%c%c%c (0x%" PRIx8 ")\n", 631ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl (results[d] & 0x8) ? 'N' : 'n', 632ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl (results[d] & 0x4) ? 'Z' : 'z', 633ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl (results[d] & 0x2) ? 'C' : 'c', 634ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl (results[d] & 0x1) ? 'V' : 'v', 635ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl results[d]); 636ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf("\n"); 6371123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } 6381123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } 6391123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } 6401123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(d == expected_length); 6411123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl if (error_count > kErrorReportLimit) { 6421123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl printf("%u other errors follow.\n", error_count - kErrorReportLimit); 6431123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } 6441123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_CHECK(error_count == 0); 6451123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } 6461123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl delete[] results; 6471123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl} 6481123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 6491123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 650ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlstatic void TestCmpZero_Helper(TestFPCmpZeroHelper_t helper, 651ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl uintptr_t inputs, unsigned inputs_length, 652ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl uintptr_t results, unsigned reg_size) { 653ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl VIXL_ASSERT((reg_size == kDRegSize) || (reg_size == kSRegSize)); 6541123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 655ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl SETUP(); 656ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl START(); 6571123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 658ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl // Roll up the loop to keep the code size down. 659ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl Label loop_n, loop_m; 660ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 661ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl Register out = x0; 662ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl Register inputs_base = x1; 663ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl Register length = w2; 664ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl Register index_n = w3; 665ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl Register flags = x4; 666ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 667ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl bool double_op = reg_size == kDRegSize; 668ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const int index_shift = 669ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl double_op ? kDRegSizeInBytesLog2 : kSRegSizeInBytesLog2; 670ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 671ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl FPRegister fn = double_op ? d1 : s1; 672ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 673ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Mov(out, results); 674ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Mov(inputs_base, inputs); 675ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Mov(length, inputs_length); 676ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 677ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Mov(index_n, 0); 678ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Bind(&loop_n); 679ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Ldr(fn, MemOperand(inputs_base, index_n, UXTW, index_shift)); 680ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 681ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl (masm.*helper)(fn, 0.0); 682ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Mrs(flags, NZCV); 683ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Ubfx(flags, flags, 28, 4); 684ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Strb(flags, MemOperand(out, 1, PostIndex)); 685ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 686ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Add(index_n, index_n, 1); 687ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Cmp(index_n, inputs_length); 688ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ B(lo, &loop_n); 689ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 690ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl END(); 691ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl RUN(); 692ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl TEARDOWN(); 693ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl} 694ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 695ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 696ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// Test FP instructions. The inputs[] and expected[] arrays should be arrays of 697ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// rawbits representations of doubles or floats. This ensures that exact bit 698ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// comparisons can be performed. 699ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixltemplate <typename T> 700ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlstatic void TestCmpZero(const char * name, TestFPCmpZeroHelper_t helper, 701ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const T inputs[], unsigned inputs_length, 702ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const uint8_t expected[], unsigned expected_length) { 703ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl VIXL_ASSERT(inputs_length > 0); 704ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 705ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const unsigned results_length = inputs_length; 706ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl uint8_t * results = new uint8_t[results_length]; 707ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 708ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const unsigned bits = sizeof(T) * 8; 709ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 710ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl TestCmpZero_Helper(helper, reinterpret_cast<uintptr_t>(inputs), inputs_length, 711ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl reinterpret_cast<uintptr_t>(results), bits); 712ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 713ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl if (Cctest::sim_test_trace()) { 714ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl // Print the results. 715ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf("const uint8_t kExpected_%s[] = {\n", name); 716ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl for (unsigned d = 0; d < results_length; d++) { 717ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl // Each NZCV result only requires 4 bits. 718ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl VIXL_ASSERT((results[d] & 0xf) == results[d]); 719ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf(" 0x%" PRIx8 ",\n", results[d]); 7201123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl } 721ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf("};\n"); 722ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf("const unsigned kExpectedCount_%s = %u;\n", name, results_length); 723ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl } else { 724ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl // Check the results. 725ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl VIXL_CHECK(expected_length == results_length); 726ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl unsigned error_count = 0; 727ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl unsigned d = 0; 728ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl for (unsigned n = 0; n < inputs_length; n++, d++) { 729ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl if (results[d] != expected[d]) { 730ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl if (++error_count > kErrorReportLimit) continue; 731ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 732ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf("%s 0x%0*" PRIx64 ", 0x%0*u (%s %g #0.0):\n", 733ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl name, 734ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl bits / 4, static_cast<uint64_t>(inputs[n]), 735ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl bits / 4, 0, 736ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl name, 737ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl rawbits_to_fp(inputs[n])); 738ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf(" Expected: %c%c%c%c (0x%" PRIx8 ")\n", 739ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl (expected[d] & 0x8) ? 'N' : 'n', 740ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl (expected[d] & 0x4) ? 'Z' : 'z', 741ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl (expected[d] & 0x2) ? 'C' : 'c', 742ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl (expected[d] & 0x1) ? 'V' : 'v', 743ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl expected[d]); 744ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf(" Found: %c%c%c%c (0x%" PRIx8 ")\n", 745ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl (results[d] & 0x8) ? 'N' : 'n', 746ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl (results[d] & 0x4) ? 'Z' : 'z', 747ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl (results[d] & 0x2) ? 'C' : 'c', 748ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl (results[d] & 0x1) ? 'V' : 'v', 749ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl results[d]); 750ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf("\n"); 751ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl } 752ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl } 753ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl VIXL_ASSERT(d == expected_length); 754ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl if (error_count > kErrorReportLimit) { 755ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf("%u other errors follow.\n", error_count - kErrorReportLimit); 756ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl } 757ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl VIXL_CHECK(error_count == 0); 758ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl } 759ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl delete[] results; 760ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl} 7611123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 7621123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 763ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlstatic void TestFPToInt_Helper(TestFPToIntHelper_t helper, uintptr_t inputs, 764ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl unsigned inputs_length, uintptr_t results, 765ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl unsigned d_size, unsigned n_size) { 766ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl VIXL_ASSERT((d_size == kXRegSize) || (d_size == kWRegSize)); 767ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl VIXL_ASSERT((n_size == kDRegSize) || (n_size == kSRegSize)); 7681123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 769ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl SETUP(); 770ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl START(); 771ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 772ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl // Roll up the loop to keep the code size down. 773ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl Label loop_n; 774ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 775ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl Register out = x0; 776ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl Register inputs_base = x1; 777ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl Register length = w2; 778ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl Register index_n = w3; 779ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 780ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const int n_index_shift = 781ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl (n_size == kDRegSize) ? kDRegSizeInBytesLog2 : kSRegSizeInBytesLog2; 782ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 783ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl Register rd = (d_size == kXRegSize) ? x10 : w10; 784ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl FPRegister fn = (n_size == kDRegSize) ? d1 : s1; 785ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 786ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Mov(out, results); 787ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Mov(inputs_base, inputs); 788ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Mov(length, inputs_length); 789ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 790ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Mov(index_n, 0); 791ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Bind(&loop_n); 792ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Ldr(fn, MemOperand(inputs_base, index_n, UXTW, n_index_shift)); 793ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 794ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl (masm.*helper)(rd, fn); 795ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Str(rd, MemOperand(out, rd.SizeInBytes(), PostIndex)); 796ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 797ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Add(index_n, index_n, 1); 798ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ Cmp(index_n, inputs_length); 799ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl __ B(lo, &loop_n); 800ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 801ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl END(); 802ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl RUN(); 803ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl TEARDOWN(); 804ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl} 8051123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 8061123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 807ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// Test FP instructions. 808ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// - The inputs[] array should be an array of rawbits representations of 809ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// doubles or floats. This ensures that exact bit comparisons can be 810ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// performed. 811ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// - The expected[] array should be an array of signed integers. 812ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixltemplate <typename Tn, typename Td> 813ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlstatic void TestFPToS(const char * name, TestFPToIntHelper_t helper, 814ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const Tn inputs[], unsigned inputs_length, 815ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const Td expected[], unsigned expected_length) { 816ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl VIXL_ASSERT(inputs_length > 0); 8171123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 818ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const unsigned results_length = inputs_length; 819ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl Td * results = new Td[results_length]; 8201123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 821ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const unsigned d_bits = sizeof(Td) * 8; 822ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const unsigned n_bits = sizeof(Tn) * 8; 8231123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 824ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl TestFPToInt_Helper(helper, reinterpret_cast<uintptr_t>(inputs), inputs_length, 825ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl reinterpret_cast<uintptr_t>(results), d_bits, n_bits); 8261123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 827ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl if (Cctest::sim_test_trace()) { 828ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl // Print the results. 829ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf("const int%u_t kExpected_%s[] = {\n", d_bits, name); 830ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl // There is no simple C++ literal for INT*_MIN that doesn't produce 831ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl // warnings, so we use an appropriate constant in that case instead. 832ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl // Deriving int_d_min in this way (rather than just checking INT64_MIN and 833ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl // the like) avoids warnings about comparing values with differing ranges. 834ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const int64_t int_d_max = (UINT64_C(1) << (d_bits - 1)) - 1; 835ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const int64_t int_d_min = -(int_d_max) - 1; 836ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl for (unsigned d = 0; d < results_length; d++) { 837ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl if (results[d] == int_d_min) { 838ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf(" -INT%u_C(%" PRId64 ") - 1,\n", d_bits, int_d_max); 839ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl } else { 840ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf(" %" PRId64 ",\n", static_cast<int64_t>(results[d])); 841ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl } 842ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl } 843ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf("};\n"); 844ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf("const unsigned kExpectedCount_%s = %u;\n", name, results_length); 845ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl } else { 846ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl // Check the results. 847ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl VIXL_CHECK(expected_length == results_length); 848ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl unsigned error_count = 0; 849ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl unsigned d = 0; 850ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl for (unsigned n = 0; n < inputs_length; n++, d++) { 851ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl if (results[d] != expected[d]) { 852ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl if (++error_count > kErrorReportLimit) continue; 853ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 854ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf("%s 0x%0*" PRIx64 " (%s %g):\n", 855ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl name, n_bits / 4, static_cast<uint64_t>(inputs[n]), 856ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl name, rawbits_to_fp(inputs[n])); 857ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf(" Expected: 0x%0*" PRIx64 " (%" PRId64 ")\n", 858ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl d_bits / 4, static_cast<uint64_t>(expected[d]), 859ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl static_cast<int64_t>(expected[d])); 860ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf(" Found: 0x%0*" PRIx64 " (%" PRId64 ")\n", 861ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl d_bits / 4, static_cast<uint64_t>(results[d]), 862ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl static_cast<int64_t>(results[d])); 863ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf("\n"); 864ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl } 865ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl } 866ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl VIXL_ASSERT(d == expected_length); 867ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl if (error_count > kErrorReportLimit) { 868ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf("%u other errors follow.\n", error_count - kErrorReportLimit); 869ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl } 870ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl VIXL_CHECK(error_count == 0); 871ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl } 872ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl delete[] results; 873ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl} 8741123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 8751123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 876ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// Test FP instructions. 877ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// - The inputs[] array should be an array of rawbits representations of 878ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// doubles or floats. This ensures that exact bit comparisons can be 879ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// performed. 880ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// - The expected[] array should be an array of unsigned integers. 881ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixltemplate <typename Tn, typename Td> 882ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlstatic void TestFPToU(const char * name, TestFPToIntHelper_t helper, 883ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const Tn inputs[], unsigned inputs_length, 884ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const Td expected[], unsigned expected_length) { 885ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl VIXL_ASSERT(inputs_length > 0); 886ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 887ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const unsigned results_length = inputs_length; 888ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl Td * results = new Td[results_length]; 889ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 890ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const unsigned d_bits = sizeof(Td) * 8; 891ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl const unsigned n_bits = sizeof(Tn) * 8; 892ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 893ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl TestFPToInt_Helper(helper, reinterpret_cast<uintptr_t>(inputs), inputs_length, 894ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl reinterpret_cast<uintptr_t>(results), d_bits, n_bits); 895ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 896ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl if (Cctest::sim_test_trace()) { 897ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl // Print the results. 898ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf("const uint%u_t kExpected_%s[] = {\n", d_bits, name); 899ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl for (unsigned d = 0; d < results_length; d++) { 900ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf(" %" PRIu64 "u,\n", static_cast<uint64_t>(results[d])); 901ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl } 902ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf("};\n"); 903ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf("const unsigned kExpectedCount_%s = %u;\n", name, results_length); 904ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl } else { 905ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl // Check the results. 906ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl VIXL_CHECK(expected_length == results_length); 907ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl unsigned error_count = 0; 908ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl unsigned d = 0; 909ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl for (unsigned n = 0; n < inputs_length; n++, d++) { 910ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl if (results[d] != expected[d]) { 911ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl if (++error_count > kErrorReportLimit) continue; 912ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 913ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf("%s 0x%0*" PRIx64 " (%s %g):\n", 914ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl name, n_bits / 4, static_cast<uint64_t>(inputs[n]), 915ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl name, rawbits_to_fp(inputs[n])); 916ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf(" Expected: 0x%0*" PRIx64 " (%" PRIu64 ")\n", 917ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl d_bits / 4, static_cast<uint64_t>(expected[d]), 918ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl static_cast<uint64_t>(expected[d])); 919ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf(" Found: 0x%0*" PRIx64 " (%" PRIu64 ")\n", 920ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl d_bits / 4, static_cast<uint64_t>(results[d]), 921ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl static_cast<uint64_t>(results[d])); 922ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf("\n"); 923ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl } 924ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl } 925ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl VIXL_ASSERT(d == expected_length); 926ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl if (error_count > kErrorReportLimit) { 927ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl printf("%u other errors follow.\n", error_count - kErrorReportLimit); 928ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl } 929ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl VIXL_CHECK(error_count == 0); 930ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl } 931ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl delete[] results; 932ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl} 933ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 934ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 935ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// Floating-point tests. 936ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 937ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 938ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// Standard floating-point test expansion for both double- and single-precision 939ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// operations. 940ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl#define STRINGIFY(s) #s 941ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 942ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl#define CALL_TEST_FP_HELPER(mnemonic, variant, type, input) \ 943ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl Test##type(STRINGIFY(mnemonic) "_" STRINGIFY(variant), \ 944ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl &MacroAssembler::mnemonic, \ 945ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl input, sizeof(input) / sizeof(input[0]), \ 946ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl kExpected_##mnemonic##_##variant, \ 947ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl kExpectedCount_##mnemonic##_##variant) 948ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 949ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl#define DEFINE_TEST_FP(mnemonic, type, input) \ 950ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl TEST(mnemonic##_d) { \ 951ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl CALL_TEST_FP_HELPER(mnemonic, d, type, kInputDouble##input); \ 952ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl } \ 953ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl TEST(mnemonic##_s) { \ 954ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl CALL_TEST_FP_HELPER(mnemonic, s, type, kInputFloat##input); \ 955ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl } 956ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 957ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlDEFINE_TEST_FP(fmadd, 3Op, Basic) 958ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlDEFINE_TEST_FP(fmsub, 3Op, Basic) 959ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlDEFINE_TEST_FP(fnmadd, 3Op, Basic) 960ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlDEFINE_TEST_FP(fnmsub, 3Op, Basic) 961ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 962ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlDEFINE_TEST_FP(fadd, 2Op, Basic) 963ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlDEFINE_TEST_FP(fdiv, 2Op, Basic) 964ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlDEFINE_TEST_FP(fmax, 2Op, Basic) 965ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlDEFINE_TEST_FP(fmaxnm, 2Op, Basic) 966ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlDEFINE_TEST_FP(fmin, 2Op, Basic) 967ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlDEFINE_TEST_FP(fminnm, 2Op, Basic) 968ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlDEFINE_TEST_FP(fmul, 2Op, Basic) 969ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlDEFINE_TEST_FP(fsub, 2Op, Basic) 970ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 971ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlDEFINE_TEST_FP(fabs, 1Op, Basic) 972ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlDEFINE_TEST_FP(fmov, 1Op, Basic) 973ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlDEFINE_TEST_FP(fneg, 1Op, Basic) 974ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlDEFINE_TEST_FP(fsqrt, 1Op, Basic) 975ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlDEFINE_TEST_FP(frinta, 1Op, Conversions) 976ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlDEFINE_TEST_FP(frintn, 1Op, Conversions) 977ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlDEFINE_TEST_FP(frintz, 1Op, Conversions) 978ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 979ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlTEST(fcmp_d) { CALL_TEST_FP_HELPER(fcmp, d, Cmp, kInputDoubleBasic); } 980ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlTEST(fcmp_s) { CALL_TEST_FP_HELPER(fcmp, s, Cmp, kInputFloatBasic); } 981ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlTEST(fcmp_dz) { CALL_TEST_FP_HELPER(fcmp, dz, CmpZero, kInputDoubleBasic); } 982ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlTEST(fcmp_sz) { CALL_TEST_FP_HELPER(fcmp, sz, CmpZero, kInputFloatBasic); } 983ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 984ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlTEST(fcvt_sd) { CALL_TEST_FP_HELPER(fcvt, sd, 1Op, kInputDoubleConversions); } 985ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlTEST(fcvt_ds) { CALL_TEST_FP_HELPER(fcvt, ds, 1Op, kInputFloatConversions); } 986ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 987ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl#define DEFINE_TEST_FP_TO_INT(mnemonic, type, input) \ 988ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl TEST(mnemonic##_xd) { \ 989ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl CALL_TEST_FP_HELPER(mnemonic, xd, type, kInputDouble##input); \ 990ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl } \ 991ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl TEST(mnemonic##_xs) { \ 992ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl CALL_TEST_FP_HELPER(mnemonic, xs, type, kInputFloat##input); \ 993ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl } \ 994ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl TEST(mnemonic##_wd) { \ 995ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl CALL_TEST_FP_HELPER(mnemonic, wd, type, kInputDouble##input); \ 996ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl } \ 997ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl TEST(mnemonic##_ws) { \ 998ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl CALL_TEST_FP_HELPER(mnemonic, ws, type, kInputFloat##input); \ 999ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl } 1000ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl 1001ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlDEFINE_TEST_FP_TO_INT(fcvtas, FPToS, Conversions) 1002ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlDEFINE_TEST_FP_TO_INT(fcvtau, FPToU, Conversions) 1003ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlDEFINE_TEST_FP_TO_INT(fcvtms, FPToS, Conversions) 1004ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlDEFINE_TEST_FP_TO_INT(fcvtmu, FPToU, Conversions) 1005ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlDEFINE_TEST_FP_TO_INT(fcvtns, FPToS, Conversions) 1006ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlDEFINE_TEST_FP_TO_INT(fcvtnu, FPToU, Conversions) 1007ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlDEFINE_TEST_FP_TO_INT(fcvtzs, FPToS, Conversions) 1008ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlDEFINE_TEST_FP_TO_INT(fcvtzu, FPToU, Conversions) 10091123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 10101123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// TODO(jbramley): Scvtf-fixed-point 10111123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// TODO(jbramley): Scvtf-integer 10121123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// TODO(jbramley): Ucvtf-fixed-point 10131123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl// TODO(jbramley): Ucvtf-integer 10141123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 1015ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// TODO(jbramley): Fccmp 1016ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl// TODO(jbramley): Fcsel 10171123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl 10181123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl} // namespace vixl 1019