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 <cfloat> 28b8021494Sopenharmony_ci#include <cstdio> 29b8021494Sopenharmony_ci#include <sstream> 30b8021494Sopenharmony_ci 31b8021494Sopenharmony_ci#include "test-runner.h" 32b8021494Sopenharmony_ci#include "test-utils.h" 33b8021494Sopenharmony_ci 34b8021494Sopenharmony_ci#include "aarch64/cpu-features-auditor-aarch64.h" 35b8021494Sopenharmony_ci#include "aarch64/macro-assembler-aarch64.h" 36b8021494Sopenharmony_ci#include "aarch64/simulator-aarch64.h" 37b8021494Sopenharmony_ci#include "aarch64/test-simulator-inputs-aarch64.h" 38b8021494Sopenharmony_ci#include "aarch64/test-simulator-traces-aarch64.h" 39b8021494Sopenharmony_ci#include "aarch64/test-utils-aarch64.h" 40b8021494Sopenharmony_ci 41b8021494Sopenharmony_cinamespace vixl { 42b8021494Sopenharmony_cinamespace aarch64 { 43b8021494Sopenharmony_ci 44b8021494Sopenharmony_ci// ==== Simulator Tests ==== 45b8021494Sopenharmony_ci// 46b8021494Sopenharmony_ci// These simulator tests check instruction behaviour against a trace taken from 47b8021494Sopenharmony_ci// real AArch64 hardware. The same test code is used to generate the trace; the 48b8021494Sopenharmony_ci// results are printed to stdout when the test is run with 49b8021494Sopenharmony_ci// --generate_test_trace. 50b8021494Sopenharmony_ci// 51b8021494Sopenharmony_ci// The input lists and expected results are stored in test/traces. The expected 52b8021494Sopenharmony_ci// results can be regenerated using tools/generate_simulator_traces.py. Adding a 53b8021494Sopenharmony_ci// test for a new instruction is described at the top of 54b8021494Sopenharmony_ci// test-simulator-traces-aarch64.h. 55b8021494Sopenharmony_ci 56b8021494Sopenharmony_ci#define __ masm. 57b8021494Sopenharmony_ci#define TEST(name) TEST_(AARCH64_SIM_##name) 58b8021494Sopenharmony_ci 59b8021494Sopenharmony_ci#define SETUP() SETUP_WITH_FEATURES(CPUFeatures()) 60b8021494Sopenharmony_ci 61b8021494Sopenharmony_ci#ifdef VIXL_INCLUDE_SIMULATOR_AARCH64 62b8021494Sopenharmony_ci 63b8021494Sopenharmony_ci#define SETUP_WITH_FEATURES(...) \ 64b8021494Sopenharmony_ci MacroAssembler masm; \ 65b8021494Sopenharmony_ci masm.SetCPUFeatures(CPUFeatures(__VA_ARGS__)); \ 66b8021494Sopenharmony_ci Decoder decoder; \ 67b8021494Sopenharmony_ci Simulator simulator(&decoder); \ 68b8021494Sopenharmony_ci simulator.SetColouredTrace(Test::coloured_trace()); 69b8021494Sopenharmony_ci 70b8021494Sopenharmony_ci#define START() \ 71b8021494Sopenharmony_ci masm.Reset(); \ 72b8021494Sopenharmony_ci simulator.ResetState(); \ 73b8021494Sopenharmony_ci __ PushCalleeSavedRegisters(); \ 74b8021494Sopenharmony_ci /* The infrastructure code hasn't been covered at the moment, e.g. */ \ 75b8021494Sopenharmony_ci /* prologue/epilogue. Suppress tagging mis-match exception before */ \ 76b8021494Sopenharmony_ci /* this point. */ \ 77b8021494Sopenharmony_ci if (masm.GetCPUFeatures()->Has(CPUFeatures::kMTE)) { \ 78b8021494Sopenharmony_ci __ Hlt(DebugHltOpcode::kMTEActive); \ 79b8021494Sopenharmony_ci } \ 80b8021494Sopenharmony_ci if (Test::trace_reg()) { \ 81b8021494Sopenharmony_ci __ Trace(LOG_STATE, TRACE_ENABLE); \ 82b8021494Sopenharmony_ci } \ 83b8021494Sopenharmony_ci if (Test::trace_write()) { \ 84b8021494Sopenharmony_ci __ Trace(LOG_WRITE, TRACE_ENABLE); \ 85b8021494Sopenharmony_ci } \ 86b8021494Sopenharmony_ci if (Test::trace_sim()) { \ 87b8021494Sopenharmony_ci __ Trace(LOG_DISASM, TRACE_ENABLE); \ 88b8021494Sopenharmony_ci } 89b8021494Sopenharmony_ci 90b8021494Sopenharmony_ci#define END() \ 91b8021494Sopenharmony_ci if (masm.GetCPUFeatures()->Has(CPUFeatures::kMTE)) { \ 92b8021494Sopenharmony_ci __ Hlt(DebugHltOpcode::kMTEInactive); \ 93b8021494Sopenharmony_ci } \ 94b8021494Sopenharmony_ci __ Trace(LOG_ALL, TRACE_DISABLE); \ 95b8021494Sopenharmony_ci __ PopCalleeSavedRegisters(); \ 96b8021494Sopenharmony_ci __ Ret(); \ 97b8021494Sopenharmony_ci masm.FinalizeCode() 98b8021494Sopenharmony_ci 99b8021494Sopenharmony_ci#define TRY_RUN(skipped) \ 100b8021494Sopenharmony_ci DISASSEMBLE(); \ 101b8021494Sopenharmony_ci simulator.RunFrom(masm.GetBuffer()->GetStartAddress<Instruction*>()); \ 102b8021494Sopenharmony_ci /* The simulator can run every test. */ \ 103b8021494Sopenharmony_ci *skipped = false 104b8021494Sopenharmony_ci 105b8021494Sopenharmony_ci 106b8021494Sopenharmony_ci#else // VIXL_INCLUDE_SIMULATOR_AARCH64 107b8021494Sopenharmony_ci 108b8021494Sopenharmony_ci#define SETUP_WITH_FEATURES(...) \ 109b8021494Sopenharmony_ci MacroAssembler masm; \ 110b8021494Sopenharmony_ci masm.SetCPUFeatures(CPUFeatures(__VA_ARGS__)); \ 111b8021494Sopenharmony_ci CPU::SetUp() 112b8021494Sopenharmony_ci 113b8021494Sopenharmony_ci#define START() \ 114b8021494Sopenharmony_ci masm.Reset(); \ 115b8021494Sopenharmony_ci __ PushCalleeSavedRegisters() 116b8021494Sopenharmony_ci 117b8021494Sopenharmony_ci#define END() \ 118b8021494Sopenharmony_ci __ PopCalleeSavedRegisters(); \ 119b8021494Sopenharmony_ci __ Ret(); \ 120b8021494Sopenharmony_ci masm.FinalizeCode() 121b8021494Sopenharmony_ci 122b8021494Sopenharmony_ci#define TRY_RUN(skipped) \ 123b8021494Sopenharmony_ci DISASSEMBLE(); \ 124b8021494Sopenharmony_ci /* If the test uses features that the current CPU doesn't support, don't */ \ 125b8021494Sopenharmony_ci /* attempt to run it natively. */ \ 126b8021494Sopenharmony_ci { \ 127b8021494Sopenharmony_ci Decoder decoder; \ 128b8021494Sopenharmony_ci /* TODO: Once available, use runtime feature detection. The use of */ \ 129b8021494Sopenharmony_ci /* AArch64LegacyBaseline is a stopgap. */ \ 130b8021494Sopenharmony_ci const CPUFeatures& this_machine = CPUFeatures::AArch64LegacyBaseline(); \ 131b8021494Sopenharmony_ci CPUFeaturesAuditor auditor(&decoder, this_machine); \ 132b8021494Sopenharmony_ci CodeBuffer* buffer = masm.GetBuffer(); \ 133b8021494Sopenharmony_ci decoder.Decode(buffer->GetStartAddress<Instruction*>(), \ 134b8021494Sopenharmony_ci buffer->GetEndAddress<Instruction*>()); \ 135b8021494Sopenharmony_ci const CPUFeatures& requirements = auditor.GetSeenFeatures(); \ 136b8021494Sopenharmony_ci if (this_machine.Has(requirements)) { \ 137b8021494Sopenharmony_ci masm.GetBuffer()->SetExecutable(); \ 138b8021494Sopenharmony_ci ExecuteMemory(buffer->GetStartAddress<byte*>(), \ 139b8021494Sopenharmony_ci masm.GetSizeOfCodeGenerated()); \ 140b8021494Sopenharmony_ci masm.GetBuffer()->SetWritable(); \ 141b8021494Sopenharmony_ci *skipped = false; \ 142b8021494Sopenharmony_ci } else { \ 143b8021494Sopenharmony_ci std::stringstream os; \ 144b8021494Sopenharmony_ci /* Note: This message needs to match REGEXP_MISSING_FEATURES from */ \ 145b8021494Sopenharmony_ci /* tools/threaded_test.py. */ \ 146b8021494Sopenharmony_ci os << "SKIPPED: Missing features: { "; \ 147b8021494Sopenharmony_ci os << requirements.Without(this_machine) << " }\n"; \ 148b8021494Sopenharmony_ci printf("%s", os.str().c_str()); \ 149b8021494Sopenharmony_ci *skipped = true; \ 150b8021494Sopenharmony_ci } \ 151b8021494Sopenharmony_ci } 152b8021494Sopenharmony_ci 153b8021494Sopenharmony_ci 154b8021494Sopenharmony_ci#endif // VIXL_INCLUDE_SIMULATOR_AARCH64 155b8021494Sopenharmony_ci 156b8021494Sopenharmony_ci 157b8021494Sopenharmony_ci#define DISASSEMBLE() \ 158b8021494Sopenharmony_ci if (Test::disassemble()) { \ 159b8021494Sopenharmony_ci PrintDisassembler disasm(stdout); \ 160b8021494Sopenharmony_ci CodeBuffer* buffer = masm.GetBuffer(); \ 161b8021494Sopenharmony_ci Instruction* start = buffer->GetStartAddress<Instruction*>(); \ 162b8021494Sopenharmony_ci Instruction* end = buffer->GetEndAddress<Instruction*>(); \ 163b8021494Sopenharmony_ci disasm.DisassembleBuffer(start, end); \ 164b8021494Sopenharmony_ci } 165b8021494Sopenharmony_ci 166b8021494Sopenharmony_ci// The maximum number of errors to report in detail for each test. 167b8021494Sopenharmony_cistatic const unsigned kErrorReportLimit = 8; 168b8021494Sopenharmony_ci 169b8021494Sopenharmony_ci 170b8021494Sopenharmony_ci// Overloaded versions of RawbitsToDouble and RawbitsToFloat for use in the 171b8021494Sopenharmony_ci// templated test functions. 172b8021494Sopenharmony_cistatic float rawbits_to_fp(uint32_t bits) { return RawbitsToFloat(bits); } 173b8021494Sopenharmony_ci 174b8021494Sopenharmony_cistatic double rawbits_to_fp(uint64_t bits) { return RawbitsToDouble(bits); } 175b8021494Sopenharmony_ci 176b8021494Sopenharmony_ci// The rawbits_to_fp functions are only used for printing decimal values so we 177b8021494Sopenharmony_ci// just approximate FP16 as double. 178b8021494Sopenharmony_cistatic double rawbits_to_fp(uint16_t bits) { 179b8021494Sopenharmony_ci return FPToDouble(RawbitsToFloat16(bits), kIgnoreDefaultNaN); 180b8021494Sopenharmony_ci} 181b8021494Sopenharmony_ci 182b8021494Sopenharmony_ci 183b8021494Sopenharmony_ci// MacroAssembler member function pointers to pass to the test dispatchers. 184b8021494Sopenharmony_citypedef void (MacroAssembler::*Test1OpFPHelper_t)(const VRegister& fd, 185b8021494Sopenharmony_ci const VRegister& fn); 186b8021494Sopenharmony_citypedef void (MacroAssembler::*Test2OpFPHelper_t)(const VRegister& fd, 187b8021494Sopenharmony_ci const VRegister& fn, 188b8021494Sopenharmony_ci const VRegister& fm); 189b8021494Sopenharmony_citypedef void (MacroAssembler::*Test3OpFPHelper_t)(const VRegister& fd, 190b8021494Sopenharmony_ci const VRegister& fn, 191b8021494Sopenharmony_ci const VRegister& fm, 192b8021494Sopenharmony_ci const VRegister& fa); 193b8021494Sopenharmony_citypedef void (MacroAssembler::*TestFPCmpHelper_t)(const VRegister& fn, 194b8021494Sopenharmony_ci const VRegister& fm); 195b8021494Sopenharmony_citypedef void (MacroAssembler::*TestFPCmpZeroHelper_t)(const VRegister& fn, 196b8021494Sopenharmony_ci double value); 197b8021494Sopenharmony_citypedef void (MacroAssembler::*TestFPToIntHelper_t)(const Register& rd, 198b8021494Sopenharmony_ci const VRegister& fn); 199b8021494Sopenharmony_citypedef void (MacroAssembler::*TestFPToFixedHelper_t)(const Register& rd, 200b8021494Sopenharmony_ci const VRegister& fn, 201b8021494Sopenharmony_ci int fbits); 202b8021494Sopenharmony_citypedef void (MacroAssembler::*TestFixedToFPHelper_t)(const VRegister& fd, 203b8021494Sopenharmony_ci const Register& rn, 204b8021494Sopenharmony_ci int fbits); 205b8021494Sopenharmony_ci// TODO: 'Test2OpNEONHelper_t' and 'Test2OpFPHelper_t' can be 206b8021494Sopenharmony_ci// consolidated into one routine. 207b8021494Sopenharmony_citypedef void (MacroAssembler::*Test1OpNEONHelper_t)(const VRegister& vd, 208b8021494Sopenharmony_ci const VRegister& vn); 209b8021494Sopenharmony_citypedef void (MacroAssembler::*Test2OpNEONHelper_t)(const VRegister& vd, 210b8021494Sopenharmony_ci const VRegister& vn, 211b8021494Sopenharmony_ci const VRegister& vm); 212b8021494Sopenharmony_citypedef void (MacroAssembler::*TestByElementNEONHelper_t)(const VRegister& vd, 213b8021494Sopenharmony_ci const VRegister& vn, 214b8021494Sopenharmony_ci const VRegister& vm, 215b8021494Sopenharmony_ci int vm_index); 216b8021494Sopenharmony_citypedef void (MacroAssembler::*TestOpImmOpImmVdUpdateNEONHelper_t)( 217b8021494Sopenharmony_ci const VRegister& vd, int imm1, const VRegister& vn, int imm2); 218b8021494Sopenharmony_ci 219b8021494Sopenharmony_ci// This helps using the same typename for both the function pointer 220b8021494Sopenharmony_ci// and the array of immediates passed to helper routines. 221b8021494Sopenharmony_citemplate <typename T> 222b8021494Sopenharmony_ciclass Test2OpImmediateNEONHelper_t { 223b8021494Sopenharmony_ci public: 224b8021494Sopenharmony_ci typedef void (MacroAssembler::*mnemonic)(const VRegister& vd, 225b8021494Sopenharmony_ci const VRegister& vn, 226b8021494Sopenharmony_ci T imm); 227b8021494Sopenharmony_ci}; 228b8021494Sopenharmony_ci 229b8021494Sopenharmony_ci 230b8021494Sopenharmony_ci// Maximum number of hex characters required to represent values of either 231b8021494Sopenharmony_ci// templated type. 232b8021494Sopenharmony_citemplate <typename Ta, typename Tb> 233b8021494Sopenharmony_cistatic unsigned MaxHexCharCount() { 234b8021494Sopenharmony_ci unsigned count = static_cast<unsigned>(std::max(sizeof(Ta), sizeof(Tb))); 235b8021494Sopenharmony_ci return (count * 8) / 4; 236b8021494Sopenharmony_ci} 237b8021494Sopenharmony_ci 238b8021494Sopenharmony_ci 239b8021494Sopenharmony_ci// Standard test dispatchers. 240b8021494Sopenharmony_ci 241b8021494Sopenharmony_ci 242b8021494Sopenharmony_cistatic void Test1Op_Helper(Test1OpFPHelper_t helper, 243b8021494Sopenharmony_ci uintptr_t inputs, 244b8021494Sopenharmony_ci unsigned inputs_length, 245b8021494Sopenharmony_ci uintptr_t results, 246b8021494Sopenharmony_ci unsigned d_size, 247b8021494Sopenharmony_ci unsigned n_size, 248b8021494Sopenharmony_ci bool* skipped) { 249b8021494Sopenharmony_ci VIXL_ASSERT((d_size == kDRegSize) || (d_size == kSRegSize) || 250b8021494Sopenharmony_ci (d_size == kHRegSize)); 251b8021494Sopenharmony_ci VIXL_ASSERT((n_size == kDRegSize) || (n_size == kSRegSize) || 252b8021494Sopenharmony_ci (n_size == kHRegSize)); 253b8021494Sopenharmony_ci 254b8021494Sopenharmony_ci CPUFeatures features; 255b8021494Sopenharmony_ci features.Combine(CPUFeatures::kFP, CPUFeatures::kFPHalf); 256b8021494Sopenharmony_ci // For frint{32,64}{x,y} variants. 257b8021494Sopenharmony_ci features.Combine(CPUFeatures::kFrintToFixedSizedInt); 258b8021494Sopenharmony_ci SETUP_WITH_FEATURES(features); 259b8021494Sopenharmony_ci START(); 260b8021494Sopenharmony_ci 261b8021494Sopenharmony_ci // Roll up the loop to keep the code size down. 262b8021494Sopenharmony_ci Label loop_n; 263b8021494Sopenharmony_ci 264b8021494Sopenharmony_ci Register out = x0; 265b8021494Sopenharmony_ci Register inputs_base = x1; 266b8021494Sopenharmony_ci Register length = w2; 267b8021494Sopenharmony_ci Register index_n = w3; 268b8021494Sopenharmony_ci 269b8021494Sopenharmony_ci int n_index_shift; 270b8021494Sopenharmony_ci VRegister fd; 271b8021494Sopenharmony_ci VRegister fn; 272b8021494Sopenharmony_ci if (n_size == kDRegSize) { 273b8021494Sopenharmony_ci n_index_shift = kDRegSizeInBytesLog2; 274b8021494Sopenharmony_ci fn = d1; 275b8021494Sopenharmony_ci } else if (n_size == kSRegSize) { 276b8021494Sopenharmony_ci n_index_shift = kSRegSizeInBytesLog2; 277b8021494Sopenharmony_ci fn = s1; 278b8021494Sopenharmony_ci } else { 279b8021494Sopenharmony_ci n_index_shift = kHRegSizeInBytesLog2; 280b8021494Sopenharmony_ci fn = h1; 281b8021494Sopenharmony_ci } 282b8021494Sopenharmony_ci 283b8021494Sopenharmony_ci if (d_size == kDRegSize) { 284b8021494Sopenharmony_ci fd = d0; 285b8021494Sopenharmony_ci } else if (d_size == kSRegSize) { 286b8021494Sopenharmony_ci fd = s0; 287b8021494Sopenharmony_ci } else { 288b8021494Sopenharmony_ci fd = h0; 289b8021494Sopenharmony_ci } 290b8021494Sopenharmony_ci 291b8021494Sopenharmony_ci 292b8021494Sopenharmony_ci __ Mov(out, results); 293b8021494Sopenharmony_ci __ Mov(inputs_base, inputs); 294b8021494Sopenharmony_ci __ Mov(length, inputs_length); 295b8021494Sopenharmony_ci 296b8021494Sopenharmony_ci __ Mov(index_n, 0); 297b8021494Sopenharmony_ci __ Bind(&loop_n); 298b8021494Sopenharmony_ci __ Ldr(fn, MemOperand(inputs_base, index_n, UXTW, n_index_shift)); 299b8021494Sopenharmony_ci 300b8021494Sopenharmony_ci { 301b8021494Sopenharmony_ci SingleEmissionCheckScope guard(&masm); 302b8021494Sopenharmony_ci (masm.*helper)(fd, fn); 303b8021494Sopenharmony_ci } 304b8021494Sopenharmony_ci __ Str(fd, MemOperand(out, fd.GetSizeInBytes(), PostIndex)); 305b8021494Sopenharmony_ci 306b8021494Sopenharmony_ci __ Add(index_n, index_n, 1); 307b8021494Sopenharmony_ci __ Cmp(index_n, inputs_length); 308b8021494Sopenharmony_ci __ B(lo, &loop_n); 309b8021494Sopenharmony_ci 310b8021494Sopenharmony_ci END(); 311b8021494Sopenharmony_ci TRY_RUN(skipped); 312b8021494Sopenharmony_ci} 313b8021494Sopenharmony_ci 314b8021494Sopenharmony_ci 315b8021494Sopenharmony_ci// Test FP instructions. The inputs[] and expected[] arrays should be arrays of 316b8021494Sopenharmony_ci// rawbits representations of doubles or floats. This ensures that exact bit 317b8021494Sopenharmony_ci// comparisons can be performed. 318b8021494Sopenharmony_citemplate <typename Tn, typename Td> 319b8021494Sopenharmony_cistatic void Test1Op(const char* name, 320b8021494Sopenharmony_ci Test1OpFPHelper_t helper, 321b8021494Sopenharmony_ci const Tn inputs[], 322b8021494Sopenharmony_ci unsigned inputs_length, 323b8021494Sopenharmony_ci const Td expected[], 324b8021494Sopenharmony_ci unsigned expected_length) { 325b8021494Sopenharmony_ci VIXL_ASSERT(inputs_length > 0); 326b8021494Sopenharmony_ci 327b8021494Sopenharmony_ci const unsigned results_length = inputs_length; 328b8021494Sopenharmony_ci Td* results = new Td[results_length]; 329b8021494Sopenharmony_ci 330b8021494Sopenharmony_ci const unsigned d_bits = sizeof(Td) * 8; 331b8021494Sopenharmony_ci const unsigned n_bits = sizeof(Tn) * 8; 332b8021494Sopenharmony_ci bool skipped; 333b8021494Sopenharmony_ci 334b8021494Sopenharmony_ci Test1Op_Helper(helper, 335b8021494Sopenharmony_ci reinterpret_cast<uintptr_t>(inputs), 336b8021494Sopenharmony_ci inputs_length, 337b8021494Sopenharmony_ci reinterpret_cast<uintptr_t>(results), 338b8021494Sopenharmony_ci d_bits, 339b8021494Sopenharmony_ci n_bits, 340b8021494Sopenharmony_ci &skipped); 341b8021494Sopenharmony_ci 342b8021494Sopenharmony_ci if (Test::generate_test_trace()) { 343b8021494Sopenharmony_ci // Print the results. 344b8021494Sopenharmony_ci printf("const uint%u_t kExpected_%s[] = {\n", d_bits, name); 345b8021494Sopenharmony_ci for (unsigned d = 0; d < results_length; d++) { 346b8021494Sopenharmony_ci printf(" 0x%0*" PRIx64 ",\n", 347b8021494Sopenharmony_ci d_bits / 4, 348b8021494Sopenharmony_ci static_cast<uint64_t>(results[d])); 349b8021494Sopenharmony_ci } 350b8021494Sopenharmony_ci printf("};\n"); 351b8021494Sopenharmony_ci printf("const unsigned kExpectedCount_%s = %u;\n", name, results_length); 352b8021494Sopenharmony_ci } else if (!skipped) { 353b8021494Sopenharmony_ci // Check the results. 354b8021494Sopenharmony_ci VIXL_CHECK(expected_length == results_length); 355b8021494Sopenharmony_ci unsigned error_count = 0; 356b8021494Sopenharmony_ci unsigned d = 0; 357b8021494Sopenharmony_ci for (unsigned n = 0; n < inputs_length; n++, d++) { 358b8021494Sopenharmony_ci if (results[d] != expected[d]) { 359b8021494Sopenharmony_ci if (++error_count > kErrorReportLimit) continue; 360b8021494Sopenharmony_ci 361b8021494Sopenharmony_ci printf("%s 0x%0*" PRIx64 " (%s %g):\n", 362b8021494Sopenharmony_ci name, 363b8021494Sopenharmony_ci n_bits / 4, 364b8021494Sopenharmony_ci static_cast<uint64_t>(inputs[n]), 365b8021494Sopenharmony_ci name, 366b8021494Sopenharmony_ci rawbits_to_fp(inputs[n])); 367b8021494Sopenharmony_ci printf(" Expected: 0x%0*" PRIx64 " (%g)\n", 368b8021494Sopenharmony_ci d_bits / 4, 369b8021494Sopenharmony_ci static_cast<uint64_t>(expected[d]), 370b8021494Sopenharmony_ci rawbits_to_fp(expected[d])); 371b8021494Sopenharmony_ci printf(" Found: 0x%0*" PRIx64 " (%g)\n", 372b8021494Sopenharmony_ci d_bits / 4, 373b8021494Sopenharmony_ci static_cast<uint64_t>(results[d]), 374b8021494Sopenharmony_ci rawbits_to_fp(results[d])); 375b8021494Sopenharmony_ci printf("\n"); 376b8021494Sopenharmony_ci } 377b8021494Sopenharmony_ci } 378b8021494Sopenharmony_ci VIXL_ASSERT(d == expected_length); 379b8021494Sopenharmony_ci if (error_count > kErrorReportLimit) { 380b8021494Sopenharmony_ci printf("%u other errors follow.\n", error_count - kErrorReportLimit); 381b8021494Sopenharmony_ci } 382b8021494Sopenharmony_ci VIXL_CHECK(error_count == 0); 383b8021494Sopenharmony_ci } 384b8021494Sopenharmony_ci delete[] results; 385b8021494Sopenharmony_ci} 386b8021494Sopenharmony_ci 387b8021494Sopenharmony_ci 388b8021494Sopenharmony_cistatic void Test2Op_Helper(Test2OpFPHelper_t helper, 389b8021494Sopenharmony_ci uintptr_t inputs, 390b8021494Sopenharmony_ci unsigned inputs_length, 391b8021494Sopenharmony_ci uintptr_t results, 392b8021494Sopenharmony_ci unsigned reg_size, 393b8021494Sopenharmony_ci bool* skipped) { 394b8021494Sopenharmony_ci VIXL_ASSERT((reg_size == kDRegSize) || (reg_size == kSRegSize) || 395b8021494Sopenharmony_ci (reg_size == kHRegSize)); 396b8021494Sopenharmony_ci 397b8021494Sopenharmony_ci SETUP_WITH_FEATURES(CPUFeatures::kFP, CPUFeatures::kFPHalf); 398b8021494Sopenharmony_ci START(); 399b8021494Sopenharmony_ci 400b8021494Sopenharmony_ci // Roll up the loop to keep the code size down. 401b8021494Sopenharmony_ci Label loop_n, loop_m; 402b8021494Sopenharmony_ci 403b8021494Sopenharmony_ci Register out = x0; 404b8021494Sopenharmony_ci Register inputs_base = x1; 405b8021494Sopenharmony_ci Register length = w2; 406b8021494Sopenharmony_ci Register index_n = w3; 407b8021494Sopenharmony_ci Register index_m = w4; 408b8021494Sopenharmony_ci 409b8021494Sopenharmony_ci bool double_op = reg_size == kDRegSize; 410b8021494Sopenharmony_ci bool float_op = reg_size == kSRegSize; 411b8021494Sopenharmony_ci int index_shift; 412b8021494Sopenharmony_ci if (double_op) { 413b8021494Sopenharmony_ci index_shift = kDRegSizeInBytesLog2; 414b8021494Sopenharmony_ci } else if (float_op) { 415b8021494Sopenharmony_ci index_shift = kSRegSizeInBytesLog2; 416b8021494Sopenharmony_ci } else { 417b8021494Sopenharmony_ci index_shift = kHRegSizeInBytesLog2; 418b8021494Sopenharmony_ci } 419b8021494Sopenharmony_ci 420b8021494Sopenharmony_ci VRegister fd; 421b8021494Sopenharmony_ci VRegister fn; 422b8021494Sopenharmony_ci VRegister fm; 423b8021494Sopenharmony_ci 424b8021494Sopenharmony_ci if (double_op) { 425b8021494Sopenharmony_ci fd = d0; 426b8021494Sopenharmony_ci fn = d1; 427b8021494Sopenharmony_ci fm = d2; 428b8021494Sopenharmony_ci } else if (float_op) { 429b8021494Sopenharmony_ci fd = s0; 430b8021494Sopenharmony_ci fn = s1; 431b8021494Sopenharmony_ci fm = s2; 432b8021494Sopenharmony_ci } else { 433b8021494Sopenharmony_ci fd = h0; 434b8021494Sopenharmony_ci fn = h1; 435b8021494Sopenharmony_ci fm = h2; 436b8021494Sopenharmony_ci } 437b8021494Sopenharmony_ci 438b8021494Sopenharmony_ci __ Mov(out, results); 439b8021494Sopenharmony_ci __ Mov(inputs_base, inputs); 440b8021494Sopenharmony_ci __ Mov(length, inputs_length); 441b8021494Sopenharmony_ci 442b8021494Sopenharmony_ci __ Mov(index_n, 0); 443b8021494Sopenharmony_ci __ Bind(&loop_n); 444b8021494Sopenharmony_ci __ Ldr(fn, MemOperand(inputs_base, index_n, UXTW, index_shift)); 445b8021494Sopenharmony_ci 446b8021494Sopenharmony_ci __ Mov(index_m, 0); 447b8021494Sopenharmony_ci __ Bind(&loop_m); 448b8021494Sopenharmony_ci __ Ldr(fm, MemOperand(inputs_base, index_m, UXTW, index_shift)); 449b8021494Sopenharmony_ci 450b8021494Sopenharmony_ci { 451b8021494Sopenharmony_ci SingleEmissionCheckScope guard(&masm); 452b8021494Sopenharmony_ci (masm.*helper)(fd, fn, fm); 453b8021494Sopenharmony_ci } 454b8021494Sopenharmony_ci __ Str(fd, MemOperand(out, fd.GetSizeInBytes(), PostIndex)); 455b8021494Sopenharmony_ci 456b8021494Sopenharmony_ci __ Add(index_m, index_m, 1); 457b8021494Sopenharmony_ci __ Cmp(index_m, inputs_length); 458b8021494Sopenharmony_ci __ B(lo, &loop_m); 459b8021494Sopenharmony_ci 460b8021494Sopenharmony_ci __ Add(index_n, index_n, 1); 461b8021494Sopenharmony_ci __ Cmp(index_n, inputs_length); 462b8021494Sopenharmony_ci __ B(lo, &loop_n); 463b8021494Sopenharmony_ci 464b8021494Sopenharmony_ci END(); 465b8021494Sopenharmony_ci TRY_RUN(skipped); 466b8021494Sopenharmony_ci} 467b8021494Sopenharmony_ci 468b8021494Sopenharmony_ci 469b8021494Sopenharmony_ci// Test FP instructions. The inputs[] and expected[] arrays should be arrays of 470b8021494Sopenharmony_ci// rawbits representations of doubles or floats. This ensures that exact bit 471b8021494Sopenharmony_ci// comparisons can be performed. 472b8021494Sopenharmony_citemplate <typename T> 473b8021494Sopenharmony_cistatic void Test2Op(const char* name, 474b8021494Sopenharmony_ci Test2OpFPHelper_t helper, 475b8021494Sopenharmony_ci const T inputs[], 476b8021494Sopenharmony_ci unsigned inputs_length, 477b8021494Sopenharmony_ci const T expected[], 478b8021494Sopenharmony_ci unsigned expected_length) { 479b8021494Sopenharmony_ci VIXL_ASSERT(inputs_length > 0); 480b8021494Sopenharmony_ci 481b8021494Sopenharmony_ci const unsigned results_length = inputs_length * inputs_length; 482b8021494Sopenharmony_ci T* results = new T[results_length]; 483b8021494Sopenharmony_ci 484b8021494Sopenharmony_ci const unsigned bits = sizeof(T) * 8; 485b8021494Sopenharmony_ci bool skipped; 486b8021494Sopenharmony_ci 487b8021494Sopenharmony_ci Test2Op_Helper(helper, 488b8021494Sopenharmony_ci reinterpret_cast<uintptr_t>(inputs), 489b8021494Sopenharmony_ci inputs_length, 490b8021494Sopenharmony_ci reinterpret_cast<uintptr_t>(results), 491b8021494Sopenharmony_ci bits, 492b8021494Sopenharmony_ci &skipped); 493b8021494Sopenharmony_ci 494b8021494Sopenharmony_ci if (Test::generate_test_trace()) { 495b8021494Sopenharmony_ci // Print the results. 496b8021494Sopenharmony_ci printf("const uint%u_t kExpected_%s[] = {\n", bits, name); 497b8021494Sopenharmony_ci for (unsigned d = 0; d < results_length; d++) { 498b8021494Sopenharmony_ci printf(" 0x%0*" PRIx64 ",\n", 499b8021494Sopenharmony_ci bits / 4, 500b8021494Sopenharmony_ci static_cast<uint64_t>(results[d])); 501b8021494Sopenharmony_ci } 502b8021494Sopenharmony_ci printf("};\n"); 503b8021494Sopenharmony_ci printf("const unsigned kExpectedCount_%s = %u;\n", name, results_length); 504b8021494Sopenharmony_ci } else if (!skipped) { 505b8021494Sopenharmony_ci // Check the results. 506b8021494Sopenharmony_ci VIXL_CHECK(expected_length == results_length); 507b8021494Sopenharmony_ci unsigned error_count = 0; 508b8021494Sopenharmony_ci unsigned d = 0; 509b8021494Sopenharmony_ci for (unsigned n = 0; n < inputs_length; n++) { 510b8021494Sopenharmony_ci for (unsigned m = 0; m < inputs_length; m++, d++) { 511b8021494Sopenharmony_ci if (results[d] != expected[d]) { 512b8021494Sopenharmony_ci if (++error_count > kErrorReportLimit) continue; 513b8021494Sopenharmony_ci 514b8021494Sopenharmony_ci printf("%s 0x%0*" PRIx64 ", 0x%0*" PRIx64 " (%s %g %g):\n", 515b8021494Sopenharmony_ci name, 516b8021494Sopenharmony_ci bits / 4, 517b8021494Sopenharmony_ci static_cast<uint64_t>(inputs[n]), 518b8021494Sopenharmony_ci bits / 4, 519b8021494Sopenharmony_ci static_cast<uint64_t>(inputs[m]), 520b8021494Sopenharmony_ci name, 521b8021494Sopenharmony_ci rawbits_to_fp(inputs[n]), 522b8021494Sopenharmony_ci rawbits_to_fp(inputs[m])); 523b8021494Sopenharmony_ci printf(" Expected: 0x%0*" PRIx64 " (%g)\n", 524b8021494Sopenharmony_ci bits / 4, 525b8021494Sopenharmony_ci static_cast<uint64_t>(expected[d]), 526b8021494Sopenharmony_ci rawbits_to_fp(expected[d])); 527b8021494Sopenharmony_ci printf(" Found: 0x%0*" PRIx64 " (%g)\n", 528b8021494Sopenharmony_ci bits / 4, 529b8021494Sopenharmony_ci static_cast<uint64_t>(results[d]), 530b8021494Sopenharmony_ci rawbits_to_fp(results[d])); 531b8021494Sopenharmony_ci printf("\n"); 532b8021494Sopenharmony_ci } 533b8021494Sopenharmony_ci } 534b8021494Sopenharmony_ci } 535b8021494Sopenharmony_ci VIXL_ASSERT(d == expected_length); 536b8021494Sopenharmony_ci if (error_count > kErrorReportLimit) { 537b8021494Sopenharmony_ci printf("%u other errors follow.\n", error_count - kErrorReportLimit); 538b8021494Sopenharmony_ci } 539b8021494Sopenharmony_ci VIXL_CHECK(error_count == 0); 540b8021494Sopenharmony_ci } 541b8021494Sopenharmony_ci delete[] results; 542b8021494Sopenharmony_ci} 543b8021494Sopenharmony_ci 544b8021494Sopenharmony_ci 545b8021494Sopenharmony_cistatic void Test3Op_Helper(Test3OpFPHelper_t helper, 546b8021494Sopenharmony_ci uintptr_t inputs, 547b8021494Sopenharmony_ci unsigned inputs_length, 548b8021494Sopenharmony_ci uintptr_t results, 549b8021494Sopenharmony_ci unsigned reg_size, 550b8021494Sopenharmony_ci bool* skipped) { 551b8021494Sopenharmony_ci VIXL_ASSERT((reg_size == kDRegSize) || (reg_size == kSRegSize) || 552b8021494Sopenharmony_ci (reg_size == kHRegSize)); 553b8021494Sopenharmony_ci 554b8021494Sopenharmony_ci SETUP_WITH_FEATURES(CPUFeatures::kFP, CPUFeatures::kFPHalf); 555b8021494Sopenharmony_ci START(); 556b8021494Sopenharmony_ci 557b8021494Sopenharmony_ci // Roll up the loop to keep the code size down. 558b8021494Sopenharmony_ci Label loop_n, loop_m, loop_a; 559b8021494Sopenharmony_ci 560b8021494Sopenharmony_ci Register out = x0; 561b8021494Sopenharmony_ci Register inputs_base = x1; 562b8021494Sopenharmony_ci Register length = w2; 563b8021494Sopenharmony_ci Register index_n = w3; 564b8021494Sopenharmony_ci Register index_m = w4; 565b8021494Sopenharmony_ci Register index_a = w5; 566b8021494Sopenharmony_ci 567b8021494Sopenharmony_ci bool double_op = reg_size == kDRegSize; 568b8021494Sopenharmony_ci bool single_op = reg_size == kSRegSize; 569b8021494Sopenharmony_ci int index_shift; 570b8021494Sopenharmony_ci VRegister fd(0, reg_size); 571b8021494Sopenharmony_ci VRegister fn(1, reg_size); 572b8021494Sopenharmony_ci VRegister fm(2, reg_size); 573b8021494Sopenharmony_ci VRegister fa(3, reg_size); 574b8021494Sopenharmony_ci if (double_op) { 575b8021494Sopenharmony_ci index_shift = kDRegSizeInBytesLog2; 576b8021494Sopenharmony_ci } else if (single_op) { 577b8021494Sopenharmony_ci index_shift = kSRegSizeInBytesLog2; 578b8021494Sopenharmony_ci } else { 579b8021494Sopenharmony_ci index_shift = kHRegSizeInBytesLog2; 580b8021494Sopenharmony_ci } 581b8021494Sopenharmony_ci 582b8021494Sopenharmony_ci __ Mov(out, results); 583b8021494Sopenharmony_ci __ Mov(inputs_base, inputs); 584b8021494Sopenharmony_ci __ Mov(length, inputs_length); 585b8021494Sopenharmony_ci 586b8021494Sopenharmony_ci __ Mov(index_n, 0); 587b8021494Sopenharmony_ci __ Bind(&loop_n); 588b8021494Sopenharmony_ci __ Ldr(fn, MemOperand(inputs_base, index_n, UXTW, index_shift)); 589b8021494Sopenharmony_ci 590b8021494Sopenharmony_ci __ Mov(index_m, 0); 591b8021494Sopenharmony_ci __ Bind(&loop_m); 592b8021494Sopenharmony_ci __ Ldr(fm, MemOperand(inputs_base, index_m, UXTW, index_shift)); 593b8021494Sopenharmony_ci 594b8021494Sopenharmony_ci __ Mov(index_a, 0); 595b8021494Sopenharmony_ci __ Bind(&loop_a); 596b8021494Sopenharmony_ci __ Ldr(fa, MemOperand(inputs_base, index_a, UXTW, index_shift)); 597b8021494Sopenharmony_ci 598b8021494Sopenharmony_ci { 599b8021494Sopenharmony_ci SingleEmissionCheckScope guard(&masm); 600b8021494Sopenharmony_ci (masm.*helper)(fd, fn, fm, fa); 601b8021494Sopenharmony_ci } 602b8021494Sopenharmony_ci __ Str(fd, MemOperand(out, fd.GetSizeInBytes(), PostIndex)); 603b8021494Sopenharmony_ci 604b8021494Sopenharmony_ci __ Add(index_a, index_a, 1); 605b8021494Sopenharmony_ci __ Cmp(index_a, inputs_length); 606b8021494Sopenharmony_ci __ B(lo, &loop_a); 607b8021494Sopenharmony_ci 608b8021494Sopenharmony_ci __ Add(index_m, index_m, 1); 609b8021494Sopenharmony_ci __ Cmp(index_m, inputs_length); 610b8021494Sopenharmony_ci __ B(lo, &loop_m); 611b8021494Sopenharmony_ci 612b8021494Sopenharmony_ci __ Add(index_n, index_n, 1); 613b8021494Sopenharmony_ci __ Cmp(index_n, inputs_length); 614b8021494Sopenharmony_ci __ B(lo, &loop_n); 615b8021494Sopenharmony_ci 616b8021494Sopenharmony_ci END(); 617b8021494Sopenharmony_ci TRY_RUN(skipped); 618b8021494Sopenharmony_ci} 619b8021494Sopenharmony_ci 620b8021494Sopenharmony_ci 621b8021494Sopenharmony_ci// Test FP instructions. The inputs[] and expected[] arrays should be arrays of 622b8021494Sopenharmony_ci// rawbits representations of doubles or floats. This ensures that exact bit 623b8021494Sopenharmony_ci// comparisons can be performed. 624b8021494Sopenharmony_citemplate <typename T> 625b8021494Sopenharmony_cistatic void Test3Op(const char* name, 626b8021494Sopenharmony_ci Test3OpFPHelper_t helper, 627b8021494Sopenharmony_ci const T inputs[], 628b8021494Sopenharmony_ci unsigned inputs_length, 629b8021494Sopenharmony_ci const T expected[], 630b8021494Sopenharmony_ci unsigned expected_length) { 631b8021494Sopenharmony_ci VIXL_ASSERT(inputs_length > 0); 632b8021494Sopenharmony_ci 633b8021494Sopenharmony_ci const unsigned results_length = inputs_length * inputs_length * inputs_length; 634b8021494Sopenharmony_ci T* results = new T[results_length]; 635b8021494Sopenharmony_ci 636b8021494Sopenharmony_ci const unsigned bits = sizeof(T) * 8; 637b8021494Sopenharmony_ci bool skipped; 638b8021494Sopenharmony_ci 639b8021494Sopenharmony_ci Test3Op_Helper(helper, 640b8021494Sopenharmony_ci reinterpret_cast<uintptr_t>(inputs), 641b8021494Sopenharmony_ci inputs_length, 642b8021494Sopenharmony_ci reinterpret_cast<uintptr_t>(results), 643b8021494Sopenharmony_ci bits, 644b8021494Sopenharmony_ci &skipped); 645b8021494Sopenharmony_ci 646b8021494Sopenharmony_ci if (Test::generate_test_trace()) { 647b8021494Sopenharmony_ci // Print the results. 648b8021494Sopenharmony_ci printf("const uint%u_t kExpected_%s[] = {\n", bits, name); 649b8021494Sopenharmony_ci for (unsigned d = 0; d < results_length; d++) { 650b8021494Sopenharmony_ci printf(" 0x%0*" PRIx64 ",\n", 651b8021494Sopenharmony_ci bits / 4, 652b8021494Sopenharmony_ci static_cast<uint64_t>(results[d])); 653b8021494Sopenharmony_ci } 654b8021494Sopenharmony_ci printf("};\n"); 655b8021494Sopenharmony_ci printf("const unsigned kExpectedCount_%s = %u;\n", name, results_length); 656b8021494Sopenharmony_ci } else if (!skipped) { 657b8021494Sopenharmony_ci // Check the results. 658b8021494Sopenharmony_ci VIXL_CHECK(expected_length == results_length); 659b8021494Sopenharmony_ci unsigned error_count = 0; 660b8021494Sopenharmony_ci unsigned d = 0; 661b8021494Sopenharmony_ci for (unsigned n = 0; n < inputs_length; n++) { 662b8021494Sopenharmony_ci for (unsigned m = 0; m < inputs_length; m++) { 663b8021494Sopenharmony_ci for (unsigned a = 0; a < inputs_length; a++, d++) { 664b8021494Sopenharmony_ci if (results[d] != expected[d]) { 665b8021494Sopenharmony_ci if (++error_count > kErrorReportLimit) continue; 666b8021494Sopenharmony_ci 667b8021494Sopenharmony_ci printf("%s 0x%0*" PRIx64 ", 0x%0*" PRIx64 ", 0x%0*" PRIx64 668b8021494Sopenharmony_ci " (%s %g %g %g):\n", 669b8021494Sopenharmony_ci name, 670b8021494Sopenharmony_ci bits / 4, 671b8021494Sopenharmony_ci static_cast<uint64_t>(inputs[n]), 672b8021494Sopenharmony_ci bits / 4, 673b8021494Sopenharmony_ci static_cast<uint64_t>(inputs[m]), 674b8021494Sopenharmony_ci bits / 4, 675b8021494Sopenharmony_ci static_cast<uint64_t>(inputs[a]), 676b8021494Sopenharmony_ci name, 677b8021494Sopenharmony_ci rawbits_to_fp(inputs[n]), 678b8021494Sopenharmony_ci rawbits_to_fp(inputs[m]), 679b8021494Sopenharmony_ci rawbits_to_fp(inputs[a])); 680b8021494Sopenharmony_ci printf(" Expected: 0x%0*" PRIx64 " (%g)\n", 681b8021494Sopenharmony_ci bits / 4, 682b8021494Sopenharmony_ci static_cast<uint64_t>(expected[d]), 683b8021494Sopenharmony_ci rawbits_to_fp(expected[d])); 684b8021494Sopenharmony_ci printf(" Found: 0x%0*" PRIx64 " (%g)\n", 685b8021494Sopenharmony_ci bits / 4, 686b8021494Sopenharmony_ci static_cast<uint64_t>(results[d]), 687b8021494Sopenharmony_ci rawbits_to_fp(results[d])); 688b8021494Sopenharmony_ci printf("\n"); 689b8021494Sopenharmony_ci } 690b8021494Sopenharmony_ci } 691b8021494Sopenharmony_ci } 692b8021494Sopenharmony_ci } 693b8021494Sopenharmony_ci VIXL_ASSERT(d == expected_length); 694b8021494Sopenharmony_ci if (error_count > kErrorReportLimit) { 695b8021494Sopenharmony_ci printf("%u other errors follow.\n", error_count - kErrorReportLimit); 696b8021494Sopenharmony_ci } 697b8021494Sopenharmony_ci VIXL_CHECK(error_count == 0); 698b8021494Sopenharmony_ci } 699b8021494Sopenharmony_ci delete[] results; 700b8021494Sopenharmony_ci} 701b8021494Sopenharmony_ci 702b8021494Sopenharmony_ci 703b8021494Sopenharmony_cistatic void TestCmp_Helper(TestFPCmpHelper_t helper, 704b8021494Sopenharmony_ci uintptr_t inputs, 705b8021494Sopenharmony_ci unsigned inputs_length, 706b8021494Sopenharmony_ci uintptr_t results, 707b8021494Sopenharmony_ci unsigned reg_size, 708b8021494Sopenharmony_ci bool* skipped) { 709b8021494Sopenharmony_ci VIXL_ASSERT((reg_size == kDRegSize) || (reg_size == kSRegSize)); 710b8021494Sopenharmony_ci 711b8021494Sopenharmony_ci SETUP_WITH_FEATURES(CPUFeatures::kFP); 712b8021494Sopenharmony_ci START(); 713b8021494Sopenharmony_ci 714b8021494Sopenharmony_ci // Roll up the loop to keep the code size down. 715b8021494Sopenharmony_ci Label loop_n, loop_m; 716b8021494Sopenharmony_ci 717b8021494Sopenharmony_ci Register out = x0; 718b8021494Sopenharmony_ci Register inputs_base = x1; 719b8021494Sopenharmony_ci Register length = w2; 720b8021494Sopenharmony_ci Register index_n = w3; 721b8021494Sopenharmony_ci Register index_m = w4; 722b8021494Sopenharmony_ci Register flags = x5; 723b8021494Sopenharmony_ci 724b8021494Sopenharmony_ci bool double_op = reg_size == kDRegSize; 725b8021494Sopenharmony_ci const int index_shift = 726b8021494Sopenharmony_ci double_op ? kDRegSizeInBytesLog2 : kSRegSizeInBytesLog2; 727b8021494Sopenharmony_ci 728b8021494Sopenharmony_ci VRegister fn = double_op ? d1 : s1; 729b8021494Sopenharmony_ci VRegister fm = double_op ? d2 : s2; 730b8021494Sopenharmony_ci 731b8021494Sopenharmony_ci __ Mov(out, results); 732b8021494Sopenharmony_ci __ Mov(inputs_base, inputs); 733b8021494Sopenharmony_ci __ Mov(length, inputs_length); 734b8021494Sopenharmony_ci 735b8021494Sopenharmony_ci __ Mov(index_n, 0); 736b8021494Sopenharmony_ci __ Bind(&loop_n); 737b8021494Sopenharmony_ci __ Ldr(fn, MemOperand(inputs_base, index_n, UXTW, index_shift)); 738b8021494Sopenharmony_ci 739b8021494Sopenharmony_ci __ Mov(index_m, 0); 740b8021494Sopenharmony_ci __ Bind(&loop_m); 741b8021494Sopenharmony_ci __ Ldr(fm, MemOperand(inputs_base, index_m, UXTW, index_shift)); 742b8021494Sopenharmony_ci 743b8021494Sopenharmony_ci { 744b8021494Sopenharmony_ci SingleEmissionCheckScope guard(&masm); 745b8021494Sopenharmony_ci (masm.*helper)(fn, fm); 746b8021494Sopenharmony_ci } 747b8021494Sopenharmony_ci __ Mrs(flags, NZCV); 748b8021494Sopenharmony_ci __ Ubfx(flags, flags, 28, 4); 749b8021494Sopenharmony_ci __ Strb(flags, MemOperand(out, 1, PostIndex)); 750b8021494Sopenharmony_ci 751b8021494Sopenharmony_ci __ Add(index_m, index_m, 1); 752b8021494Sopenharmony_ci __ Cmp(index_m, inputs_length); 753b8021494Sopenharmony_ci __ B(lo, &loop_m); 754b8021494Sopenharmony_ci 755b8021494Sopenharmony_ci __ Add(index_n, index_n, 1); 756b8021494Sopenharmony_ci __ Cmp(index_n, inputs_length); 757b8021494Sopenharmony_ci __ B(lo, &loop_n); 758b8021494Sopenharmony_ci 759b8021494Sopenharmony_ci END(); 760b8021494Sopenharmony_ci TRY_RUN(skipped); 761b8021494Sopenharmony_ci} 762b8021494Sopenharmony_ci 763b8021494Sopenharmony_ci 764b8021494Sopenharmony_ci// Test FP instructions. The inputs[] and expected[] arrays should be arrays of 765b8021494Sopenharmony_ci// rawbits representations of doubles or floats. This ensures that exact bit 766b8021494Sopenharmony_ci// comparisons can be performed. 767b8021494Sopenharmony_citemplate <typename T> 768b8021494Sopenharmony_cistatic void TestCmp(const char* name, 769b8021494Sopenharmony_ci TestFPCmpHelper_t helper, 770b8021494Sopenharmony_ci const T inputs[], 771b8021494Sopenharmony_ci unsigned inputs_length, 772b8021494Sopenharmony_ci const uint8_t expected[], 773b8021494Sopenharmony_ci unsigned expected_length) { 774b8021494Sopenharmony_ci VIXL_ASSERT(inputs_length > 0); 775b8021494Sopenharmony_ci 776b8021494Sopenharmony_ci const unsigned results_length = inputs_length * inputs_length; 777b8021494Sopenharmony_ci uint8_t* results = new uint8_t[results_length]; 778b8021494Sopenharmony_ci 779b8021494Sopenharmony_ci const unsigned bits = sizeof(T) * 8; 780b8021494Sopenharmony_ci bool skipped; 781b8021494Sopenharmony_ci 782b8021494Sopenharmony_ci TestCmp_Helper(helper, 783b8021494Sopenharmony_ci reinterpret_cast<uintptr_t>(inputs), 784b8021494Sopenharmony_ci inputs_length, 785b8021494Sopenharmony_ci reinterpret_cast<uintptr_t>(results), 786b8021494Sopenharmony_ci bits, 787b8021494Sopenharmony_ci &skipped); 788b8021494Sopenharmony_ci 789b8021494Sopenharmony_ci if (Test::generate_test_trace()) { 790b8021494Sopenharmony_ci // Print the results. 791b8021494Sopenharmony_ci printf("const uint8_t kExpected_%s[] = {\n", name); 792b8021494Sopenharmony_ci for (unsigned d = 0; d < results_length; d++) { 793b8021494Sopenharmony_ci // Each NZCV result only requires 4 bits. 794b8021494Sopenharmony_ci VIXL_ASSERT((results[d] & 0xf) == results[d]); 795b8021494Sopenharmony_ci printf(" 0x%" PRIx8 ",\n", results[d]); 796b8021494Sopenharmony_ci } 797b8021494Sopenharmony_ci printf("};\n"); 798b8021494Sopenharmony_ci printf("const unsigned kExpectedCount_%s = %u;\n", name, results_length); 799b8021494Sopenharmony_ci } else if (!skipped) { 800b8021494Sopenharmony_ci // Check the results. 801b8021494Sopenharmony_ci VIXL_CHECK(expected_length == results_length); 802b8021494Sopenharmony_ci unsigned error_count = 0; 803b8021494Sopenharmony_ci unsigned d = 0; 804b8021494Sopenharmony_ci for (unsigned n = 0; n < inputs_length; n++) { 805b8021494Sopenharmony_ci for (unsigned m = 0; m < inputs_length; m++, d++) { 806b8021494Sopenharmony_ci if (results[d] != expected[d]) { 807b8021494Sopenharmony_ci if (++error_count > kErrorReportLimit) continue; 808b8021494Sopenharmony_ci 809b8021494Sopenharmony_ci printf("%s 0x%0*" PRIx64 ", 0x%0*" PRIx64 " (%s %g %g):\n", 810b8021494Sopenharmony_ci name, 811b8021494Sopenharmony_ci bits / 4, 812b8021494Sopenharmony_ci static_cast<uint64_t>(inputs[n]), 813b8021494Sopenharmony_ci bits / 4, 814b8021494Sopenharmony_ci static_cast<uint64_t>(inputs[m]), 815b8021494Sopenharmony_ci name, 816b8021494Sopenharmony_ci rawbits_to_fp(inputs[n]), 817b8021494Sopenharmony_ci rawbits_to_fp(inputs[m])); 818b8021494Sopenharmony_ci printf(" Expected: %c%c%c%c (0x%" PRIx8 ")\n", 819b8021494Sopenharmony_ci (expected[d] & 0x8) ? 'N' : 'n', 820b8021494Sopenharmony_ci (expected[d] & 0x4) ? 'Z' : 'z', 821b8021494Sopenharmony_ci (expected[d] & 0x2) ? 'C' : 'c', 822b8021494Sopenharmony_ci (expected[d] & 0x1) ? 'V' : 'v', 823b8021494Sopenharmony_ci expected[d]); 824b8021494Sopenharmony_ci printf(" Found: %c%c%c%c (0x%" PRIx8 ")\n", 825b8021494Sopenharmony_ci (results[d] & 0x8) ? 'N' : 'n', 826b8021494Sopenharmony_ci (results[d] & 0x4) ? 'Z' : 'z', 827b8021494Sopenharmony_ci (results[d] & 0x2) ? 'C' : 'c', 828b8021494Sopenharmony_ci (results[d] & 0x1) ? 'V' : 'v', 829b8021494Sopenharmony_ci results[d]); 830b8021494Sopenharmony_ci printf("\n"); 831b8021494Sopenharmony_ci } 832b8021494Sopenharmony_ci } 833b8021494Sopenharmony_ci } 834b8021494Sopenharmony_ci VIXL_ASSERT(d == expected_length); 835b8021494Sopenharmony_ci if (error_count > kErrorReportLimit) { 836b8021494Sopenharmony_ci printf("%u other errors follow.\n", error_count - kErrorReportLimit); 837b8021494Sopenharmony_ci } 838b8021494Sopenharmony_ci VIXL_CHECK(error_count == 0); 839b8021494Sopenharmony_ci } 840b8021494Sopenharmony_ci delete[] results; 841b8021494Sopenharmony_ci} 842b8021494Sopenharmony_ci 843b8021494Sopenharmony_ci 844b8021494Sopenharmony_cistatic void TestCmpZero_Helper(TestFPCmpZeroHelper_t helper, 845b8021494Sopenharmony_ci uintptr_t inputs, 846b8021494Sopenharmony_ci unsigned inputs_length, 847b8021494Sopenharmony_ci uintptr_t results, 848b8021494Sopenharmony_ci unsigned reg_size, 849b8021494Sopenharmony_ci bool* skipped) { 850b8021494Sopenharmony_ci VIXL_ASSERT((reg_size == kDRegSize) || (reg_size == kSRegSize)); 851b8021494Sopenharmony_ci 852b8021494Sopenharmony_ci SETUP_WITH_FEATURES(CPUFeatures::kFP); 853b8021494Sopenharmony_ci START(); 854b8021494Sopenharmony_ci 855b8021494Sopenharmony_ci // Roll up the loop to keep the code size down. 856b8021494Sopenharmony_ci Label loop_n, loop_m; 857b8021494Sopenharmony_ci 858b8021494Sopenharmony_ci Register out = x0; 859b8021494Sopenharmony_ci Register inputs_base = x1; 860b8021494Sopenharmony_ci Register length = w2; 861b8021494Sopenharmony_ci Register index_n = w3; 862b8021494Sopenharmony_ci Register flags = x4; 863b8021494Sopenharmony_ci 864b8021494Sopenharmony_ci bool double_op = reg_size == kDRegSize; 865b8021494Sopenharmony_ci const int index_shift = 866b8021494Sopenharmony_ci double_op ? kDRegSizeInBytesLog2 : kSRegSizeInBytesLog2; 867b8021494Sopenharmony_ci 868b8021494Sopenharmony_ci VRegister fn = double_op ? d1 : s1; 869b8021494Sopenharmony_ci 870b8021494Sopenharmony_ci __ Mov(out, results); 871b8021494Sopenharmony_ci __ Mov(inputs_base, inputs); 872b8021494Sopenharmony_ci __ Mov(length, inputs_length); 873b8021494Sopenharmony_ci 874b8021494Sopenharmony_ci __ Mov(index_n, 0); 875b8021494Sopenharmony_ci __ Bind(&loop_n); 876b8021494Sopenharmony_ci __ Ldr(fn, MemOperand(inputs_base, index_n, UXTW, index_shift)); 877b8021494Sopenharmony_ci 878b8021494Sopenharmony_ci { 879b8021494Sopenharmony_ci SingleEmissionCheckScope guard(&masm); 880b8021494Sopenharmony_ci (masm.*helper)(fn, 0.0); 881b8021494Sopenharmony_ci } 882b8021494Sopenharmony_ci __ Mrs(flags, NZCV); 883b8021494Sopenharmony_ci __ Ubfx(flags, flags, 28, 4); 884b8021494Sopenharmony_ci __ Strb(flags, MemOperand(out, 1, PostIndex)); 885b8021494Sopenharmony_ci 886b8021494Sopenharmony_ci __ Add(index_n, index_n, 1); 887b8021494Sopenharmony_ci __ Cmp(index_n, inputs_length); 888b8021494Sopenharmony_ci __ B(lo, &loop_n); 889b8021494Sopenharmony_ci 890b8021494Sopenharmony_ci END(); 891b8021494Sopenharmony_ci TRY_RUN(skipped); 892b8021494Sopenharmony_ci} 893b8021494Sopenharmony_ci 894b8021494Sopenharmony_ci 895b8021494Sopenharmony_ci// Test FP instructions. The inputs[] and expected[] arrays should be arrays of 896b8021494Sopenharmony_ci// rawbits representations of doubles or floats. This ensures that exact bit 897b8021494Sopenharmony_ci// comparisons can be performed. 898b8021494Sopenharmony_citemplate <typename T> 899b8021494Sopenharmony_cistatic void TestCmpZero(const char* name, 900b8021494Sopenharmony_ci TestFPCmpZeroHelper_t helper, 901b8021494Sopenharmony_ci const T inputs[], 902b8021494Sopenharmony_ci unsigned inputs_length, 903b8021494Sopenharmony_ci const uint8_t expected[], 904b8021494Sopenharmony_ci unsigned expected_length) { 905b8021494Sopenharmony_ci VIXL_ASSERT(inputs_length > 0); 906b8021494Sopenharmony_ci 907b8021494Sopenharmony_ci const unsigned results_length = inputs_length; 908b8021494Sopenharmony_ci uint8_t* results = new uint8_t[results_length]; 909b8021494Sopenharmony_ci 910b8021494Sopenharmony_ci const unsigned bits = sizeof(T) * 8; 911b8021494Sopenharmony_ci bool skipped; 912b8021494Sopenharmony_ci 913b8021494Sopenharmony_ci TestCmpZero_Helper(helper, 914b8021494Sopenharmony_ci reinterpret_cast<uintptr_t>(inputs), 915b8021494Sopenharmony_ci inputs_length, 916b8021494Sopenharmony_ci reinterpret_cast<uintptr_t>(results), 917b8021494Sopenharmony_ci bits, 918b8021494Sopenharmony_ci &skipped); 919b8021494Sopenharmony_ci 920b8021494Sopenharmony_ci if (Test::generate_test_trace()) { 921b8021494Sopenharmony_ci // Print the results. 922b8021494Sopenharmony_ci printf("const uint8_t kExpected_%s[] = {\n", name); 923b8021494Sopenharmony_ci for (unsigned d = 0; d < results_length; d++) { 924b8021494Sopenharmony_ci // Each NZCV result only requires 4 bits. 925b8021494Sopenharmony_ci VIXL_ASSERT((results[d] & 0xf) == results[d]); 926b8021494Sopenharmony_ci printf(" 0x%" PRIx8 ",\n", results[d]); 927b8021494Sopenharmony_ci } 928b8021494Sopenharmony_ci printf("};\n"); 929b8021494Sopenharmony_ci printf("const unsigned kExpectedCount_%s = %u;\n", name, results_length); 930b8021494Sopenharmony_ci } else if (!skipped) { 931b8021494Sopenharmony_ci // Check the results. 932b8021494Sopenharmony_ci VIXL_CHECK(expected_length == results_length); 933b8021494Sopenharmony_ci unsigned error_count = 0; 934b8021494Sopenharmony_ci unsigned d = 0; 935b8021494Sopenharmony_ci for (unsigned n = 0; n < inputs_length; n++, d++) { 936b8021494Sopenharmony_ci if (results[d] != expected[d]) { 937b8021494Sopenharmony_ci if (++error_count > kErrorReportLimit) continue; 938b8021494Sopenharmony_ci 939b8021494Sopenharmony_ci printf("%s 0x%0*" PRIx64 ", 0x%0*u (%s %g #0.0):\n", 940b8021494Sopenharmony_ci name, 941b8021494Sopenharmony_ci bits / 4, 942b8021494Sopenharmony_ci static_cast<uint64_t>(inputs[n]), 943b8021494Sopenharmony_ci bits / 4, 944b8021494Sopenharmony_ci 0, 945b8021494Sopenharmony_ci name, 946b8021494Sopenharmony_ci rawbits_to_fp(inputs[n])); 947b8021494Sopenharmony_ci printf(" Expected: %c%c%c%c (0x%" PRIx8 ")\n", 948b8021494Sopenharmony_ci (expected[d] & 0x8) ? 'N' : 'n', 949b8021494Sopenharmony_ci (expected[d] & 0x4) ? 'Z' : 'z', 950b8021494Sopenharmony_ci (expected[d] & 0x2) ? 'C' : 'c', 951b8021494Sopenharmony_ci (expected[d] & 0x1) ? 'V' : 'v', 952b8021494Sopenharmony_ci expected[d]); 953b8021494Sopenharmony_ci printf(" Found: %c%c%c%c (0x%" PRIx8 ")\n", 954b8021494Sopenharmony_ci (results[d] & 0x8) ? 'N' : 'n', 955b8021494Sopenharmony_ci (results[d] & 0x4) ? 'Z' : 'z', 956b8021494Sopenharmony_ci (results[d] & 0x2) ? 'C' : 'c', 957b8021494Sopenharmony_ci (results[d] & 0x1) ? 'V' : 'v', 958b8021494Sopenharmony_ci results[d]); 959b8021494Sopenharmony_ci printf("\n"); 960b8021494Sopenharmony_ci } 961b8021494Sopenharmony_ci } 962b8021494Sopenharmony_ci VIXL_ASSERT(d == expected_length); 963b8021494Sopenharmony_ci if (error_count > kErrorReportLimit) { 964b8021494Sopenharmony_ci printf("%u other errors follow.\n", error_count - kErrorReportLimit); 965b8021494Sopenharmony_ci } 966b8021494Sopenharmony_ci VIXL_CHECK(error_count == 0); 967b8021494Sopenharmony_ci } 968b8021494Sopenharmony_ci delete[] results; 969b8021494Sopenharmony_ci} 970b8021494Sopenharmony_ci 971b8021494Sopenharmony_ci 972b8021494Sopenharmony_cistatic void TestFPToFixed_Helper(TestFPToFixedHelper_t helper, 973b8021494Sopenharmony_ci uintptr_t inputs, 974b8021494Sopenharmony_ci unsigned inputs_length, 975b8021494Sopenharmony_ci uintptr_t results, 976b8021494Sopenharmony_ci unsigned d_size, 977b8021494Sopenharmony_ci unsigned n_size, 978b8021494Sopenharmony_ci bool* skipped) { 979b8021494Sopenharmony_ci VIXL_ASSERT((d_size == kXRegSize) || (d_size == kWRegSize)); 980b8021494Sopenharmony_ci VIXL_ASSERT((n_size == kDRegSize) || (n_size == kSRegSize) || 981b8021494Sopenharmony_ci (n_size == kHRegSize)); 982b8021494Sopenharmony_ci 983b8021494Sopenharmony_ci SETUP_WITH_FEATURES(CPUFeatures::kFP, CPUFeatures::kFPHalf); 984b8021494Sopenharmony_ci START(); 985b8021494Sopenharmony_ci 986b8021494Sopenharmony_ci // Roll up the loop to keep the code size down. 987b8021494Sopenharmony_ci Label loop_n; 988b8021494Sopenharmony_ci 989b8021494Sopenharmony_ci Register out = x0; 990b8021494Sopenharmony_ci Register inputs_base = x1; 991b8021494Sopenharmony_ci Register length = w2; 992b8021494Sopenharmony_ci Register index_n = w3; 993b8021494Sopenharmony_ci 994b8021494Sopenharmony_ci int n_index_shift; 995b8021494Sopenharmony_ci if (n_size == kDRegSize) { 996b8021494Sopenharmony_ci n_index_shift = kDRegSizeInBytesLog2; 997b8021494Sopenharmony_ci } else if (n_size == kSRegSize) { 998b8021494Sopenharmony_ci n_index_shift = kSRegSizeInBytesLog2; 999b8021494Sopenharmony_ci } else { 1000b8021494Sopenharmony_ci n_index_shift = kHRegSizeInBytesLog2; 1001b8021494Sopenharmony_ci } 1002b8021494Sopenharmony_ci 1003b8021494Sopenharmony_ci Register rd = (d_size == kXRegSize) ? Register(x10) : Register(w10); 1004b8021494Sopenharmony_ci VRegister fn; 1005b8021494Sopenharmony_ci if (n_size == kDRegSize) { 1006b8021494Sopenharmony_ci fn = d1; 1007b8021494Sopenharmony_ci } else if (n_size == kSRegSize) { 1008b8021494Sopenharmony_ci fn = s1; 1009b8021494Sopenharmony_ci } else { 1010b8021494Sopenharmony_ci fn = h1; 1011b8021494Sopenharmony_ci } 1012b8021494Sopenharmony_ci 1013b8021494Sopenharmony_ci __ Mov(out, results); 1014b8021494Sopenharmony_ci __ Mov(inputs_base, inputs); 1015b8021494Sopenharmony_ci __ Mov(length, inputs_length); 1016b8021494Sopenharmony_ci 1017b8021494Sopenharmony_ci __ Mov(index_n, 0); 1018b8021494Sopenharmony_ci __ Bind(&loop_n); 1019b8021494Sopenharmony_ci __ Ldr(fn, MemOperand(inputs_base, index_n, UXTW, n_index_shift)); 1020b8021494Sopenharmony_ci 1021b8021494Sopenharmony_ci for (unsigned fbits = 0; fbits <= d_size; ++fbits) { 1022b8021494Sopenharmony_ci { 1023b8021494Sopenharmony_ci SingleEmissionCheckScope guard(&masm); 1024b8021494Sopenharmony_ci (masm.*helper)(rd, fn, fbits); 1025b8021494Sopenharmony_ci } 1026b8021494Sopenharmony_ci __ Str(rd, MemOperand(out, rd.GetSizeInBytes(), PostIndex)); 1027b8021494Sopenharmony_ci } 1028b8021494Sopenharmony_ci 1029b8021494Sopenharmony_ci __ Add(index_n, index_n, 1); 1030b8021494Sopenharmony_ci __ Cmp(index_n, inputs_length); 1031b8021494Sopenharmony_ci __ B(lo, &loop_n); 1032b8021494Sopenharmony_ci 1033b8021494Sopenharmony_ci END(); 1034b8021494Sopenharmony_ci TRY_RUN(skipped); 1035b8021494Sopenharmony_ci} 1036b8021494Sopenharmony_ci 1037b8021494Sopenharmony_ci 1038b8021494Sopenharmony_cistatic void TestFPToInt_Helper(TestFPToIntHelper_t helper, 1039b8021494Sopenharmony_ci uintptr_t inputs, 1040b8021494Sopenharmony_ci unsigned inputs_length, 1041b8021494Sopenharmony_ci uintptr_t results, 1042b8021494Sopenharmony_ci unsigned d_size, 1043b8021494Sopenharmony_ci unsigned n_size, 1044b8021494Sopenharmony_ci bool* skipped) { 1045b8021494Sopenharmony_ci VIXL_ASSERT((d_size == kXRegSize) || (d_size == kWRegSize)); 1046b8021494Sopenharmony_ci VIXL_ASSERT((n_size == kDRegSize) || (n_size == kSRegSize) || 1047b8021494Sopenharmony_ci (n_size == kHRegSize)); 1048b8021494Sopenharmony_ci 1049b8021494Sopenharmony_ci SETUP_WITH_FEATURES(CPUFeatures::kFP, 1050b8021494Sopenharmony_ci CPUFeatures::kFPHalf, 1051b8021494Sopenharmony_ci CPUFeatures::kJSCVT); 1052b8021494Sopenharmony_ci START(); 1053b8021494Sopenharmony_ci 1054b8021494Sopenharmony_ci // Roll up the loop to keep the code size down. 1055b8021494Sopenharmony_ci Label loop_n; 1056b8021494Sopenharmony_ci 1057b8021494Sopenharmony_ci Register out = x0; 1058b8021494Sopenharmony_ci Register inputs_base = x1; 1059b8021494Sopenharmony_ci Register length = w2; 1060b8021494Sopenharmony_ci Register index_n = w3; 1061b8021494Sopenharmony_ci 1062b8021494Sopenharmony_ci int n_index_shift; 1063b8021494Sopenharmony_ci if (n_size == kDRegSize) { 1064b8021494Sopenharmony_ci n_index_shift = kDRegSizeInBytesLog2; 1065b8021494Sopenharmony_ci } else if (n_size == kSRegSize) { 1066b8021494Sopenharmony_ci n_index_shift = kSRegSizeInBytesLog2; 1067b8021494Sopenharmony_ci } else { 1068b8021494Sopenharmony_ci n_index_shift = kHRegSizeInBytesLog2; 1069b8021494Sopenharmony_ci } 1070b8021494Sopenharmony_ci 1071b8021494Sopenharmony_ci Register rd = (d_size == kXRegSize) ? Register(x10) : Register(w10); 1072b8021494Sopenharmony_ci VRegister fn; 1073b8021494Sopenharmony_ci if (n_size == kDRegSize) { 1074b8021494Sopenharmony_ci fn = d1; 1075b8021494Sopenharmony_ci } else if (n_size == kSRegSize) { 1076b8021494Sopenharmony_ci fn = s1; 1077b8021494Sopenharmony_ci } else { 1078b8021494Sopenharmony_ci fn = h1; 1079b8021494Sopenharmony_ci } 1080b8021494Sopenharmony_ci 1081b8021494Sopenharmony_ci __ Mov(out, results); 1082b8021494Sopenharmony_ci __ Mov(inputs_base, inputs); 1083b8021494Sopenharmony_ci __ Mov(length, inputs_length); 1084b8021494Sopenharmony_ci 1085b8021494Sopenharmony_ci __ Mov(index_n, 0); 1086b8021494Sopenharmony_ci __ Bind(&loop_n); 1087b8021494Sopenharmony_ci __ Ldr(fn, MemOperand(inputs_base, index_n, UXTW, n_index_shift)); 1088b8021494Sopenharmony_ci 1089b8021494Sopenharmony_ci { 1090b8021494Sopenharmony_ci SingleEmissionCheckScope guard(&masm); 1091b8021494Sopenharmony_ci (masm.*helper)(rd, fn); 1092b8021494Sopenharmony_ci } 1093b8021494Sopenharmony_ci __ Str(rd, MemOperand(out, rd.GetSizeInBytes(), PostIndex)); 1094b8021494Sopenharmony_ci 1095b8021494Sopenharmony_ci __ Add(index_n, index_n, 1); 1096b8021494Sopenharmony_ci __ Cmp(index_n, inputs_length); 1097b8021494Sopenharmony_ci __ B(lo, &loop_n); 1098b8021494Sopenharmony_ci 1099b8021494Sopenharmony_ci END(); 1100b8021494Sopenharmony_ci TRY_RUN(skipped); 1101b8021494Sopenharmony_ci} 1102b8021494Sopenharmony_ci 1103b8021494Sopenharmony_ci 1104b8021494Sopenharmony_ci// Test FP instructions. 1105b8021494Sopenharmony_ci// - The inputs[] array should be an array of rawbits representations of 1106b8021494Sopenharmony_ci// doubles or floats. This ensures that exact bit comparisons can be 1107b8021494Sopenharmony_ci// performed. 1108b8021494Sopenharmony_ci// - The expected[] array should be an array of signed integers. 1109b8021494Sopenharmony_citemplate <typename Tn, typename Td> 1110b8021494Sopenharmony_cistatic void TestFPToS(const char* name, 1111b8021494Sopenharmony_ci TestFPToIntHelper_t helper, 1112b8021494Sopenharmony_ci const Tn inputs[], 1113b8021494Sopenharmony_ci unsigned inputs_length, 1114b8021494Sopenharmony_ci const Td expected[], 1115b8021494Sopenharmony_ci unsigned expected_length) { 1116b8021494Sopenharmony_ci VIXL_ASSERT(inputs_length > 0); 1117b8021494Sopenharmony_ci 1118b8021494Sopenharmony_ci const unsigned results_length = inputs_length; 1119b8021494Sopenharmony_ci Td* results = new Td[results_length]; 1120b8021494Sopenharmony_ci 1121b8021494Sopenharmony_ci const unsigned d_bits = sizeof(Td) * 8; 1122b8021494Sopenharmony_ci const unsigned n_bits = sizeof(Tn) * 8; 1123b8021494Sopenharmony_ci bool skipped; 1124b8021494Sopenharmony_ci 1125b8021494Sopenharmony_ci TestFPToInt_Helper(helper, 1126b8021494Sopenharmony_ci reinterpret_cast<uintptr_t>(inputs), 1127b8021494Sopenharmony_ci inputs_length, 1128b8021494Sopenharmony_ci reinterpret_cast<uintptr_t>(results), 1129b8021494Sopenharmony_ci d_bits, 1130b8021494Sopenharmony_ci n_bits, 1131b8021494Sopenharmony_ci &skipped); 1132b8021494Sopenharmony_ci 1133b8021494Sopenharmony_ci if (Test::generate_test_trace()) { 1134b8021494Sopenharmony_ci // Print the results. 1135b8021494Sopenharmony_ci printf("const int%u_t kExpected_%s[] = {\n", d_bits, name); 1136b8021494Sopenharmony_ci // There is no simple C++ literal for INT*_MIN that doesn't produce 1137b8021494Sopenharmony_ci // warnings, so we use an appropriate constant in that case instead. 1138b8021494Sopenharmony_ci // Deriving int_d_min in this way (rather than just checking INT64_MIN and 1139b8021494Sopenharmony_ci // the like) avoids warnings about comparing values with differing ranges. 1140b8021494Sopenharmony_ci const int64_t int_d_max = (UINT64_C(1) << (d_bits - 1)) - 1; 1141b8021494Sopenharmony_ci const int64_t int_d_min = -(int_d_max)-1; 1142b8021494Sopenharmony_ci for (unsigned d = 0; d < results_length; d++) { 1143b8021494Sopenharmony_ci if (results[d] == int_d_min) { 1144b8021494Sopenharmony_ci printf(" -INT%u_C(%" PRId64 ") - 1,\n", d_bits, int_d_max); 1145b8021494Sopenharmony_ci } else { 1146b8021494Sopenharmony_ci // Some constants (such as those between INT32_MAX and UINT32_MAX) 1147b8021494Sopenharmony_ci // trigger compiler warnings. To avoid these warnings, use an 1148b8021494Sopenharmony_ci // appropriate macro to make the type explicit. 1149b8021494Sopenharmony_ci int64_t result_int64 = static_cast<int64_t>(results[d]); 1150b8021494Sopenharmony_ci if (result_int64 >= 0) { 1151b8021494Sopenharmony_ci printf(" INT%u_C(%" PRId64 "),\n", d_bits, result_int64); 1152b8021494Sopenharmony_ci } else { 1153b8021494Sopenharmony_ci printf(" -INT%u_C(%" PRId64 "),\n", d_bits, -result_int64); 1154b8021494Sopenharmony_ci } 1155b8021494Sopenharmony_ci } 1156b8021494Sopenharmony_ci } 1157b8021494Sopenharmony_ci printf("};\n"); 1158b8021494Sopenharmony_ci printf("const unsigned kExpectedCount_%s = %u;\n", name, results_length); 1159b8021494Sopenharmony_ci } else if (!skipped) { 1160b8021494Sopenharmony_ci // Check the results. 1161b8021494Sopenharmony_ci VIXL_CHECK(expected_length == results_length); 1162b8021494Sopenharmony_ci unsigned error_count = 0; 1163b8021494Sopenharmony_ci unsigned d = 0; 1164b8021494Sopenharmony_ci for (unsigned n = 0; n < inputs_length; n++, d++) { 1165b8021494Sopenharmony_ci if (results[d] != expected[d]) { 1166b8021494Sopenharmony_ci if (++error_count > kErrorReportLimit) continue; 1167b8021494Sopenharmony_ci 1168b8021494Sopenharmony_ci printf("%s 0x%0*" PRIx64 " (%s %g):\n", 1169b8021494Sopenharmony_ci name, 1170b8021494Sopenharmony_ci n_bits / 4, 1171b8021494Sopenharmony_ci static_cast<uint64_t>(inputs[n]), 1172b8021494Sopenharmony_ci name, 1173b8021494Sopenharmony_ci rawbits_to_fp(inputs[n])); 1174b8021494Sopenharmony_ci printf(" Expected: 0x%0*" PRIx64 " (%" PRId64 ")\n", 1175b8021494Sopenharmony_ci d_bits / 4, 1176b8021494Sopenharmony_ci static_cast<uint64_t>(expected[d]), 1177b8021494Sopenharmony_ci static_cast<int64_t>(expected[d])); 1178b8021494Sopenharmony_ci printf(" Found: 0x%0*" PRIx64 " (%" PRId64 ")\n", 1179b8021494Sopenharmony_ci d_bits / 4, 1180b8021494Sopenharmony_ci static_cast<uint64_t>(results[d]), 1181b8021494Sopenharmony_ci static_cast<int64_t>(results[d])); 1182b8021494Sopenharmony_ci printf("\n"); 1183b8021494Sopenharmony_ci } 1184b8021494Sopenharmony_ci } 1185b8021494Sopenharmony_ci VIXL_ASSERT(d == expected_length); 1186b8021494Sopenharmony_ci if (error_count > kErrorReportLimit) { 1187b8021494Sopenharmony_ci printf("%u other errors follow.\n", error_count - kErrorReportLimit); 1188b8021494Sopenharmony_ci } 1189b8021494Sopenharmony_ci VIXL_CHECK(error_count == 0); 1190b8021494Sopenharmony_ci } 1191b8021494Sopenharmony_ci delete[] results; 1192b8021494Sopenharmony_ci} 1193b8021494Sopenharmony_ci 1194b8021494Sopenharmony_ci 1195b8021494Sopenharmony_ci// Test FP instructions. 1196b8021494Sopenharmony_ci// - The inputs[] array should be an array of rawbits representations of 1197b8021494Sopenharmony_ci// doubles or floats. This ensures that exact bit comparisons can be 1198b8021494Sopenharmony_ci// performed. 1199b8021494Sopenharmony_ci// - The expected[] array should be an array of unsigned integers. 1200b8021494Sopenharmony_citemplate <typename Tn, typename Td> 1201b8021494Sopenharmony_cistatic void TestFPToU(const char* name, 1202b8021494Sopenharmony_ci TestFPToIntHelper_t helper, 1203b8021494Sopenharmony_ci const Tn inputs[], 1204b8021494Sopenharmony_ci unsigned inputs_length, 1205b8021494Sopenharmony_ci const Td expected[], 1206b8021494Sopenharmony_ci unsigned expected_length) { 1207b8021494Sopenharmony_ci VIXL_ASSERT(inputs_length > 0); 1208b8021494Sopenharmony_ci 1209b8021494Sopenharmony_ci const unsigned results_length = inputs_length; 1210b8021494Sopenharmony_ci Td* results = new Td[results_length]; 1211b8021494Sopenharmony_ci 1212b8021494Sopenharmony_ci const unsigned d_bits = sizeof(Td) * 8; 1213b8021494Sopenharmony_ci const unsigned n_bits = sizeof(Tn) * 8; 1214b8021494Sopenharmony_ci bool skipped; 1215b8021494Sopenharmony_ci 1216b8021494Sopenharmony_ci TestFPToInt_Helper(helper, 1217b8021494Sopenharmony_ci reinterpret_cast<uintptr_t>(inputs), 1218b8021494Sopenharmony_ci inputs_length, 1219b8021494Sopenharmony_ci reinterpret_cast<uintptr_t>(results), 1220b8021494Sopenharmony_ci d_bits, 1221b8021494Sopenharmony_ci n_bits, 1222b8021494Sopenharmony_ci &skipped); 1223b8021494Sopenharmony_ci 1224b8021494Sopenharmony_ci if (Test::generate_test_trace()) { 1225b8021494Sopenharmony_ci // Print the results. 1226b8021494Sopenharmony_ci printf("const uint%u_t kExpected_%s[] = {\n", d_bits, name); 1227b8021494Sopenharmony_ci for (unsigned d = 0; d < results_length; d++) { 1228b8021494Sopenharmony_ci printf(" %" PRIu64 "u,\n", static_cast<uint64_t>(results[d])); 1229b8021494Sopenharmony_ci } 1230b8021494Sopenharmony_ci printf("};\n"); 1231b8021494Sopenharmony_ci printf("const unsigned kExpectedCount_%s = %u;\n", name, results_length); 1232b8021494Sopenharmony_ci } else if (!skipped) { 1233b8021494Sopenharmony_ci // Check the results. 1234b8021494Sopenharmony_ci VIXL_CHECK(expected_length == results_length); 1235b8021494Sopenharmony_ci unsigned error_count = 0; 1236b8021494Sopenharmony_ci unsigned d = 0; 1237b8021494Sopenharmony_ci for (unsigned n = 0; n < inputs_length; n++, d++) { 1238b8021494Sopenharmony_ci if (results[d] != expected[d]) { 1239b8021494Sopenharmony_ci if (++error_count > kErrorReportLimit) continue; 1240b8021494Sopenharmony_ci 1241b8021494Sopenharmony_ci printf("%s 0x%0*" PRIx64 " (%s %g):\n", 1242b8021494Sopenharmony_ci name, 1243b8021494Sopenharmony_ci n_bits / 4, 1244b8021494Sopenharmony_ci static_cast<uint64_t>(inputs[n]), 1245b8021494Sopenharmony_ci name, 1246b8021494Sopenharmony_ci rawbits_to_fp(inputs[n])); 1247b8021494Sopenharmony_ci printf(" Expected: 0x%0*" PRIx64 " (%" PRIu64 ")\n", 1248b8021494Sopenharmony_ci d_bits / 4, 1249b8021494Sopenharmony_ci static_cast<uint64_t>(expected[d]), 1250b8021494Sopenharmony_ci static_cast<uint64_t>(expected[d])); 1251b8021494Sopenharmony_ci printf(" Found: 0x%0*" PRIx64 " (%" PRIu64 ")\n", 1252b8021494Sopenharmony_ci d_bits / 4, 1253b8021494Sopenharmony_ci static_cast<uint64_t>(results[d]), 1254b8021494Sopenharmony_ci static_cast<uint64_t>(results[d])); 1255b8021494Sopenharmony_ci printf("\n"); 1256b8021494Sopenharmony_ci } 1257b8021494Sopenharmony_ci } 1258b8021494Sopenharmony_ci VIXL_ASSERT(d == expected_length); 1259b8021494Sopenharmony_ci if (error_count > kErrorReportLimit) { 1260b8021494Sopenharmony_ci printf("%u other errors follow.\n", error_count - kErrorReportLimit); 1261b8021494Sopenharmony_ci } 1262b8021494Sopenharmony_ci VIXL_CHECK(error_count == 0); 1263b8021494Sopenharmony_ci } 1264b8021494Sopenharmony_ci delete[] results; 1265b8021494Sopenharmony_ci} 1266b8021494Sopenharmony_ci 1267b8021494Sopenharmony_ci 1268b8021494Sopenharmony_ci// Test FP instructions. 1269b8021494Sopenharmony_ci// - The inputs[] array should be an array of rawbits representations of 1270b8021494Sopenharmony_ci// doubles or floats. This ensures that exact bit comparisons can be 1271b8021494Sopenharmony_ci// performed. 1272b8021494Sopenharmony_ci// - The expected[] array should be an array of signed integers. 1273b8021494Sopenharmony_citemplate <typename Tn, typename Td> 1274b8021494Sopenharmony_cistatic void TestFPToFixedS(const char* name, 1275b8021494Sopenharmony_ci TestFPToFixedHelper_t helper, 1276b8021494Sopenharmony_ci const Tn inputs[], 1277b8021494Sopenharmony_ci unsigned inputs_length, 1278b8021494Sopenharmony_ci const Td expected[], 1279b8021494Sopenharmony_ci unsigned expected_length) { 1280b8021494Sopenharmony_ci VIXL_ASSERT(inputs_length > 0); 1281b8021494Sopenharmony_ci 1282b8021494Sopenharmony_ci const unsigned d_bits = sizeof(Td) * 8; 1283b8021494Sopenharmony_ci const unsigned n_bits = sizeof(Tn) * 8; 1284b8021494Sopenharmony_ci 1285b8021494Sopenharmony_ci const unsigned results_length = inputs_length * (d_bits + 1); 1286b8021494Sopenharmony_ci Td* results = new Td[results_length]; 1287b8021494Sopenharmony_ci 1288b8021494Sopenharmony_ci bool skipped; 1289b8021494Sopenharmony_ci 1290b8021494Sopenharmony_ci TestFPToFixed_Helper(helper, 1291b8021494Sopenharmony_ci reinterpret_cast<uintptr_t>(inputs), 1292b8021494Sopenharmony_ci inputs_length, 1293b8021494Sopenharmony_ci reinterpret_cast<uintptr_t>(results), 1294b8021494Sopenharmony_ci d_bits, 1295b8021494Sopenharmony_ci n_bits, 1296b8021494Sopenharmony_ci &skipped); 1297b8021494Sopenharmony_ci 1298b8021494Sopenharmony_ci if (Test::generate_test_trace()) { 1299b8021494Sopenharmony_ci // Print the results. 1300b8021494Sopenharmony_ci printf("const int%u_t kExpected_%s[] = {\n", d_bits, name); 1301b8021494Sopenharmony_ci // There is no simple C++ literal for INT*_MIN that doesn't produce 1302b8021494Sopenharmony_ci // warnings, so we use an appropriate constant in that case instead. 1303b8021494Sopenharmony_ci // Deriving int_d_min in this way (rather than just checking INT64_MIN and 1304b8021494Sopenharmony_ci // the like) avoids warnings about comparing values with differing ranges. 1305b8021494Sopenharmony_ci const int64_t int_d_max = (UINT64_C(1) << (d_bits - 1)) - 1; 1306b8021494Sopenharmony_ci const int64_t int_d_min = -(int_d_max)-1; 1307b8021494Sopenharmony_ci for (unsigned d = 0; d < results_length; d++) { 1308b8021494Sopenharmony_ci if (results[d] == int_d_min) { 1309b8021494Sopenharmony_ci printf(" -INT%u_C(%" PRId64 ") - 1,\n", d_bits, int_d_max); 1310b8021494Sopenharmony_ci } else { 1311b8021494Sopenharmony_ci // Some constants (such as those between INT32_MAX and UINT32_MAX) 1312b8021494Sopenharmony_ci // trigger compiler warnings. To avoid these warnings, use an 1313b8021494Sopenharmony_ci // appropriate macro to make the type explicit. 1314b8021494Sopenharmony_ci int64_t result_int64 = static_cast<int64_t>(results[d]); 1315b8021494Sopenharmony_ci if (result_int64 >= 0) { 1316b8021494Sopenharmony_ci printf(" INT%u_C(%" PRId64 "),\n", d_bits, result_int64); 1317b8021494Sopenharmony_ci } else { 1318b8021494Sopenharmony_ci printf(" -INT%u_C(%" PRId64 "),\n", d_bits, -result_int64); 1319b8021494Sopenharmony_ci } 1320b8021494Sopenharmony_ci } 1321b8021494Sopenharmony_ci } 1322b8021494Sopenharmony_ci printf("};\n"); 1323b8021494Sopenharmony_ci printf("const unsigned kExpectedCount_%s = %u;\n", name, results_length); 1324b8021494Sopenharmony_ci } else if (!skipped) { 1325b8021494Sopenharmony_ci // Check the results. 1326b8021494Sopenharmony_ci VIXL_CHECK(expected_length == results_length); 1327b8021494Sopenharmony_ci unsigned error_count = 0; 1328b8021494Sopenharmony_ci unsigned d = 0; 1329b8021494Sopenharmony_ci for (unsigned n = 0; n < inputs_length; n++) { 1330b8021494Sopenharmony_ci for (unsigned fbits = 0; fbits <= d_bits; ++fbits, d++) { 1331b8021494Sopenharmony_ci if (results[d] != expected[d]) { 1332b8021494Sopenharmony_ci if (++error_count > kErrorReportLimit) continue; 1333b8021494Sopenharmony_ci 1334b8021494Sopenharmony_ci printf("%s 0x%0*" PRIx64 " #%d (%s %g #%d):\n", 1335b8021494Sopenharmony_ci name, 1336b8021494Sopenharmony_ci n_bits / 4, 1337b8021494Sopenharmony_ci static_cast<uint64_t>(inputs[n]), 1338b8021494Sopenharmony_ci fbits, 1339b8021494Sopenharmony_ci name, 1340b8021494Sopenharmony_ci rawbits_to_fp(inputs[n]), 1341b8021494Sopenharmony_ci fbits); 1342b8021494Sopenharmony_ci printf(" Expected: 0x%0*" PRIx64 " (%" PRId64 ")\n", 1343b8021494Sopenharmony_ci d_bits / 4, 1344b8021494Sopenharmony_ci static_cast<uint64_t>(expected[d]), 1345b8021494Sopenharmony_ci static_cast<int64_t>(expected[d])); 1346b8021494Sopenharmony_ci printf(" Found: 0x%0*" PRIx64 " (%" PRId64 ")\n", 1347b8021494Sopenharmony_ci d_bits / 4, 1348b8021494Sopenharmony_ci static_cast<uint64_t>(results[d]), 1349b8021494Sopenharmony_ci static_cast<int64_t>(results[d])); 1350b8021494Sopenharmony_ci printf("\n"); 1351b8021494Sopenharmony_ci } 1352b8021494Sopenharmony_ci } 1353b8021494Sopenharmony_ci } 1354b8021494Sopenharmony_ci VIXL_ASSERT(d == expected_length); 1355b8021494Sopenharmony_ci if (error_count > kErrorReportLimit) { 1356b8021494Sopenharmony_ci printf("%u other errors follow.\n", error_count - kErrorReportLimit); 1357b8021494Sopenharmony_ci } 1358b8021494Sopenharmony_ci VIXL_CHECK(error_count == 0); 1359b8021494Sopenharmony_ci } 1360b8021494Sopenharmony_ci delete[] results; 1361b8021494Sopenharmony_ci} 1362b8021494Sopenharmony_ci 1363b8021494Sopenharmony_ci 1364b8021494Sopenharmony_ci// Test FP instructions. 1365b8021494Sopenharmony_ci// - The inputs[] array should be an array of rawbits representations of 1366b8021494Sopenharmony_ci// doubles or floats. This ensures that exact bit comparisons can be 1367b8021494Sopenharmony_ci// performed. 1368b8021494Sopenharmony_ci// - The expected[] array should be an array of unsigned integers. 1369b8021494Sopenharmony_citemplate <typename Tn, typename Td> 1370b8021494Sopenharmony_cistatic void TestFPToFixedU(const char* name, 1371b8021494Sopenharmony_ci TestFPToFixedHelper_t helper, 1372b8021494Sopenharmony_ci const Tn inputs[], 1373b8021494Sopenharmony_ci unsigned inputs_length, 1374b8021494Sopenharmony_ci const Td expected[], 1375b8021494Sopenharmony_ci unsigned expected_length) { 1376b8021494Sopenharmony_ci VIXL_ASSERT(inputs_length > 0); 1377b8021494Sopenharmony_ci 1378b8021494Sopenharmony_ci const unsigned d_bits = sizeof(Td) * 8; 1379b8021494Sopenharmony_ci const unsigned n_bits = sizeof(Tn) * 8; 1380b8021494Sopenharmony_ci 1381b8021494Sopenharmony_ci const unsigned results_length = inputs_length * (d_bits + 1); 1382b8021494Sopenharmony_ci Td* results = new Td[results_length]; 1383b8021494Sopenharmony_ci 1384b8021494Sopenharmony_ci bool skipped; 1385b8021494Sopenharmony_ci 1386b8021494Sopenharmony_ci TestFPToFixed_Helper(helper, 1387b8021494Sopenharmony_ci reinterpret_cast<uintptr_t>(inputs), 1388b8021494Sopenharmony_ci inputs_length, 1389b8021494Sopenharmony_ci reinterpret_cast<uintptr_t>(results), 1390b8021494Sopenharmony_ci d_bits, 1391b8021494Sopenharmony_ci n_bits, 1392b8021494Sopenharmony_ci &skipped); 1393b8021494Sopenharmony_ci 1394b8021494Sopenharmony_ci if (Test::generate_test_trace()) { 1395b8021494Sopenharmony_ci // Print the results. 1396b8021494Sopenharmony_ci printf("const uint%u_t kExpected_%s[] = {\n", d_bits, name); 1397b8021494Sopenharmony_ci for (unsigned d = 0; d < results_length; d++) { 1398b8021494Sopenharmony_ci printf(" %" PRIu64 "u,\n", static_cast<uint64_t>(results[d])); 1399b8021494Sopenharmony_ci } 1400b8021494Sopenharmony_ci printf("};\n"); 1401b8021494Sopenharmony_ci printf("const unsigned kExpectedCount_%s = %u;\n", name, results_length); 1402b8021494Sopenharmony_ci } else if (!skipped) { 1403b8021494Sopenharmony_ci // Check the results. 1404b8021494Sopenharmony_ci VIXL_CHECK(expected_length == results_length); 1405b8021494Sopenharmony_ci unsigned error_count = 0; 1406b8021494Sopenharmony_ci unsigned d = 0; 1407b8021494Sopenharmony_ci for (unsigned n = 0; n < inputs_length; n++) { 1408b8021494Sopenharmony_ci for (unsigned fbits = 0; fbits <= d_bits; ++fbits, d++) { 1409b8021494Sopenharmony_ci if (results[d] != expected[d]) { 1410b8021494Sopenharmony_ci if (++error_count > kErrorReportLimit) continue; 1411b8021494Sopenharmony_ci 1412b8021494Sopenharmony_ci printf("%s 0x%0*" PRIx64 " #%d (%s %g #%d):\n", 1413b8021494Sopenharmony_ci name, 1414b8021494Sopenharmony_ci n_bits / 4, 1415b8021494Sopenharmony_ci static_cast<uint64_t>(inputs[n]), 1416b8021494Sopenharmony_ci fbits, 1417b8021494Sopenharmony_ci name, 1418b8021494Sopenharmony_ci rawbits_to_fp(inputs[n]), 1419b8021494Sopenharmony_ci fbits); 1420b8021494Sopenharmony_ci printf(" Expected: 0x%0*" PRIx64 " (%" PRIu64 ")\n", 1421b8021494Sopenharmony_ci d_bits / 4, 1422b8021494Sopenharmony_ci static_cast<uint64_t>(expected[d]), 1423b8021494Sopenharmony_ci static_cast<uint64_t>(expected[d])); 1424b8021494Sopenharmony_ci printf(" Found: 0x%0*" PRIx64 " (%" PRIu64 ")\n", 1425b8021494Sopenharmony_ci d_bits / 4, 1426b8021494Sopenharmony_ci static_cast<uint64_t>(results[d]), 1427b8021494Sopenharmony_ci static_cast<uint64_t>(results[d])); 1428b8021494Sopenharmony_ci printf("\n"); 1429b8021494Sopenharmony_ci } 1430b8021494Sopenharmony_ci } 1431b8021494Sopenharmony_ci } 1432b8021494Sopenharmony_ci VIXL_ASSERT(d == expected_length); 1433b8021494Sopenharmony_ci if (error_count > kErrorReportLimit) { 1434b8021494Sopenharmony_ci printf("%u other errors follow.\n", error_count - kErrorReportLimit); 1435b8021494Sopenharmony_ci } 1436b8021494Sopenharmony_ci VIXL_CHECK(error_count == 0); 1437b8021494Sopenharmony_ci } 1438b8021494Sopenharmony_ci delete[] results; 1439b8021494Sopenharmony_ci} 1440b8021494Sopenharmony_ci 1441b8021494Sopenharmony_ci 1442b8021494Sopenharmony_ci// ==== Tests for instructions of the form <INST> VReg, VReg. ==== 1443b8021494Sopenharmony_ci 1444b8021494Sopenharmony_ci 1445b8021494Sopenharmony_cistatic void Test1OpNEON_Helper(Test1OpNEONHelper_t helper, 1446b8021494Sopenharmony_ci uintptr_t inputs_n, 1447b8021494Sopenharmony_ci unsigned inputs_n_length, 1448b8021494Sopenharmony_ci uintptr_t results, 1449b8021494Sopenharmony_ci VectorFormat vd_form, 1450b8021494Sopenharmony_ci VectorFormat vn_form, 1451b8021494Sopenharmony_ci bool* skipped) { 1452b8021494Sopenharmony_ci VIXL_ASSERT(vd_form != kFormatUndefined); 1453b8021494Sopenharmony_ci VIXL_ASSERT(vn_form != kFormatUndefined); 1454b8021494Sopenharmony_ci 1455b8021494Sopenharmony_ci CPUFeatures features; 1456b8021494Sopenharmony_ci features.Combine(CPUFeatures::kNEON, 1457b8021494Sopenharmony_ci CPUFeatures::kFP, 1458b8021494Sopenharmony_ci CPUFeatures::kRDM, 1459b8021494Sopenharmony_ci CPUFeatures::kNEONHalf); 1460b8021494Sopenharmony_ci // For frint{32,64}{x,y} variants. 1461b8021494Sopenharmony_ci features.Combine(CPUFeatures::kFrintToFixedSizedInt); 1462b8021494Sopenharmony_ci SETUP_WITH_FEATURES(features); 1463b8021494Sopenharmony_ci START(); 1464b8021494Sopenharmony_ci 1465b8021494Sopenharmony_ci // Roll up the loop to keep the code size down. 1466b8021494Sopenharmony_ci Label loop_n; 1467b8021494Sopenharmony_ci 1468b8021494Sopenharmony_ci Register out = x0; 1469b8021494Sopenharmony_ci Register inputs_n_base = x1; 1470b8021494Sopenharmony_ci Register inputs_n_last_16bytes = x3; 1471b8021494Sopenharmony_ci Register index_n = x5; 1472b8021494Sopenharmony_ci 1473b8021494Sopenharmony_ci // TODO: Refactor duplicate definitions below with a VRegister::As() routine. 1474b8021494Sopenharmony_ci const unsigned vd_bits = RegisterSizeInBitsFromFormat(vd_form); 1475b8021494Sopenharmony_ci const unsigned vd_lane_count = LaneCountFromFormat(vd_form); 1476b8021494Sopenharmony_ci 1477b8021494Sopenharmony_ci const unsigned vn_bits = RegisterSizeInBitsFromFormat(vn_form); 1478b8021494Sopenharmony_ci const unsigned vn_lane_count = LaneCountFromFormat(vn_form); 1479b8021494Sopenharmony_ci const unsigned vn_lane_bytes = LaneSizeInBytesFromFormat(vn_form); 1480b8021494Sopenharmony_ci const unsigned vn_lane_bytes_log2 = LaneSizeInBytesLog2FromFormat(vn_form); 1481b8021494Sopenharmony_ci const unsigned vn_lane_bits = LaneSizeInBitsFromFormat(vn_form); 1482b8021494Sopenharmony_ci 1483b8021494Sopenharmony_ci 1484b8021494Sopenharmony_ci // These will be either a D- or a Q-register form, with a single lane 1485b8021494Sopenharmony_ci // (for use in scalar load and store operations). 1486b8021494Sopenharmony_ci VRegister vd = VRegister(0, vd_bits); 1487b8021494Sopenharmony_ci VRegister vn = v1.V16B(); 1488b8021494Sopenharmony_ci VRegister vntmp = v3.V16B(); 1489b8021494Sopenharmony_ci 1490b8021494Sopenharmony_ci // These will have the correct format for use when calling 'helper'. 1491b8021494Sopenharmony_ci VRegister vd_helper = VRegister(0, vd_bits, vd_lane_count); 1492b8021494Sopenharmony_ci VRegister vn_helper = VRegister(1, vn_bits, vn_lane_count); 1493b8021494Sopenharmony_ci 1494b8021494Sopenharmony_ci // 'v*tmp_single' will be either 'Vt.B', 'Vt.H', 'Vt.S' or 'Vt.D'. 1495b8021494Sopenharmony_ci VRegister vntmp_single = VRegister(3, vn_lane_bits); 1496b8021494Sopenharmony_ci 1497b8021494Sopenharmony_ci __ Mov(out, results); 1498b8021494Sopenharmony_ci 1499b8021494Sopenharmony_ci __ Mov(inputs_n_base, inputs_n); 1500b8021494Sopenharmony_ci __ Mov(inputs_n_last_16bytes, 1501b8021494Sopenharmony_ci inputs_n + (vn_lane_bytes * inputs_n_length) - 16); 1502b8021494Sopenharmony_ci 1503b8021494Sopenharmony_ci __ Ldr(vn, MemOperand(inputs_n_last_16bytes)); 1504b8021494Sopenharmony_ci 1505b8021494Sopenharmony_ci __ Mov(index_n, 0); 1506b8021494Sopenharmony_ci __ Bind(&loop_n); 1507b8021494Sopenharmony_ci 1508b8021494Sopenharmony_ci __ Ldr(vntmp_single, 1509b8021494Sopenharmony_ci MemOperand(inputs_n_base, index_n, LSL, vn_lane_bytes_log2)); 1510b8021494Sopenharmony_ci __ Ext(vn, vn, vntmp, vn_lane_bytes); 1511b8021494Sopenharmony_ci 1512b8021494Sopenharmony_ci // Set the destination to zero. 1513b8021494Sopenharmony_ci // TODO: Setting the destination to values other than zero 1514b8021494Sopenharmony_ci // might be a better test for instructions such as sqxtn2 1515b8021494Sopenharmony_ci // which may leave parts of V registers unchanged. 1516b8021494Sopenharmony_ci __ Movi(vd.V16B(), 0); 1517b8021494Sopenharmony_ci 1518b8021494Sopenharmony_ci { 1519b8021494Sopenharmony_ci SingleEmissionCheckScope guard(&masm); 1520b8021494Sopenharmony_ci (masm.*helper)(vd_helper, vn_helper); 1521b8021494Sopenharmony_ci } 1522b8021494Sopenharmony_ci __ Str(vd, MemOperand(out, vd.GetSizeInBytes(), PostIndex)); 1523b8021494Sopenharmony_ci 1524b8021494Sopenharmony_ci __ Add(index_n, index_n, 1); 1525b8021494Sopenharmony_ci __ Cmp(index_n, inputs_n_length); 1526b8021494Sopenharmony_ci __ B(lo, &loop_n); 1527b8021494Sopenharmony_ci 1528b8021494Sopenharmony_ci END(); 1529b8021494Sopenharmony_ci TRY_RUN(skipped); 1530b8021494Sopenharmony_ci} 1531b8021494Sopenharmony_ci 1532b8021494Sopenharmony_ci 1533b8021494Sopenharmony_ci// Test NEON instructions. The inputs_*[] and expected[] arrays should be 1534b8021494Sopenharmony_ci// arrays of rawbit representation of input values. This ensures that 1535b8021494Sopenharmony_ci// exact bit comparisons can be performed. 1536b8021494Sopenharmony_citemplate <typename Td, typename Tn> 1537b8021494Sopenharmony_cistatic void Test1OpNEON(const char* name, 1538b8021494Sopenharmony_ci Test1OpNEONHelper_t helper, 1539b8021494Sopenharmony_ci const Tn inputs_n[], 1540b8021494Sopenharmony_ci unsigned inputs_n_length, 1541b8021494Sopenharmony_ci const Td expected[], 1542b8021494Sopenharmony_ci unsigned expected_length, 1543b8021494Sopenharmony_ci VectorFormat vd_form, 1544b8021494Sopenharmony_ci VectorFormat vn_form) { 1545b8021494Sopenharmony_ci VIXL_ASSERT(inputs_n_length > 0); 1546b8021494Sopenharmony_ci 1547b8021494Sopenharmony_ci const unsigned vd_lane_count = LaneCountFromFormat(vd_form); 1548b8021494Sopenharmony_ci const unsigned vn_lane_bytes = LaneSizeInBytesFromFormat(vn_form); 1549b8021494Sopenharmony_ci const unsigned vn_lane_count = LaneCountFromFormat(vn_form); 1550b8021494Sopenharmony_ci 1551b8021494Sopenharmony_ci const unsigned results_length = inputs_n_length; 1552b8021494Sopenharmony_ci Td* results = new Td[results_length * vd_lane_count]; 1553b8021494Sopenharmony_ci const unsigned lane_bit = sizeof(Td) * 8; 1554b8021494Sopenharmony_ci const unsigned lane_len_in_hex = MaxHexCharCount<Td, Tn>(); 1555b8021494Sopenharmony_ci 1556b8021494Sopenharmony_ci bool skipped; 1557b8021494Sopenharmony_ci 1558b8021494Sopenharmony_ci Test1OpNEON_Helper(helper, 1559b8021494Sopenharmony_ci reinterpret_cast<uintptr_t>(inputs_n), 1560b8021494Sopenharmony_ci inputs_n_length, 1561b8021494Sopenharmony_ci reinterpret_cast<uintptr_t>(results), 1562b8021494Sopenharmony_ci vd_form, 1563b8021494Sopenharmony_ci vn_form, 1564b8021494Sopenharmony_ci &skipped); 1565b8021494Sopenharmony_ci 1566b8021494Sopenharmony_ci if (Test::generate_test_trace()) { 1567b8021494Sopenharmony_ci // Print the results. 1568b8021494Sopenharmony_ci printf("const uint%u_t kExpected_NEON_%s[] = {\n", lane_bit, name); 1569b8021494Sopenharmony_ci for (unsigned iteration = 0; iteration < results_length; iteration++) { 1570b8021494Sopenharmony_ci printf(" "); 1571b8021494Sopenharmony_ci // Output a separate result for each element of the result vector. 1572b8021494Sopenharmony_ci for (unsigned lane = 0; lane < vd_lane_count; lane++) { 1573b8021494Sopenharmony_ci unsigned index = lane + (iteration * vd_lane_count); 1574b8021494Sopenharmony_ci printf(" 0x%0*" PRIx64 ",", 1575b8021494Sopenharmony_ci lane_len_in_hex, 1576b8021494Sopenharmony_ci static_cast<uint64_t>(results[index])); 1577b8021494Sopenharmony_ci } 1578b8021494Sopenharmony_ci printf("\n"); 1579b8021494Sopenharmony_ci } 1580b8021494Sopenharmony_ci 1581b8021494Sopenharmony_ci printf("};\n"); 1582b8021494Sopenharmony_ci printf("const unsigned kExpectedCount_NEON_%s = %u;\n", 1583b8021494Sopenharmony_ci name, 1584b8021494Sopenharmony_ci results_length); 1585b8021494Sopenharmony_ci } else if (!skipped) { 1586b8021494Sopenharmony_ci // Check the results. 1587b8021494Sopenharmony_ci VIXL_CHECK(expected_length == results_length); 1588b8021494Sopenharmony_ci unsigned error_count = 0; 1589b8021494Sopenharmony_ci unsigned d = 0; 1590b8021494Sopenharmony_ci const char* padding = " "; 1591b8021494Sopenharmony_ci VIXL_ASSERT(strlen(padding) >= (lane_len_in_hex + 1)); 1592b8021494Sopenharmony_ci for (unsigned n = 0; n < inputs_n_length; n++, d++) { 1593b8021494Sopenharmony_ci bool error_in_vector = false; 1594b8021494Sopenharmony_ci 1595b8021494Sopenharmony_ci for (unsigned lane = 0; lane < vd_lane_count; lane++) { 1596b8021494Sopenharmony_ci unsigned output_index = (n * vd_lane_count) + lane; 1597b8021494Sopenharmony_ci 1598b8021494Sopenharmony_ci if (results[output_index] != expected[output_index]) { 1599b8021494Sopenharmony_ci error_in_vector = true; 1600b8021494Sopenharmony_ci break; 1601b8021494Sopenharmony_ci } 1602b8021494Sopenharmony_ci } 1603b8021494Sopenharmony_ci 1604b8021494Sopenharmony_ci if (error_in_vector && (++error_count <= kErrorReportLimit)) { 1605b8021494Sopenharmony_ci printf("%s\n", name); 1606b8021494Sopenharmony_ci printf(" Vn%.*s| Vd%.*s| Expected\n", 1607b8021494Sopenharmony_ci lane_len_in_hex + 1, 1608b8021494Sopenharmony_ci padding, 1609b8021494Sopenharmony_ci lane_len_in_hex + 1, 1610b8021494Sopenharmony_ci padding); 1611b8021494Sopenharmony_ci 1612b8021494Sopenharmony_ci const unsigned first_index_n = 1613b8021494Sopenharmony_ci inputs_n_length - (16 / vn_lane_bytes) + n + 1; 1614b8021494Sopenharmony_ci 1615b8021494Sopenharmony_ci for (unsigned lane = 0; lane < std::max(vd_lane_count, vn_lane_count); 1616b8021494Sopenharmony_ci lane++) { 1617b8021494Sopenharmony_ci unsigned output_index = (n * vd_lane_count) + lane; 1618b8021494Sopenharmony_ci unsigned input_index_n = (first_index_n + lane) % inputs_n_length; 1619b8021494Sopenharmony_ci 1620b8021494Sopenharmony_ci printf("%c0x%0*" PRIx64 " | 0x%0*" PRIx64 1621b8021494Sopenharmony_ci " " 1622b8021494Sopenharmony_ci "| 0x%0*" PRIx64 "\n", 1623b8021494Sopenharmony_ci results[output_index] != expected[output_index] ? '*' : ' ', 1624b8021494Sopenharmony_ci lane_len_in_hex, 1625b8021494Sopenharmony_ci static_cast<uint64_t>(inputs_n[input_index_n]), 1626b8021494Sopenharmony_ci lane_len_in_hex, 1627b8021494Sopenharmony_ci static_cast<uint64_t>(results[output_index]), 1628b8021494Sopenharmony_ci lane_len_in_hex, 1629b8021494Sopenharmony_ci static_cast<uint64_t>(expected[output_index])); 1630b8021494Sopenharmony_ci } 1631b8021494Sopenharmony_ci } 1632b8021494Sopenharmony_ci } 1633b8021494Sopenharmony_ci VIXL_ASSERT(d == expected_length); 1634b8021494Sopenharmony_ci if (error_count > kErrorReportLimit) { 1635b8021494Sopenharmony_ci printf("%u other errors follow.\n", error_count - kErrorReportLimit); 1636b8021494Sopenharmony_ci } 1637b8021494Sopenharmony_ci VIXL_CHECK(error_count == 0); 1638b8021494Sopenharmony_ci } 1639b8021494Sopenharmony_ci delete[] results; 1640b8021494Sopenharmony_ci} 1641b8021494Sopenharmony_ci 1642b8021494Sopenharmony_ci 1643b8021494Sopenharmony_ci// ==== Tests for instructions of the form <mnemonic> <V><d>, <Vn>.<T> ==== 1644b8021494Sopenharmony_ci// where <V> is one of B, H, S or D registers. 1645b8021494Sopenharmony_ci// e.g. saddlv H1, v0.8B 1646b8021494Sopenharmony_ci 1647b8021494Sopenharmony_ci// TODO: Change tests to store all lanes of the resulting V register. 1648b8021494Sopenharmony_ci// Some tests store all 128 bits of the resulting V register to 1649b8021494Sopenharmony_ci// check the simulator's behaviour on the rest of the register. 1650b8021494Sopenharmony_ci// This is better than storing the affected lanes only. 1651b8021494Sopenharmony_ci// Change any tests such as the 'Across' template to do the same. 1652b8021494Sopenharmony_ci 1653b8021494Sopenharmony_cistatic void Test1OpAcrossNEON_Helper(Test1OpNEONHelper_t helper, 1654b8021494Sopenharmony_ci uintptr_t inputs_n, 1655b8021494Sopenharmony_ci unsigned inputs_n_length, 1656b8021494Sopenharmony_ci uintptr_t results, 1657b8021494Sopenharmony_ci VectorFormat vd_form, 1658b8021494Sopenharmony_ci VectorFormat vn_form, 1659b8021494Sopenharmony_ci bool* skipped) { 1660b8021494Sopenharmony_ci VIXL_ASSERT(vd_form != kFormatUndefined); 1661b8021494Sopenharmony_ci VIXL_ASSERT(vn_form != kFormatUndefined); 1662b8021494Sopenharmony_ci 1663b8021494Sopenharmony_ci SETUP_WITH_FEATURES(CPUFeatures::kNEON, 1664b8021494Sopenharmony_ci CPUFeatures::kFP, 1665b8021494Sopenharmony_ci CPUFeatures::kNEONHalf); 1666b8021494Sopenharmony_ci START(); 1667b8021494Sopenharmony_ci 1668b8021494Sopenharmony_ci // Roll up the loop to keep the code size down. 1669b8021494Sopenharmony_ci Label loop_n; 1670b8021494Sopenharmony_ci 1671b8021494Sopenharmony_ci Register out = x0; 1672b8021494Sopenharmony_ci Register inputs_n_base = x1; 1673b8021494Sopenharmony_ci Register inputs_n_last_vector = x3; 1674b8021494Sopenharmony_ci Register index_n = x5; 1675b8021494Sopenharmony_ci 1676b8021494Sopenharmony_ci // TODO: Refactor duplicate definitions below with a VRegister::As() routine. 1677b8021494Sopenharmony_ci const unsigned vd_bits = RegisterSizeInBitsFromFormat(vd_form); 1678b8021494Sopenharmony_ci const unsigned vn_bits = RegisterSizeInBitsFromFormat(vn_form); 1679b8021494Sopenharmony_ci const unsigned vn_lane_count = LaneCountFromFormat(vn_form); 1680b8021494Sopenharmony_ci const unsigned vn_lane_bytes = LaneSizeInBytesFromFormat(vn_form); 1681b8021494Sopenharmony_ci const unsigned vn_lane_bytes_log2 = LaneSizeInBytesLog2FromFormat(vn_form); 1682b8021494Sopenharmony_ci const unsigned vn_lane_bits = LaneSizeInBitsFromFormat(vn_form); 1683b8021494Sopenharmony_ci 1684b8021494Sopenharmony_ci // Test destructive operations by (arbitrarily) using the same register for 1685b8021494Sopenharmony_ci // B and S lane sizes. 1686b8021494Sopenharmony_ci bool destructive = (vd_bits == kBRegSize) || (vd_bits == kSRegSize); 1687b8021494Sopenharmony_ci 1688b8021494Sopenharmony_ci // Create two aliases for v0; the first is the destination for the tested 1689b8021494Sopenharmony_ci // instruction, the second, the whole Q register to check the results. 1690b8021494Sopenharmony_ci VRegister vd = VRegister(0, vd_bits); 1691b8021494Sopenharmony_ci VRegister vdstr = VRegister(0, kQRegSize); 1692b8021494Sopenharmony_ci 1693b8021494Sopenharmony_ci VRegister vn = VRegister(1, vn_bits); 1694b8021494Sopenharmony_ci VRegister vntmp = VRegister(3, vn_bits); 1695b8021494Sopenharmony_ci 1696b8021494Sopenharmony_ci // These will have the correct format for use when calling 'helper'. 1697b8021494Sopenharmony_ci VRegister vd_helper = VRegister(0, vn_bits, vn_lane_count); 1698b8021494Sopenharmony_ci VRegister vn_helper = VRegister(1, vn_bits, vn_lane_count); 1699b8021494Sopenharmony_ci 1700b8021494Sopenharmony_ci // 'v*tmp_single' will be either 'Vt.B', 'Vt.H', 'Vt.S' or 'Vt.D'. 1701b8021494Sopenharmony_ci VRegister vntmp_single = VRegister(3, vn_lane_bits); 1702b8021494Sopenharmony_ci 1703b8021494Sopenharmony_ci // Same registers for use in the 'ext' instructions. 1704b8021494Sopenharmony_ci VRegister vn_ext = (kDRegSize == vn_bits) ? vn.V8B() : vn.V16B(); 1705b8021494Sopenharmony_ci VRegister vntmp_ext = (kDRegSize == vn_bits) ? vntmp.V8B() : vntmp.V16B(); 1706b8021494Sopenharmony_ci 1707b8021494Sopenharmony_ci __ Mov(out, results); 1708b8021494Sopenharmony_ci 1709b8021494Sopenharmony_ci __ Mov(inputs_n_base, inputs_n); 1710b8021494Sopenharmony_ci __ Mov(inputs_n_last_vector, 1711b8021494Sopenharmony_ci inputs_n + vn_lane_bytes * (inputs_n_length - vn_lane_count)); 1712b8021494Sopenharmony_ci 1713b8021494Sopenharmony_ci __ Ldr(vn, MemOperand(inputs_n_last_vector)); 1714b8021494Sopenharmony_ci 1715b8021494Sopenharmony_ci __ Mov(index_n, 0); 1716b8021494Sopenharmony_ci __ Bind(&loop_n); 1717b8021494Sopenharmony_ci 1718b8021494Sopenharmony_ci __ Ldr(vntmp_single, 1719b8021494Sopenharmony_ci MemOperand(inputs_n_base, index_n, LSL, vn_lane_bytes_log2)); 1720b8021494Sopenharmony_ci __ Ext(vn_ext, vn_ext, vntmp_ext, vn_lane_bytes); 1721b8021494Sopenharmony_ci 1722b8021494Sopenharmony_ci if (destructive) { 1723b8021494Sopenharmony_ci __ Mov(vd_helper, vn_helper); 1724b8021494Sopenharmony_ci SingleEmissionCheckScope guard(&masm); 1725b8021494Sopenharmony_ci (masm.*helper)(vd, vd_helper); 1726b8021494Sopenharmony_ci } else { 1727b8021494Sopenharmony_ci SingleEmissionCheckScope guard(&masm); 1728b8021494Sopenharmony_ci (masm.*helper)(vd, vn_helper); 1729b8021494Sopenharmony_ci } 1730b8021494Sopenharmony_ci 1731b8021494Sopenharmony_ci __ Str(vdstr, MemOperand(out, kQRegSizeInBytes, PostIndex)); 1732b8021494Sopenharmony_ci 1733b8021494Sopenharmony_ci __ Add(index_n, index_n, 1); 1734b8021494Sopenharmony_ci __ Cmp(index_n, inputs_n_length); 1735b8021494Sopenharmony_ci __ B(lo, &loop_n); 1736b8021494Sopenharmony_ci 1737b8021494Sopenharmony_ci END(); 1738b8021494Sopenharmony_ci TRY_RUN(skipped); 1739b8021494Sopenharmony_ci} 1740b8021494Sopenharmony_ci 1741b8021494Sopenharmony_ci// Test NEON instructions. The inputs_*[] and expected[] arrays should be 1742b8021494Sopenharmony_ci// arrays of rawbit representation of input values. This ensures that 1743b8021494Sopenharmony_ci// exact bit comparisons can be performed. 1744b8021494Sopenharmony_citemplate <typename Td, typename Tn> 1745b8021494Sopenharmony_cistatic void Test1OpAcrossNEON(const char* name, 1746b8021494Sopenharmony_ci Test1OpNEONHelper_t helper, 1747b8021494Sopenharmony_ci const Tn inputs_n[], 1748b8021494Sopenharmony_ci unsigned inputs_n_length, 1749b8021494Sopenharmony_ci const Td expected[], 1750b8021494Sopenharmony_ci unsigned expected_length, 1751b8021494Sopenharmony_ci VectorFormat vd_form, 1752b8021494Sopenharmony_ci VectorFormat vn_form) { 1753b8021494Sopenharmony_ci VIXL_ASSERT(inputs_n_length > 0); 1754b8021494Sopenharmony_ci 1755b8021494Sopenharmony_ci const unsigned vd_lane_count = LaneCountFromFormat(vd_form); 1756b8021494Sopenharmony_ci const unsigned vd_lanes_per_q = MaxLaneCountFromFormat(vd_form); 1757b8021494Sopenharmony_ci 1758b8021494Sopenharmony_ci const unsigned results_length = inputs_n_length; 1759b8021494Sopenharmony_ci Td* results = new Td[results_length * vd_lanes_per_q]; 1760b8021494Sopenharmony_ci const unsigned lane_bit = sizeof(Td) * 8; 1761b8021494Sopenharmony_ci const unsigned lane_len_in_hex = MaxHexCharCount<Td, Tn>(); 1762b8021494Sopenharmony_ci 1763b8021494Sopenharmony_ci bool skipped; 1764b8021494Sopenharmony_ci 1765b8021494Sopenharmony_ci Test1OpAcrossNEON_Helper(helper, 1766b8021494Sopenharmony_ci reinterpret_cast<uintptr_t>(inputs_n), 1767b8021494Sopenharmony_ci inputs_n_length, 1768b8021494Sopenharmony_ci reinterpret_cast<uintptr_t>(results), 1769b8021494Sopenharmony_ci vd_form, 1770b8021494Sopenharmony_ci vn_form, 1771b8021494Sopenharmony_ci &skipped); 1772b8021494Sopenharmony_ci 1773b8021494Sopenharmony_ci if (Test::generate_test_trace()) { 1774b8021494Sopenharmony_ci // Print the results. 1775b8021494Sopenharmony_ci printf("const uint%u_t kExpected_NEON_%s[] = {\n", lane_bit, name); 1776b8021494Sopenharmony_ci for (unsigned iteration = 0; iteration < results_length; iteration++) { 1777b8021494Sopenharmony_ci printf(" "); 1778b8021494Sopenharmony_ci // Output a separate result for each element of the result vector. 1779b8021494Sopenharmony_ci for (unsigned lane = 0; lane < vd_lane_count; lane++) { 1780b8021494Sopenharmony_ci unsigned index = lane + (iteration * vd_lanes_per_q); 1781b8021494Sopenharmony_ci printf(" 0x%0*" PRIx64 ",", 1782b8021494Sopenharmony_ci lane_len_in_hex, 1783b8021494Sopenharmony_ci static_cast<uint64_t>(results[index])); 1784b8021494Sopenharmony_ci } 1785b8021494Sopenharmony_ci printf("\n"); 1786b8021494Sopenharmony_ci } 1787b8021494Sopenharmony_ci 1788b8021494Sopenharmony_ci printf("};\n"); 1789b8021494Sopenharmony_ci printf("const unsigned kExpectedCount_NEON_%s = %u;\n", 1790b8021494Sopenharmony_ci name, 1791b8021494Sopenharmony_ci results_length); 1792b8021494Sopenharmony_ci } else if (!skipped) { 1793b8021494Sopenharmony_ci // Check the results. 1794b8021494Sopenharmony_ci VIXL_CHECK(expected_length == results_length); 1795b8021494Sopenharmony_ci unsigned error_count = 0; 1796b8021494Sopenharmony_ci unsigned d = 0; 1797b8021494Sopenharmony_ci const char* padding = " "; 1798b8021494Sopenharmony_ci VIXL_ASSERT(strlen(padding) >= (lane_len_in_hex + 1)); 1799b8021494Sopenharmony_ci for (unsigned n = 0; n < inputs_n_length; n++, d++) { 1800b8021494Sopenharmony_ci bool error_in_vector = false; 1801b8021494Sopenharmony_ci 1802b8021494Sopenharmony_ci for (unsigned lane = 0; lane < vd_lane_count; lane++) { 1803b8021494Sopenharmony_ci unsigned expected_index = (n * vd_lane_count) + lane; 1804b8021494Sopenharmony_ci unsigned results_index = (n * vd_lanes_per_q) + lane; 1805b8021494Sopenharmony_ci 1806b8021494Sopenharmony_ci if (results[results_index] != expected[expected_index]) { 1807b8021494Sopenharmony_ci error_in_vector = true; 1808b8021494Sopenharmony_ci break; 1809b8021494Sopenharmony_ci } 1810b8021494Sopenharmony_ci } 1811b8021494Sopenharmony_ci 1812b8021494Sopenharmony_ci // For across operations, the remaining lanes should be zero. 1813b8021494Sopenharmony_ci for (unsigned lane = vd_lane_count; lane < vd_lanes_per_q; lane++) { 1814b8021494Sopenharmony_ci unsigned results_index = (n * vd_lanes_per_q) + lane; 1815b8021494Sopenharmony_ci if (results[results_index] != 0) { 1816b8021494Sopenharmony_ci error_in_vector = true; 1817b8021494Sopenharmony_ci break; 1818b8021494Sopenharmony_ci } 1819b8021494Sopenharmony_ci } 1820b8021494Sopenharmony_ci 1821b8021494Sopenharmony_ci if (error_in_vector && (++error_count <= kErrorReportLimit)) { 1822b8021494Sopenharmony_ci const unsigned vn_lane_count = LaneCountFromFormat(vn_form); 1823b8021494Sopenharmony_ci 1824b8021494Sopenharmony_ci printf("%s\n", name); 1825b8021494Sopenharmony_ci printf(" Vn%.*s| Vd%.*s| Expected\n", 1826b8021494Sopenharmony_ci lane_len_in_hex + 1, 1827b8021494Sopenharmony_ci padding, 1828b8021494Sopenharmony_ci lane_len_in_hex + 1, 1829b8021494Sopenharmony_ci padding); 1830b8021494Sopenharmony_ci 1831b8021494Sopenharmony_ci // TODO: In case of an error, all tests print out as many elements as 1832b8021494Sopenharmony_ci // there are lanes in the output or input vectors. This way 1833b8021494Sopenharmony_ci // the viewer can read all the values that were needed for the 1834b8021494Sopenharmony_ci // operation but the output contains also unnecessary values. 1835b8021494Sopenharmony_ci // These prints can be improved according to the arguments 1836b8021494Sopenharmony_ci // passed to test functions. 1837b8021494Sopenharmony_ci // This output for the 'Across' category has the required 1838b8021494Sopenharmony_ci // modifications. 1839b8021494Sopenharmony_ci for (unsigned lane = 0; lane < vn_lane_count; lane++) { 1840b8021494Sopenharmony_ci unsigned results_index = 1841b8021494Sopenharmony_ci (n * vd_lanes_per_q) + ((vn_lane_count - 1) - lane); 1842b8021494Sopenharmony_ci unsigned input_index_n = 1843b8021494Sopenharmony_ci (inputs_n_length - vn_lane_count + n + 1 + lane) % 1844b8021494Sopenharmony_ci inputs_n_length; 1845b8021494Sopenharmony_ci 1846b8021494Sopenharmony_ci Td expect = 0; 1847b8021494Sopenharmony_ci if ((vn_lane_count - 1) == lane) { 1848b8021494Sopenharmony_ci // This is the last lane to be printed, ie. the least-significant 1849b8021494Sopenharmony_ci // lane, so use the expected value; any other lane should be zero. 1850b8021494Sopenharmony_ci unsigned expected_index = n * vd_lane_count; 1851b8021494Sopenharmony_ci expect = expected[expected_index]; 1852b8021494Sopenharmony_ci } 1853b8021494Sopenharmony_ci printf("%c0x%0*" PRIx64 " | 0x%0*" PRIx64 " | 0x%0*" PRIx64 "\n", 1854b8021494Sopenharmony_ci results[results_index] != expect ? '*' : ' ', 1855b8021494Sopenharmony_ci lane_len_in_hex, 1856b8021494Sopenharmony_ci static_cast<uint64_t>(inputs_n[input_index_n]), 1857b8021494Sopenharmony_ci lane_len_in_hex, 1858b8021494Sopenharmony_ci static_cast<uint64_t>(results[results_index]), 1859b8021494Sopenharmony_ci lane_len_in_hex, 1860b8021494Sopenharmony_ci static_cast<uint64_t>(expect)); 1861b8021494Sopenharmony_ci } 1862b8021494Sopenharmony_ci } 1863b8021494Sopenharmony_ci } 1864b8021494Sopenharmony_ci VIXL_ASSERT(d == expected_length); 1865b8021494Sopenharmony_ci if (error_count > kErrorReportLimit) { 1866b8021494Sopenharmony_ci printf("%u other errors follow.\n", error_count - kErrorReportLimit); 1867b8021494Sopenharmony_ci } 1868b8021494Sopenharmony_ci VIXL_CHECK(error_count == 0); 1869b8021494Sopenharmony_ci } 1870b8021494Sopenharmony_ci delete[] results; 1871b8021494Sopenharmony_ci} 1872b8021494Sopenharmony_ci 1873b8021494Sopenharmony_ci 1874b8021494Sopenharmony_ci// ==== Tests for instructions of the form <INST> VReg, VReg, VReg. ==== 1875b8021494Sopenharmony_ci 1876b8021494Sopenharmony_ci// TODO: Iterate over inputs_d once the traces file is split. 1877b8021494Sopenharmony_ci 1878b8021494Sopenharmony_cistatic void Test2OpNEON_Helper(Test2OpNEONHelper_t helper, 1879b8021494Sopenharmony_ci uintptr_t inputs_d, 1880b8021494Sopenharmony_ci uintptr_t inputs_n, 1881b8021494Sopenharmony_ci unsigned inputs_n_length, 1882b8021494Sopenharmony_ci uintptr_t inputs_m, 1883b8021494Sopenharmony_ci unsigned inputs_m_length, 1884b8021494Sopenharmony_ci uintptr_t results, 1885b8021494Sopenharmony_ci VectorFormat vd_form, 1886b8021494Sopenharmony_ci VectorFormat vn_form, 1887b8021494Sopenharmony_ci VectorFormat vm_form, 1888b8021494Sopenharmony_ci bool* skipped) { 1889b8021494Sopenharmony_ci VIXL_ASSERT(vd_form != kFormatUndefined); 1890b8021494Sopenharmony_ci VIXL_ASSERT(vn_form != kFormatUndefined); 1891b8021494Sopenharmony_ci VIXL_ASSERT(vm_form != kFormatUndefined); 1892b8021494Sopenharmony_ci 1893b8021494Sopenharmony_ci CPUFeatures features; 1894b8021494Sopenharmony_ci features.Combine(CPUFeatures::kNEON, CPUFeatures::kNEONHalf); 1895b8021494Sopenharmony_ci features.Combine(CPUFeatures::kFP); 1896b8021494Sopenharmony_ci features.Combine(CPUFeatures::kRDM); 1897b8021494Sopenharmony_ci features.Combine(CPUFeatures::kDotProduct); 1898b8021494Sopenharmony_ci features.Combine(CPUFeatures::kFHM); 1899b8021494Sopenharmony_ci SETUP_WITH_FEATURES(features); 1900b8021494Sopenharmony_ci START(); 1901b8021494Sopenharmony_ci 1902b8021494Sopenharmony_ci // Roll up the loop to keep the code size down. 1903b8021494Sopenharmony_ci Label loop_n, loop_m; 1904b8021494Sopenharmony_ci 1905b8021494Sopenharmony_ci Register out = x0; 1906b8021494Sopenharmony_ci Register inputs_n_base = x1; 1907b8021494Sopenharmony_ci Register inputs_m_base = x2; 1908b8021494Sopenharmony_ci Register inputs_d_base = x3; 1909b8021494Sopenharmony_ci Register inputs_n_last_16bytes = x4; 1910b8021494Sopenharmony_ci Register inputs_m_last_16bytes = x5; 1911b8021494Sopenharmony_ci Register index_n = x6; 1912b8021494Sopenharmony_ci Register index_m = x7; 1913b8021494Sopenharmony_ci 1914b8021494Sopenharmony_ci // TODO: Refactor duplicate definitions below with a VRegister::As() routine. 1915b8021494Sopenharmony_ci const unsigned vd_bits = RegisterSizeInBitsFromFormat(vd_form); 1916b8021494Sopenharmony_ci const unsigned vd_lane_count = LaneCountFromFormat(vd_form); 1917b8021494Sopenharmony_ci 1918b8021494Sopenharmony_ci const unsigned vn_bits = RegisterSizeInBitsFromFormat(vn_form); 1919b8021494Sopenharmony_ci const unsigned vn_lane_count = LaneCountFromFormat(vn_form); 1920b8021494Sopenharmony_ci const unsigned vn_lane_bytes = LaneSizeInBytesFromFormat(vn_form); 1921b8021494Sopenharmony_ci const unsigned vn_lane_bytes_log2 = LaneSizeInBytesLog2FromFormat(vn_form); 1922b8021494Sopenharmony_ci const unsigned vn_lane_bits = LaneSizeInBitsFromFormat(vn_form); 1923b8021494Sopenharmony_ci 1924b8021494Sopenharmony_ci const unsigned vm_bits = RegisterSizeInBitsFromFormat(vm_form); 1925b8021494Sopenharmony_ci const unsigned vm_lane_count = LaneCountFromFormat(vm_form); 1926b8021494Sopenharmony_ci const unsigned vm_lane_bytes = LaneSizeInBytesFromFormat(vm_form); 1927b8021494Sopenharmony_ci const unsigned vm_lane_bytes_log2 = LaneSizeInBytesLog2FromFormat(vm_form); 1928b8021494Sopenharmony_ci const unsigned vm_lane_bits = LaneSizeInBitsFromFormat(vm_form); 1929b8021494Sopenharmony_ci 1930b8021494Sopenharmony_ci 1931b8021494Sopenharmony_ci // Always load and store 128 bits regardless of the format. 1932b8021494Sopenharmony_ci VRegister vd = v0.V16B(); 1933b8021494Sopenharmony_ci VRegister vn = v1.V16B(); 1934b8021494Sopenharmony_ci VRegister vm = v2.V16B(); 1935b8021494Sopenharmony_ci VRegister vntmp = v3.V16B(); 1936b8021494Sopenharmony_ci VRegister vmtmp = v4.V16B(); 1937b8021494Sopenharmony_ci VRegister vres = v5.V16B(); 1938b8021494Sopenharmony_ci 1939b8021494Sopenharmony_ci // These will have the correct format for calling the 'helper'. 1940b8021494Sopenharmony_ci VRegister vn_helper = VRegister(1, vn_bits, vn_lane_count); 1941b8021494Sopenharmony_ci VRegister vm_helper = VRegister(2, vm_bits, vm_lane_count); 1942b8021494Sopenharmony_ci VRegister vres_helper = VRegister(5, vd_bits, vd_lane_count); 1943b8021494Sopenharmony_ci 1944b8021494Sopenharmony_ci // 'v*tmp_single' will be either 'Vt.B', 'Vt.H', 'Vt.S' or 'Vt.D'. 1945b8021494Sopenharmony_ci VRegister vntmp_single = VRegister(3, vn_lane_bits); 1946b8021494Sopenharmony_ci VRegister vmtmp_single = VRegister(4, vm_lane_bits); 1947b8021494Sopenharmony_ci 1948b8021494Sopenharmony_ci __ Mov(out, results); 1949b8021494Sopenharmony_ci 1950b8021494Sopenharmony_ci __ Mov(inputs_d_base, inputs_d); 1951b8021494Sopenharmony_ci 1952b8021494Sopenharmony_ci __ Mov(inputs_n_base, inputs_n); 1953b8021494Sopenharmony_ci __ Mov(inputs_n_last_16bytes, inputs_n + (inputs_n_length - 16)); 1954b8021494Sopenharmony_ci __ Mov(inputs_m_base, inputs_m); 1955b8021494Sopenharmony_ci __ Mov(inputs_m_last_16bytes, inputs_m + (inputs_m_length - 16)); 1956b8021494Sopenharmony_ci 1957b8021494Sopenharmony_ci __ Ldr(vd, MemOperand(inputs_d_base)); 1958b8021494Sopenharmony_ci __ Ldr(vn, MemOperand(inputs_n_last_16bytes)); 1959b8021494Sopenharmony_ci __ Ldr(vm, MemOperand(inputs_m_last_16bytes)); 1960b8021494Sopenharmony_ci 1961b8021494Sopenharmony_ci __ Mov(index_n, 0); 1962b8021494Sopenharmony_ci __ Bind(&loop_n); 1963b8021494Sopenharmony_ci 1964b8021494Sopenharmony_ci __ Ldr(vntmp_single, 1965b8021494Sopenharmony_ci MemOperand(inputs_n_base, index_n, LSL, vn_lane_bytes_log2)); 1966b8021494Sopenharmony_ci __ Ext(vn, vn, vntmp, vn_lane_bytes); 1967b8021494Sopenharmony_ci 1968b8021494Sopenharmony_ci __ Mov(index_m, 0); 1969b8021494Sopenharmony_ci __ Bind(&loop_m); 1970b8021494Sopenharmony_ci 1971b8021494Sopenharmony_ci __ Ldr(vmtmp_single, 1972b8021494Sopenharmony_ci MemOperand(inputs_m_base, index_m, LSL, vm_lane_bytes_log2)); 1973b8021494Sopenharmony_ci __ Ext(vm, vm, vmtmp, vm_lane_bytes); 1974b8021494Sopenharmony_ci 1975b8021494Sopenharmony_ci __ Mov(vres, vd); 1976b8021494Sopenharmony_ci { 1977b8021494Sopenharmony_ci SingleEmissionCheckScope guard(&masm); 1978b8021494Sopenharmony_ci (masm.*helper)(vres_helper, vn_helper, vm_helper); 1979b8021494Sopenharmony_ci } 1980b8021494Sopenharmony_ci __ Str(vres, MemOperand(out, vd.GetSizeInBytes(), PostIndex)); 1981b8021494Sopenharmony_ci 1982b8021494Sopenharmony_ci __ Add(index_m, index_m, 1); 1983b8021494Sopenharmony_ci __ Cmp(index_m, inputs_m_length); 1984b8021494Sopenharmony_ci __ B(lo, &loop_m); 1985b8021494Sopenharmony_ci 1986b8021494Sopenharmony_ci __ Add(index_n, index_n, 1); 1987b8021494Sopenharmony_ci __ Cmp(index_n, inputs_n_length); 1988b8021494Sopenharmony_ci __ B(lo, &loop_n); 1989b8021494Sopenharmony_ci 1990b8021494Sopenharmony_ci END(); 1991b8021494Sopenharmony_ci TRY_RUN(skipped); 1992b8021494Sopenharmony_ci} 1993b8021494Sopenharmony_ci 1994b8021494Sopenharmony_ci 1995b8021494Sopenharmony_ci// Test NEON instructions. The inputs_*[] and expected[] arrays should be 1996b8021494Sopenharmony_ci// arrays of rawbit representation of input values. This ensures that 1997b8021494Sopenharmony_ci// exact bit comparisons can be performed. 1998b8021494Sopenharmony_citemplate <typename Td, typename Tn, typename Tm> 1999b8021494Sopenharmony_cistatic void Test2OpNEON(const char* name, 2000b8021494Sopenharmony_ci Test2OpNEONHelper_t helper, 2001b8021494Sopenharmony_ci const Td inputs_d[], 2002b8021494Sopenharmony_ci const Tn inputs_n[], 2003b8021494Sopenharmony_ci unsigned inputs_n_length, 2004b8021494Sopenharmony_ci const Tm inputs_m[], 2005b8021494Sopenharmony_ci unsigned inputs_m_length, 2006b8021494Sopenharmony_ci const Td expected[], 2007b8021494Sopenharmony_ci unsigned expected_length, 2008b8021494Sopenharmony_ci VectorFormat vd_form, 2009b8021494Sopenharmony_ci VectorFormat vn_form, 2010b8021494Sopenharmony_ci VectorFormat vm_form) { 2011b8021494Sopenharmony_ci VIXL_ASSERT(inputs_n_length > 0 && inputs_m_length > 0); 2012b8021494Sopenharmony_ci 2013b8021494Sopenharmony_ci const unsigned vd_lane_count = MaxLaneCountFromFormat(vd_form); 2014b8021494Sopenharmony_ci 2015b8021494Sopenharmony_ci const unsigned results_length = inputs_n_length * inputs_m_length; 2016b8021494Sopenharmony_ci Td* results = new Td[results_length * vd_lane_count]; 2017b8021494Sopenharmony_ci const unsigned lane_bit = sizeof(Td) * 8; 2018b8021494Sopenharmony_ci const unsigned lane_len_in_hex = MaxHexCharCount<Td, Tm>(); 2019b8021494Sopenharmony_ci 2020b8021494Sopenharmony_ci bool skipped; 2021b8021494Sopenharmony_ci 2022b8021494Sopenharmony_ci Test2OpNEON_Helper(helper, 2023b8021494Sopenharmony_ci reinterpret_cast<uintptr_t>(inputs_d), 2024b8021494Sopenharmony_ci reinterpret_cast<uintptr_t>(inputs_n), 2025b8021494Sopenharmony_ci inputs_n_length, 2026b8021494Sopenharmony_ci reinterpret_cast<uintptr_t>(inputs_m), 2027b8021494Sopenharmony_ci inputs_m_length, 2028b8021494Sopenharmony_ci reinterpret_cast<uintptr_t>(results), 2029b8021494Sopenharmony_ci vd_form, 2030b8021494Sopenharmony_ci vn_form, 2031b8021494Sopenharmony_ci vm_form, 2032b8021494Sopenharmony_ci &skipped); 2033b8021494Sopenharmony_ci 2034b8021494Sopenharmony_ci if (Test::generate_test_trace()) { 2035b8021494Sopenharmony_ci // Print the results. 2036b8021494Sopenharmony_ci printf("const uint%u_t kExpected_NEON_%s[] = {\n", lane_bit, name); 2037b8021494Sopenharmony_ci for (unsigned iteration = 0; iteration < results_length; iteration++) { 2038b8021494Sopenharmony_ci printf(" "); 2039b8021494Sopenharmony_ci // Output a separate result for each element of the result vector. 2040b8021494Sopenharmony_ci for (unsigned lane = 0; lane < vd_lane_count; lane++) { 2041b8021494Sopenharmony_ci unsigned index = lane + (iteration * vd_lane_count); 2042b8021494Sopenharmony_ci printf(" 0x%0*" PRIx64 ",", 2043b8021494Sopenharmony_ci lane_len_in_hex, 2044b8021494Sopenharmony_ci static_cast<uint64_t>(results[index])); 2045b8021494Sopenharmony_ci } 2046b8021494Sopenharmony_ci printf("\n"); 2047b8021494Sopenharmony_ci } 2048b8021494Sopenharmony_ci 2049b8021494Sopenharmony_ci printf("};\n"); 2050b8021494Sopenharmony_ci printf("const unsigned kExpectedCount_NEON_%s = %u;\n", 2051b8021494Sopenharmony_ci name, 2052b8021494Sopenharmony_ci results_length); 2053b8021494Sopenharmony_ci } else if (!skipped) { 2054b8021494Sopenharmony_ci // Check the results. 2055b8021494Sopenharmony_ci VIXL_CHECK(expected_length == results_length); 2056b8021494Sopenharmony_ci unsigned error_count = 0; 2057b8021494Sopenharmony_ci unsigned d = 0; 2058b8021494Sopenharmony_ci const char* padding = " "; 2059b8021494Sopenharmony_ci VIXL_ASSERT(strlen(padding) >= (lane_len_in_hex + 1)); 2060b8021494Sopenharmony_ci for (unsigned n = 0; n < inputs_n_length; n++) { 2061b8021494Sopenharmony_ci for (unsigned m = 0; m < inputs_m_length; m++, d++) { 2062b8021494Sopenharmony_ci bool error_in_vector = false; 2063b8021494Sopenharmony_ci 2064b8021494Sopenharmony_ci for (unsigned lane = 0; lane < vd_lane_count; lane++) { 2065b8021494Sopenharmony_ci unsigned output_index = (n * inputs_m_length * vd_lane_count) + 2066b8021494Sopenharmony_ci (m * vd_lane_count) + lane; 2067b8021494Sopenharmony_ci 2068b8021494Sopenharmony_ci if (results[output_index] != expected[output_index]) { 2069b8021494Sopenharmony_ci error_in_vector = true; 2070b8021494Sopenharmony_ci break; 2071b8021494Sopenharmony_ci } 2072b8021494Sopenharmony_ci } 2073b8021494Sopenharmony_ci 2074b8021494Sopenharmony_ci if (error_in_vector && (++error_count <= kErrorReportLimit)) { 2075b8021494Sopenharmony_ci printf("%s\n", name); 2076b8021494Sopenharmony_ci printf(" Vd%.*s| Vn%.*s| Vm%.*s| Vd%.*s| Expected\n", 2077b8021494Sopenharmony_ci lane_len_in_hex + 1, 2078b8021494Sopenharmony_ci padding, 2079b8021494Sopenharmony_ci lane_len_in_hex + 1, 2080b8021494Sopenharmony_ci padding, 2081b8021494Sopenharmony_ci lane_len_in_hex + 1, 2082b8021494Sopenharmony_ci padding, 2083b8021494Sopenharmony_ci lane_len_in_hex + 1, 2084b8021494Sopenharmony_ci padding); 2085b8021494Sopenharmony_ci 2086b8021494Sopenharmony_ci for (unsigned lane = 0; lane < vd_lane_count; lane++) { 2087b8021494Sopenharmony_ci unsigned output_index = (n * inputs_m_length * vd_lane_count) + 2088b8021494Sopenharmony_ci (m * vd_lane_count) + lane; 2089b8021494Sopenharmony_ci unsigned input_index_n = 2090b8021494Sopenharmony_ci (inputs_n_length - vd_lane_count + n + 1 + lane) % 2091b8021494Sopenharmony_ci inputs_n_length; 2092b8021494Sopenharmony_ci unsigned input_index_m = 2093b8021494Sopenharmony_ci (inputs_m_length - vd_lane_count + m + 1 + lane) % 2094b8021494Sopenharmony_ci inputs_m_length; 2095b8021494Sopenharmony_ci 2096b8021494Sopenharmony_ci printf("%c0x%0*" PRIx64 " | 0x%0*" PRIx64 " | 0x%0*" PRIx64 2097b8021494Sopenharmony_ci " " 2098b8021494Sopenharmony_ci "| 0x%0*" PRIx64 " | 0x%0*" PRIx64 "\n", 2099b8021494Sopenharmony_ci results[output_index] != expected[output_index] ? '*' : ' ', 2100b8021494Sopenharmony_ci lane_len_in_hex, 2101b8021494Sopenharmony_ci static_cast<uint64_t>(inputs_d[lane]), 2102b8021494Sopenharmony_ci lane_len_in_hex, 2103b8021494Sopenharmony_ci static_cast<uint64_t>(inputs_n[input_index_n]), 2104b8021494Sopenharmony_ci lane_len_in_hex, 2105b8021494Sopenharmony_ci static_cast<uint64_t>(inputs_m[input_index_m]), 2106b8021494Sopenharmony_ci lane_len_in_hex, 2107b8021494Sopenharmony_ci static_cast<uint64_t>(results[output_index]), 2108b8021494Sopenharmony_ci lane_len_in_hex, 2109b8021494Sopenharmony_ci static_cast<uint64_t>(expected[output_index])); 2110b8021494Sopenharmony_ci } 2111b8021494Sopenharmony_ci } 2112b8021494Sopenharmony_ci } 2113b8021494Sopenharmony_ci } 2114b8021494Sopenharmony_ci VIXL_ASSERT(d == expected_length); 2115b8021494Sopenharmony_ci if (error_count > kErrorReportLimit) { 2116b8021494Sopenharmony_ci printf("%u other errors follow.\n", error_count - kErrorReportLimit); 2117b8021494Sopenharmony_ci } 2118b8021494Sopenharmony_ci VIXL_CHECK(error_count == 0); 2119b8021494Sopenharmony_ci } 2120b8021494Sopenharmony_ci delete[] results; 2121b8021494Sopenharmony_ci} 2122b8021494Sopenharmony_ci 2123b8021494Sopenharmony_ci 2124b8021494Sopenharmony_ci// ==== Tests for instructions of the form <INST> Vd, Vn, Vm[<#index>]. ==== 2125b8021494Sopenharmony_ci 2126b8021494Sopenharmony_cistatic void TestByElementNEON_Helper(TestByElementNEONHelper_t helper, 2127b8021494Sopenharmony_ci uintptr_t inputs_d, 2128b8021494Sopenharmony_ci uintptr_t inputs_n, 2129b8021494Sopenharmony_ci unsigned inputs_n_length, 2130b8021494Sopenharmony_ci uintptr_t inputs_m, 2131b8021494Sopenharmony_ci unsigned inputs_m_length, 2132b8021494Sopenharmony_ci const int indices[], 2133b8021494Sopenharmony_ci unsigned indices_length, 2134b8021494Sopenharmony_ci uintptr_t results, 2135b8021494Sopenharmony_ci VectorFormat vd_form, 2136b8021494Sopenharmony_ci VectorFormat vn_form, 2137b8021494Sopenharmony_ci VectorFormat vm_form, 2138b8021494Sopenharmony_ci unsigned vm_subvector_count, 2139b8021494Sopenharmony_ci bool* skipped) { 2140b8021494Sopenharmony_ci VIXL_ASSERT(vd_form != kFormatUndefined); 2141b8021494Sopenharmony_ci VIXL_ASSERT(vn_form != kFormatUndefined); 2142b8021494Sopenharmony_ci VIXL_ASSERT(vm_form != kFormatUndefined); 2143b8021494Sopenharmony_ci VIXL_ASSERT((vm_subvector_count != 0) && IsPowerOf2(vm_subvector_count)); 2144b8021494Sopenharmony_ci 2145b8021494Sopenharmony_ci CPUFeatures features; 2146b8021494Sopenharmony_ci features.Combine(CPUFeatures::kNEON, CPUFeatures::kNEONHalf); 2147b8021494Sopenharmony_ci features.Combine(CPUFeatures::kFP); 2148b8021494Sopenharmony_ci features.Combine(CPUFeatures::kRDM); 2149b8021494Sopenharmony_ci features.Combine(CPUFeatures::kDotProduct); 2150b8021494Sopenharmony_ci features.Combine(CPUFeatures::kFHM); 2151b8021494Sopenharmony_ci SETUP_WITH_FEATURES(features); 2152b8021494Sopenharmony_ci 2153b8021494Sopenharmony_ci START(); 2154b8021494Sopenharmony_ci 2155b8021494Sopenharmony_ci // Roll up the loop to keep the code size down. 2156b8021494Sopenharmony_ci Label loop_n, loop_m; 2157b8021494Sopenharmony_ci 2158b8021494Sopenharmony_ci Register out = x0; 2159b8021494Sopenharmony_ci Register inputs_n_base = x1; 2160b8021494Sopenharmony_ci Register inputs_m_base = x2; 2161b8021494Sopenharmony_ci Register inputs_d_base = x3; 2162b8021494Sopenharmony_ci Register inputs_n_last_16bytes = x4; 2163b8021494Sopenharmony_ci Register inputs_m_last_16bytes = x5; 2164b8021494Sopenharmony_ci Register index_n = x6; 2165b8021494Sopenharmony_ci Register index_m = x7; 2166b8021494Sopenharmony_ci 2167b8021494Sopenharmony_ci // TODO: Refactor duplicate definitions below with a VRegister::As() routine. 2168b8021494Sopenharmony_ci const unsigned vd_bits = RegisterSizeInBitsFromFormat(vd_form); 2169b8021494Sopenharmony_ci const unsigned vd_lane_count = LaneCountFromFormat(vd_form); 2170b8021494Sopenharmony_ci 2171b8021494Sopenharmony_ci const unsigned vn_bits = RegisterSizeInBitsFromFormat(vn_form); 2172b8021494Sopenharmony_ci const unsigned vn_lane_count = LaneCountFromFormat(vn_form); 2173b8021494Sopenharmony_ci const unsigned vn_lane_bytes = LaneSizeInBytesFromFormat(vn_form); 2174b8021494Sopenharmony_ci const unsigned vn_lane_bytes_log2 = LaneSizeInBytesLog2FromFormat(vn_form); 2175b8021494Sopenharmony_ci const unsigned vn_lane_bits = LaneSizeInBitsFromFormat(vn_form); 2176b8021494Sopenharmony_ci 2177b8021494Sopenharmony_ci const unsigned vm_bits = RegisterSizeInBitsFromFormat(vm_form); 2178b8021494Sopenharmony_ci const unsigned vm_lane_count = LaneCountFromFormat(vm_form); 2179b8021494Sopenharmony_ci const unsigned vm_lane_bytes = LaneSizeInBytesFromFormat(vm_form); 2180b8021494Sopenharmony_ci const unsigned vm_lane_bytes_log2 = LaneSizeInBytesLog2FromFormat(vm_form); 2181b8021494Sopenharmony_ci const unsigned vm_lane_bits = LaneSizeInBitsFromFormat(vm_form); 2182b8021494Sopenharmony_ci 2183b8021494Sopenharmony_ci VIXL_ASSERT((vm_bits * vm_subvector_count) <= kQRegSize); 2184b8021494Sopenharmony_ci 2185b8021494Sopenharmony_ci // Always load and store 128 bits regardless of the format. 2186b8021494Sopenharmony_ci VRegister vd = v0.V16B(); 2187b8021494Sopenharmony_ci VRegister vn = v1.V16B(); 2188b8021494Sopenharmony_ci VRegister vm = v2.V16B(); 2189b8021494Sopenharmony_ci VRegister vntmp = v3.V16B(); 2190b8021494Sopenharmony_ci VRegister vmtmp = v4.V16B(); 2191b8021494Sopenharmony_ci VRegister vres = v5.V16B(); 2192b8021494Sopenharmony_ci 2193b8021494Sopenharmony_ci // These will have the correct format for calling the 'helper'. 2194b8021494Sopenharmony_ci VRegister vn_helper = VRegister(1, vn_bits, vn_lane_count); 2195b8021494Sopenharmony_ci VRegister vm_helper = 2196b8021494Sopenharmony_ci VRegister(2, vm_bits * vm_subvector_count, vm_lane_count); 2197b8021494Sopenharmony_ci VRegister vres_helper = VRegister(5, vd_bits, vd_lane_count); 2198b8021494Sopenharmony_ci 2199b8021494Sopenharmony_ci // 'v*tmp_single' will be either 'Vt.B', 'Vt.H', 'Vt.S' or 'Vt.D'. 2200b8021494Sopenharmony_ci VRegister vntmp_single = VRegister(3, vn_lane_bits); 2201b8021494Sopenharmony_ci VRegister vmtmp_single = VRegister(4, vm_lane_bits); 2202b8021494Sopenharmony_ci 2203b8021494Sopenharmony_ci __ Mov(out, results); 2204b8021494Sopenharmony_ci 2205b8021494Sopenharmony_ci __ Mov(inputs_d_base, inputs_d); 2206b8021494Sopenharmony_ci 2207b8021494Sopenharmony_ci __ Mov(inputs_n_base, inputs_n); 2208b8021494Sopenharmony_ci __ Mov(inputs_n_last_16bytes, inputs_n + (inputs_n_length - 16)); 2209b8021494Sopenharmony_ci __ Mov(inputs_m_base, inputs_m); 2210b8021494Sopenharmony_ci __ Mov(inputs_m_last_16bytes, inputs_m + (inputs_m_length - 16)); 2211b8021494Sopenharmony_ci 2212b8021494Sopenharmony_ci __ Ldr(vd, MemOperand(inputs_d_base)); 2213b8021494Sopenharmony_ci __ Ldr(vn, MemOperand(inputs_n_last_16bytes)); 2214b8021494Sopenharmony_ci __ Ldr(vm, MemOperand(inputs_m_last_16bytes)); 2215b8021494Sopenharmony_ci 2216b8021494Sopenharmony_ci __ Mov(index_n, 0); 2217b8021494Sopenharmony_ci __ Bind(&loop_n); 2218b8021494Sopenharmony_ci 2219b8021494Sopenharmony_ci __ Ldr(vntmp_single, 2220b8021494Sopenharmony_ci MemOperand(inputs_n_base, index_n, LSL, vn_lane_bytes_log2)); 2221b8021494Sopenharmony_ci __ Ext(vn, vn, vntmp, vn_lane_bytes); 2222b8021494Sopenharmony_ci 2223b8021494Sopenharmony_ci __ Mov(index_m, 0); 2224b8021494Sopenharmony_ci __ Bind(&loop_m); 2225b8021494Sopenharmony_ci 2226b8021494Sopenharmony_ci __ Ldr(vmtmp_single, 2227b8021494Sopenharmony_ci MemOperand(inputs_m_base, index_m, LSL, vm_lane_bytes_log2)); 2228b8021494Sopenharmony_ci __ Ext(vm, vm, vmtmp, vm_lane_bytes); 2229b8021494Sopenharmony_ci 2230b8021494Sopenharmony_ci __ Mov(vres, vd); 2231b8021494Sopenharmony_ci { 2232b8021494Sopenharmony_ci for (unsigned i = 0; i < indices_length; i++) { 2233b8021494Sopenharmony_ci { 2234b8021494Sopenharmony_ci SingleEmissionCheckScope guard(&masm); 2235b8021494Sopenharmony_ci (masm.*helper)(vres_helper, vn_helper, vm_helper, indices[i]); 2236b8021494Sopenharmony_ci } 2237b8021494Sopenharmony_ci __ Str(vres, MemOperand(out, vd.GetSizeInBytes(), PostIndex)); 2238b8021494Sopenharmony_ci } 2239b8021494Sopenharmony_ci } 2240b8021494Sopenharmony_ci 2241b8021494Sopenharmony_ci __ Add(index_m, index_m, 1); 2242b8021494Sopenharmony_ci __ Cmp(index_m, inputs_m_length); 2243b8021494Sopenharmony_ci __ B(lo, &loop_m); 2244b8021494Sopenharmony_ci 2245b8021494Sopenharmony_ci __ Add(index_n, index_n, 1); 2246b8021494Sopenharmony_ci __ Cmp(index_n, inputs_n_length); 2247b8021494Sopenharmony_ci __ B(lo, &loop_n); 2248b8021494Sopenharmony_ci 2249b8021494Sopenharmony_ci END(); 2250b8021494Sopenharmony_ci TRY_RUN(skipped); 2251b8021494Sopenharmony_ci} 2252b8021494Sopenharmony_ci 2253b8021494Sopenharmony_ci 2254b8021494Sopenharmony_ci// Test NEON instructions. The inputs_*[] and expected[] arrays should be 2255b8021494Sopenharmony_ci// arrays of rawbit representation of input values. This ensures that 2256b8021494Sopenharmony_ci// exact bit comparisons can be performed. 2257b8021494Sopenharmony_citemplate <typename Td, typename Tn, typename Tm> 2258b8021494Sopenharmony_cistatic void TestByElementNEON(const char* name, 2259b8021494Sopenharmony_ci TestByElementNEONHelper_t helper, 2260b8021494Sopenharmony_ci const Td inputs_d[], 2261b8021494Sopenharmony_ci const Tn inputs_n[], 2262b8021494Sopenharmony_ci unsigned inputs_n_length, 2263b8021494Sopenharmony_ci const Tm inputs_m[], 2264b8021494Sopenharmony_ci unsigned inputs_m_length, 2265b8021494Sopenharmony_ci const int indices[], 2266b8021494Sopenharmony_ci unsigned indices_length, 2267b8021494Sopenharmony_ci const Td expected[], 2268b8021494Sopenharmony_ci unsigned expected_length, 2269b8021494Sopenharmony_ci VectorFormat vd_form, 2270b8021494Sopenharmony_ci VectorFormat vn_form, 2271b8021494Sopenharmony_ci VectorFormat vm_form, 2272b8021494Sopenharmony_ci unsigned vm_subvector_count = 1) { 2273b8021494Sopenharmony_ci VIXL_ASSERT(inputs_n_length > 0); 2274b8021494Sopenharmony_ci VIXL_ASSERT(inputs_m_length > 0); 2275b8021494Sopenharmony_ci VIXL_ASSERT(indices_length > 0); 2276b8021494Sopenharmony_ci 2277b8021494Sopenharmony_ci const unsigned vd_lane_count = MaxLaneCountFromFormat(vd_form); 2278b8021494Sopenharmony_ci 2279b8021494Sopenharmony_ci const unsigned results_length = 2280b8021494Sopenharmony_ci inputs_n_length * inputs_m_length * indices_length; 2281b8021494Sopenharmony_ci Td* results = new Td[results_length * vd_lane_count]; 2282b8021494Sopenharmony_ci const unsigned lane_bit = sizeof(Td) * 8; 2283b8021494Sopenharmony_ci const unsigned lane_len_in_hex = MaxHexCharCount<Td, Tm>(); 2284b8021494Sopenharmony_ci 2285b8021494Sopenharmony_ci bool skipped; 2286b8021494Sopenharmony_ci 2287b8021494Sopenharmony_ci TestByElementNEON_Helper(helper, 2288b8021494Sopenharmony_ci reinterpret_cast<uintptr_t>(inputs_d), 2289b8021494Sopenharmony_ci reinterpret_cast<uintptr_t>(inputs_n), 2290b8021494Sopenharmony_ci inputs_n_length, 2291b8021494Sopenharmony_ci reinterpret_cast<uintptr_t>(inputs_m), 2292b8021494Sopenharmony_ci inputs_m_length, 2293b8021494Sopenharmony_ci indices, 2294b8021494Sopenharmony_ci indices_length, 2295b8021494Sopenharmony_ci reinterpret_cast<uintptr_t>(results), 2296b8021494Sopenharmony_ci vd_form, 2297b8021494Sopenharmony_ci vn_form, 2298b8021494Sopenharmony_ci vm_form, 2299b8021494Sopenharmony_ci vm_subvector_count, 2300b8021494Sopenharmony_ci &skipped); 2301b8021494Sopenharmony_ci 2302b8021494Sopenharmony_ci if (Test::generate_test_trace()) { 2303b8021494Sopenharmony_ci // Print the results. 2304b8021494Sopenharmony_ci printf("const uint%u_t kExpected_NEON_%s[] = {\n", lane_bit, name); 2305b8021494Sopenharmony_ci for (unsigned iteration = 0; iteration < results_length; iteration++) { 2306b8021494Sopenharmony_ci printf(" "); 2307b8021494Sopenharmony_ci // Output a separate result for each element of the result vector. 2308b8021494Sopenharmony_ci for (unsigned lane = 0; lane < vd_lane_count; lane++) { 2309b8021494Sopenharmony_ci unsigned index = lane + (iteration * vd_lane_count); 2310b8021494Sopenharmony_ci printf(" 0x%0*" PRIx64 ",", 2311b8021494Sopenharmony_ci lane_len_in_hex, 2312b8021494Sopenharmony_ci static_cast<uint64_t>(results[index])); 2313b8021494Sopenharmony_ci } 2314b8021494Sopenharmony_ci printf("\n"); 2315b8021494Sopenharmony_ci } 2316b8021494Sopenharmony_ci 2317b8021494Sopenharmony_ci printf("};\n"); 2318b8021494Sopenharmony_ci printf("const unsigned kExpectedCount_NEON_%s = %u;\n", 2319b8021494Sopenharmony_ci name, 2320b8021494Sopenharmony_ci results_length); 2321b8021494Sopenharmony_ci } else if (!skipped) { 2322b8021494Sopenharmony_ci // Check the results. 2323b8021494Sopenharmony_ci VIXL_CHECK(expected_length == results_length); 2324b8021494Sopenharmony_ci unsigned error_count = 0; 2325b8021494Sopenharmony_ci unsigned d = 0; 2326b8021494Sopenharmony_ci const char* padding = " "; 2327b8021494Sopenharmony_ci VIXL_ASSERT(strlen(padding) >= (lane_len_in_hex + 1)); 2328b8021494Sopenharmony_ci for (unsigned n = 0; n < inputs_n_length; n++) { 2329b8021494Sopenharmony_ci for (unsigned m = 0; m < inputs_m_length; m++) { 2330b8021494Sopenharmony_ci for (unsigned index = 0; index < indices_length; index++, d++) { 2331b8021494Sopenharmony_ci bool error_in_vector = false; 2332b8021494Sopenharmony_ci 2333b8021494Sopenharmony_ci for (unsigned lane = 0; lane < vd_lane_count; lane++) { 2334b8021494Sopenharmony_ci unsigned output_index = 2335b8021494Sopenharmony_ci (n * inputs_m_length * indices_length * vd_lane_count) + 2336b8021494Sopenharmony_ci (m * indices_length * vd_lane_count) + (index * vd_lane_count) + 2337b8021494Sopenharmony_ci lane; 2338b8021494Sopenharmony_ci 2339b8021494Sopenharmony_ci if (results[output_index] != expected[output_index]) { 2340b8021494Sopenharmony_ci error_in_vector = true; 2341b8021494Sopenharmony_ci break; 2342b8021494Sopenharmony_ci } 2343b8021494Sopenharmony_ci } 2344b8021494Sopenharmony_ci 2345b8021494Sopenharmony_ci if (error_in_vector && (++error_count <= kErrorReportLimit)) { 2346b8021494Sopenharmony_ci printf("%s\n", name); 2347b8021494Sopenharmony_ci printf(" Vd%.*s| Vn%.*s| Vm%.*s| Index | Vd%.*s| Expected\n", 2348b8021494Sopenharmony_ci lane_len_in_hex + 1, 2349b8021494Sopenharmony_ci padding, 2350b8021494Sopenharmony_ci lane_len_in_hex + 1, 2351b8021494Sopenharmony_ci padding, 2352b8021494Sopenharmony_ci lane_len_in_hex + 1, 2353b8021494Sopenharmony_ci padding, 2354b8021494Sopenharmony_ci lane_len_in_hex + 1, 2355b8021494Sopenharmony_ci padding); 2356b8021494Sopenharmony_ci 2357b8021494Sopenharmony_ci for (unsigned lane = 0; lane < vd_lane_count; lane++) { 2358b8021494Sopenharmony_ci unsigned output_index = 2359b8021494Sopenharmony_ci (n * inputs_m_length * indices_length * vd_lane_count) + 2360b8021494Sopenharmony_ci (m * indices_length * vd_lane_count) + 2361b8021494Sopenharmony_ci (index * vd_lane_count) + lane; 2362b8021494Sopenharmony_ci unsigned input_index_n = 2363b8021494Sopenharmony_ci (inputs_n_length - vd_lane_count + n + 1 + lane) % 2364b8021494Sopenharmony_ci inputs_n_length; 2365b8021494Sopenharmony_ci unsigned input_index_m = 2366b8021494Sopenharmony_ci (inputs_m_length - vd_lane_count + m + 1 + lane) % 2367b8021494Sopenharmony_ci inputs_m_length; 2368b8021494Sopenharmony_ci 2369b8021494Sopenharmony_ci printf("%c0x%0*" PRIx64 " | 0x%0*" PRIx64 " | 0x%0*" PRIx64 2370b8021494Sopenharmony_ci " " 2371b8021494Sopenharmony_ci "| [%3d] | 0x%0*" PRIx64 " | 0x%0*" PRIx64 "\n", 2372b8021494Sopenharmony_ci results[output_index] != expected[output_index] ? '*' 2373b8021494Sopenharmony_ci : ' ', 2374b8021494Sopenharmony_ci lane_len_in_hex, 2375b8021494Sopenharmony_ci static_cast<uint64_t>(inputs_d[lane]), 2376b8021494Sopenharmony_ci lane_len_in_hex, 2377b8021494Sopenharmony_ci static_cast<uint64_t>(inputs_n[input_index_n]), 2378b8021494Sopenharmony_ci lane_len_in_hex, 2379b8021494Sopenharmony_ci static_cast<uint64_t>(inputs_m[input_index_m]), 2380b8021494Sopenharmony_ci indices[index], 2381b8021494Sopenharmony_ci lane_len_in_hex, 2382b8021494Sopenharmony_ci static_cast<uint64_t>(results[output_index]), 2383b8021494Sopenharmony_ci lane_len_in_hex, 2384b8021494Sopenharmony_ci static_cast<uint64_t>(expected[output_index])); 2385b8021494Sopenharmony_ci } 2386b8021494Sopenharmony_ci } 2387b8021494Sopenharmony_ci } 2388b8021494Sopenharmony_ci } 2389b8021494Sopenharmony_ci } 2390b8021494Sopenharmony_ci VIXL_ASSERT(d == expected_length); 2391b8021494Sopenharmony_ci if (error_count > kErrorReportLimit) { 2392b8021494Sopenharmony_ci printf("%u other errors follow.\n", error_count - kErrorReportLimit); 2393b8021494Sopenharmony_ci } 2394b8021494Sopenharmony_ci VIXL_CHECK(error_count == 0); 2395b8021494Sopenharmony_ci } 2396b8021494Sopenharmony_ci delete[] results; 2397b8021494Sopenharmony_ci} 2398b8021494Sopenharmony_ci 2399b8021494Sopenharmony_ci 2400b8021494Sopenharmony_ci// ==== Tests for instructions of the form <INST> VReg, VReg, #Immediate. ==== 2401b8021494Sopenharmony_ci 2402b8021494Sopenharmony_ci 2403b8021494Sopenharmony_citemplate <typename Tm> 2404b8021494Sopenharmony_civoid Test2OpImmNEON_Helper( 2405b8021494Sopenharmony_ci typename Test2OpImmediateNEONHelper_t<Tm>::mnemonic helper, 2406b8021494Sopenharmony_ci uintptr_t inputs_n, 2407b8021494Sopenharmony_ci unsigned inputs_n_length, 2408b8021494Sopenharmony_ci const Tm inputs_m[], 2409b8021494Sopenharmony_ci unsigned inputs_m_length, 2410b8021494Sopenharmony_ci uintptr_t results, 2411b8021494Sopenharmony_ci VectorFormat vd_form, 2412b8021494Sopenharmony_ci VectorFormat vn_form, 2413b8021494Sopenharmony_ci bool* skipped) { 2414b8021494Sopenharmony_ci VIXL_ASSERT(vd_form != kFormatUndefined && vn_form != kFormatUndefined); 2415b8021494Sopenharmony_ci 2416b8021494Sopenharmony_ci SETUP_WITH_FEATURES(CPUFeatures::kNEON, 2417b8021494Sopenharmony_ci CPUFeatures::kFP, 2418b8021494Sopenharmony_ci CPUFeatures::kNEONHalf); 2419b8021494Sopenharmony_ci START(); 2420b8021494Sopenharmony_ci 2421b8021494Sopenharmony_ci // Roll up the loop to keep the code size down. 2422b8021494Sopenharmony_ci Label loop_n; 2423b8021494Sopenharmony_ci 2424b8021494Sopenharmony_ci Register out = x0; 2425b8021494Sopenharmony_ci Register inputs_n_base = x1; 2426b8021494Sopenharmony_ci Register inputs_n_last_16bytes = x3; 2427b8021494Sopenharmony_ci Register index_n = x5; 2428b8021494Sopenharmony_ci 2429b8021494Sopenharmony_ci // TODO: Refactor duplicate definitions below with a VRegister::As() routine. 2430b8021494Sopenharmony_ci const unsigned vd_bits = RegisterSizeInBitsFromFormat(vd_form); 2431b8021494Sopenharmony_ci const unsigned vd_lane_count = LaneCountFromFormat(vd_form); 2432b8021494Sopenharmony_ci 2433b8021494Sopenharmony_ci const unsigned vn_bits = RegisterSizeInBitsFromFormat(vn_form); 2434b8021494Sopenharmony_ci const unsigned vn_lane_count = LaneCountFromFormat(vn_form); 2435b8021494Sopenharmony_ci const unsigned vn_lane_bytes = LaneSizeInBytesFromFormat(vn_form); 2436b8021494Sopenharmony_ci const unsigned vn_lane_bytes_log2 = LaneSizeInBytesLog2FromFormat(vn_form); 2437b8021494Sopenharmony_ci const unsigned vn_lane_bits = LaneSizeInBitsFromFormat(vn_form); 2438b8021494Sopenharmony_ci 2439b8021494Sopenharmony_ci 2440b8021494Sopenharmony_ci // These will be either a D- or a Q-register form, with a single lane 2441b8021494Sopenharmony_ci // (for use in scalar load and store operations). 2442b8021494Sopenharmony_ci VRegister vd = VRegister(0, vd_bits); 2443b8021494Sopenharmony_ci VRegister vn = v1.V16B(); 2444b8021494Sopenharmony_ci VRegister vntmp = v3.V16B(); 2445b8021494Sopenharmony_ci 2446b8021494Sopenharmony_ci // These will have the correct format for use when calling 'helper'. 2447b8021494Sopenharmony_ci VRegister vd_helper = VRegister(0, vd_bits, vd_lane_count); 2448b8021494Sopenharmony_ci VRegister vn_helper = VRegister(1, vn_bits, vn_lane_count); 2449b8021494Sopenharmony_ci 2450b8021494Sopenharmony_ci // 'v*tmp_single' will be either 'Vt.B', 'Vt.H', 'Vt.S' or 'Vt.D'. 2451b8021494Sopenharmony_ci VRegister vntmp_single = VRegister(3, vn_lane_bits); 2452b8021494Sopenharmony_ci 2453b8021494Sopenharmony_ci __ Mov(out, results); 2454b8021494Sopenharmony_ci 2455b8021494Sopenharmony_ci __ Mov(inputs_n_base, inputs_n); 2456b8021494Sopenharmony_ci __ Mov(inputs_n_last_16bytes, 2457b8021494Sopenharmony_ci inputs_n + (vn_lane_bytes * inputs_n_length) - 16); 2458b8021494Sopenharmony_ci 2459b8021494Sopenharmony_ci __ Ldr(vn, MemOperand(inputs_n_last_16bytes)); 2460b8021494Sopenharmony_ci 2461b8021494Sopenharmony_ci __ Mov(index_n, 0); 2462b8021494Sopenharmony_ci __ Bind(&loop_n); 2463b8021494Sopenharmony_ci 2464b8021494Sopenharmony_ci __ Ldr(vntmp_single, 2465b8021494Sopenharmony_ci MemOperand(inputs_n_base, index_n, LSL, vn_lane_bytes_log2)); 2466b8021494Sopenharmony_ci __ Ext(vn, vn, vntmp, vn_lane_bytes); 2467b8021494Sopenharmony_ci 2468b8021494Sopenharmony_ci // Set the destination to zero for tests such as '[r]shrn2'. 2469b8021494Sopenharmony_ci // TODO: Setting the destination to values other than zero might be a better 2470b8021494Sopenharmony_ci // test for shift and accumulate instructions (srsra/ssra/usra/ursra). 2471b8021494Sopenharmony_ci __ Movi(vd.V16B(), 0); 2472b8021494Sopenharmony_ci 2473b8021494Sopenharmony_ci { 2474b8021494Sopenharmony_ci for (unsigned i = 0; i < inputs_m_length; i++) { 2475b8021494Sopenharmony_ci { 2476b8021494Sopenharmony_ci SingleEmissionCheckScope guard(&masm); 2477b8021494Sopenharmony_ci (masm.*helper)(vd_helper, vn_helper, inputs_m[i]); 2478b8021494Sopenharmony_ci } 2479b8021494Sopenharmony_ci __ Str(vd, MemOperand(out, vd.GetSizeInBytes(), PostIndex)); 2480b8021494Sopenharmony_ci } 2481b8021494Sopenharmony_ci } 2482b8021494Sopenharmony_ci 2483b8021494Sopenharmony_ci __ Add(index_n, index_n, 1); 2484b8021494Sopenharmony_ci __ Cmp(index_n, inputs_n_length); 2485b8021494Sopenharmony_ci __ B(lo, &loop_n); 2486b8021494Sopenharmony_ci 2487b8021494Sopenharmony_ci END(); 2488b8021494Sopenharmony_ci TRY_RUN(skipped); 2489b8021494Sopenharmony_ci} 2490b8021494Sopenharmony_ci 2491b8021494Sopenharmony_ci 2492b8021494Sopenharmony_ci// Test NEON instructions. The inputs_*[] and expected[] arrays should be 2493b8021494Sopenharmony_ci// arrays of rawbit representation of input values. This ensures that 2494b8021494Sopenharmony_ci// exact bit comparisons can be performed. 2495b8021494Sopenharmony_citemplate <typename Td, typename Tn, typename Tm> 2496b8021494Sopenharmony_cistatic void Test2OpImmNEON( 2497b8021494Sopenharmony_ci const char* name, 2498b8021494Sopenharmony_ci typename Test2OpImmediateNEONHelper_t<Tm>::mnemonic helper, 2499b8021494Sopenharmony_ci const Tn inputs_n[], 2500b8021494Sopenharmony_ci unsigned inputs_n_length, 2501b8021494Sopenharmony_ci const Tm inputs_m[], 2502b8021494Sopenharmony_ci unsigned inputs_m_length, 2503b8021494Sopenharmony_ci const Td expected[], 2504b8021494Sopenharmony_ci unsigned expected_length, 2505b8021494Sopenharmony_ci VectorFormat vd_form, 2506b8021494Sopenharmony_ci VectorFormat vn_form) { 2507b8021494Sopenharmony_ci VIXL_ASSERT(inputs_n_length > 0 && inputs_m_length > 0); 2508b8021494Sopenharmony_ci 2509b8021494Sopenharmony_ci const unsigned vd_lane_count = LaneCountFromFormat(vd_form); 2510b8021494Sopenharmony_ci const unsigned vn_lane_bytes = LaneSizeInBytesFromFormat(vn_form); 2511b8021494Sopenharmony_ci const unsigned vn_lane_count = LaneCountFromFormat(vn_form); 2512b8021494Sopenharmony_ci 2513b8021494Sopenharmony_ci const unsigned results_length = inputs_n_length * inputs_m_length; 2514b8021494Sopenharmony_ci Td* results = new Td[results_length * vd_lane_count]; 2515b8021494Sopenharmony_ci const unsigned lane_bit = sizeof(Td) * 8; 2516b8021494Sopenharmony_ci const unsigned lane_len_in_hex = MaxHexCharCount<Td, Tn>(); 2517b8021494Sopenharmony_ci 2518b8021494Sopenharmony_ci bool skipped; 2519b8021494Sopenharmony_ci 2520b8021494Sopenharmony_ci Test2OpImmNEON_Helper(helper, 2521b8021494Sopenharmony_ci reinterpret_cast<uintptr_t>(inputs_n), 2522b8021494Sopenharmony_ci inputs_n_length, 2523b8021494Sopenharmony_ci inputs_m, 2524b8021494Sopenharmony_ci inputs_m_length, 2525b8021494Sopenharmony_ci reinterpret_cast<uintptr_t>(results), 2526b8021494Sopenharmony_ci vd_form, 2527b8021494Sopenharmony_ci vn_form, 2528b8021494Sopenharmony_ci &skipped); 2529b8021494Sopenharmony_ci 2530b8021494Sopenharmony_ci if (Test::generate_test_trace()) { 2531b8021494Sopenharmony_ci // Print the results. 2532b8021494Sopenharmony_ci printf("const uint%u_t kExpected_NEON_%s[] = {\n", lane_bit, name); 2533b8021494Sopenharmony_ci for (unsigned iteration = 0; iteration < results_length; iteration++) { 2534b8021494Sopenharmony_ci printf(" "); 2535b8021494Sopenharmony_ci // Output a separate result for each element of the result vector. 2536b8021494Sopenharmony_ci for (unsigned lane = 0; lane < vd_lane_count; lane++) { 2537b8021494Sopenharmony_ci unsigned index = lane + (iteration * vd_lane_count); 2538b8021494Sopenharmony_ci printf(" 0x%0*" PRIx64 ",", 2539b8021494Sopenharmony_ci lane_len_in_hex, 2540b8021494Sopenharmony_ci static_cast<uint64_t>(results[index])); 2541b8021494Sopenharmony_ci } 2542b8021494Sopenharmony_ci printf("\n"); 2543b8021494Sopenharmony_ci } 2544b8021494Sopenharmony_ci 2545b8021494Sopenharmony_ci printf("};\n"); 2546b8021494Sopenharmony_ci printf("const unsigned kExpectedCount_NEON_%s = %u;\n", 2547b8021494Sopenharmony_ci name, 2548b8021494Sopenharmony_ci results_length); 2549b8021494Sopenharmony_ci } else if (!skipped) { 2550b8021494Sopenharmony_ci // Check the results. 2551b8021494Sopenharmony_ci VIXL_CHECK(expected_length == results_length); 2552b8021494Sopenharmony_ci unsigned error_count = 0; 2553b8021494Sopenharmony_ci unsigned d = 0; 2554b8021494Sopenharmony_ci const char* padding = " "; 2555b8021494Sopenharmony_ci VIXL_ASSERT(strlen(padding) >= (lane_len_in_hex + 1)); 2556b8021494Sopenharmony_ci for (unsigned n = 0; n < inputs_n_length; n++) { 2557b8021494Sopenharmony_ci for (unsigned m = 0; m < inputs_m_length; m++, d++) { 2558b8021494Sopenharmony_ci bool error_in_vector = false; 2559b8021494Sopenharmony_ci 2560b8021494Sopenharmony_ci for (unsigned lane = 0; lane < vd_lane_count; lane++) { 2561b8021494Sopenharmony_ci unsigned output_index = (n * inputs_m_length * vd_lane_count) + 2562b8021494Sopenharmony_ci (m * vd_lane_count) + lane; 2563b8021494Sopenharmony_ci 2564b8021494Sopenharmony_ci if (results[output_index] != expected[output_index]) { 2565b8021494Sopenharmony_ci error_in_vector = true; 2566b8021494Sopenharmony_ci break; 2567b8021494Sopenharmony_ci } 2568b8021494Sopenharmony_ci } 2569b8021494Sopenharmony_ci 2570b8021494Sopenharmony_ci if (error_in_vector && (++error_count <= kErrorReportLimit)) { 2571b8021494Sopenharmony_ci printf("%s\n", name); 2572b8021494Sopenharmony_ci printf(" Vn%.*s| Imm%.*s| Vd%.*s| Expected\n", 2573b8021494Sopenharmony_ci lane_len_in_hex + 1, 2574b8021494Sopenharmony_ci padding, 2575b8021494Sopenharmony_ci lane_len_in_hex, 2576b8021494Sopenharmony_ci padding, 2577b8021494Sopenharmony_ci lane_len_in_hex + 1, 2578b8021494Sopenharmony_ci padding); 2579b8021494Sopenharmony_ci 2580b8021494Sopenharmony_ci const unsigned first_index_n = 2581b8021494Sopenharmony_ci inputs_n_length - (16 / vn_lane_bytes) + n + 1; 2582b8021494Sopenharmony_ci 2583b8021494Sopenharmony_ci for (unsigned lane = 0; lane < std::max(vd_lane_count, vn_lane_count); 2584b8021494Sopenharmony_ci lane++) { 2585b8021494Sopenharmony_ci unsigned output_index = (n * inputs_m_length * vd_lane_count) + 2586b8021494Sopenharmony_ci (m * vd_lane_count) + lane; 2587b8021494Sopenharmony_ci unsigned input_index_n = (first_index_n + lane) % inputs_n_length; 2588b8021494Sopenharmony_ci unsigned input_index_m = m; 2589b8021494Sopenharmony_ci 2590b8021494Sopenharmony_ci printf("%c0x%0*" PRIx64 " | 0x%0*" PRIx64 2591b8021494Sopenharmony_ci " " 2592b8021494Sopenharmony_ci "| 0x%0*" PRIx64 " | 0x%0*" PRIx64 "\n", 2593b8021494Sopenharmony_ci results[output_index] != expected[output_index] ? '*' : ' ', 2594b8021494Sopenharmony_ci lane_len_in_hex, 2595b8021494Sopenharmony_ci static_cast<uint64_t>(inputs_n[input_index_n]), 2596b8021494Sopenharmony_ci lane_len_in_hex, 2597b8021494Sopenharmony_ci static_cast<uint64_t>(inputs_m[input_index_m]), 2598b8021494Sopenharmony_ci lane_len_in_hex, 2599b8021494Sopenharmony_ci static_cast<uint64_t>(results[output_index]), 2600b8021494Sopenharmony_ci lane_len_in_hex, 2601b8021494Sopenharmony_ci static_cast<uint64_t>(expected[output_index])); 2602b8021494Sopenharmony_ci } 2603b8021494Sopenharmony_ci } 2604b8021494Sopenharmony_ci } 2605b8021494Sopenharmony_ci } 2606b8021494Sopenharmony_ci VIXL_ASSERT(d == expected_length); 2607b8021494Sopenharmony_ci if (error_count > kErrorReportLimit) { 2608b8021494Sopenharmony_ci printf("%u other errors follow.\n", error_count - kErrorReportLimit); 2609b8021494Sopenharmony_ci } 2610b8021494Sopenharmony_ci VIXL_CHECK(error_count == 0); 2611b8021494Sopenharmony_ci } 2612b8021494Sopenharmony_ci delete[] results; 2613b8021494Sopenharmony_ci} 2614b8021494Sopenharmony_ci 2615b8021494Sopenharmony_ci 2616b8021494Sopenharmony_ci// ==== Tests for instructions of the form <INST> VReg, #Imm, VReg, #Imm. ==== 2617b8021494Sopenharmony_ci 2618b8021494Sopenharmony_ci 2619b8021494Sopenharmony_cistatic void TestOpImmOpImmNEON_Helper(TestOpImmOpImmVdUpdateNEONHelper_t helper, 2620b8021494Sopenharmony_ci uintptr_t inputs_d, 2621b8021494Sopenharmony_ci const int inputs_imm1[], 2622b8021494Sopenharmony_ci unsigned inputs_imm1_length, 2623b8021494Sopenharmony_ci uintptr_t inputs_n, 2624b8021494Sopenharmony_ci unsigned inputs_n_length, 2625b8021494Sopenharmony_ci const int inputs_imm2[], 2626b8021494Sopenharmony_ci unsigned inputs_imm2_length, 2627b8021494Sopenharmony_ci uintptr_t results, 2628b8021494Sopenharmony_ci VectorFormat vd_form, 2629b8021494Sopenharmony_ci VectorFormat vn_form, 2630b8021494Sopenharmony_ci bool* skipped) { 2631b8021494Sopenharmony_ci VIXL_ASSERT(vd_form != kFormatUndefined); 2632b8021494Sopenharmony_ci VIXL_ASSERT(vn_form != kFormatUndefined); 2633b8021494Sopenharmony_ci 2634b8021494Sopenharmony_ci SETUP_WITH_FEATURES(CPUFeatures::kNEON, CPUFeatures::kFP); 2635b8021494Sopenharmony_ci START(); 2636b8021494Sopenharmony_ci 2637b8021494Sopenharmony_ci // Roll up the loop to keep the code size down. 2638b8021494Sopenharmony_ci Label loop_n; 2639b8021494Sopenharmony_ci 2640b8021494Sopenharmony_ci Register out = x0; 2641b8021494Sopenharmony_ci Register inputs_d_base = x1; 2642b8021494Sopenharmony_ci Register inputs_n_base = x2; 2643b8021494Sopenharmony_ci Register inputs_n_last_vector = x4; 2644b8021494Sopenharmony_ci Register index_n = x6; 2645b8021494Sopenharmony_ci 2646b8021494Sopenharmony_ci // TODO: Refactor duplicate definitions below with a VRegister::As() routine. 2647b8021494Sopenharmony_ci const unsigned vd_bits = RegisterSizeInBitsFromFormat(vd_form); 2648b8021494Sopenharmony_ci const unsigned vd_lane_count = LaneCountFromFormat(vd_form); 2649b8021494Sopenharmony_ci 2650b8021494Sopenharmony_ci const unsigned vn_bits = RegisterSizeInBitsFromFormat(vn_form); 2651b8021494Sopenharmony_ci const unsigned vn_lane_count = LaneCountFromFormat(vn_form); 2652b8021494Sopenharmony_ci const unsigned vn_lane_bytes = LaneSizeInBytesFromFormat(vn_form); 2653b8021494Sopenharmony_ci const unsigned vn_lane_bytes_log2 = LaneSizeInBytesLog2FromFormat(vn_form); 2654b8021494Sopenharmony_ci const unsigned vn_lane_bits = LaneSizeInBitsFromFormat(vn_form); 2655b8021494Sopenharmony_ci 2656b8021494Sopenharmony_ci 2657b8021494Sopenharmony_ci // These will be either a D- or a Q-register form, with a single lane 2658b8021494Sopenharmony_ci // (for use in scalar load and store operations). 2659b8021494Sopenharmony_ci VRegister vd = VRegister(0, vd_bits); 2660b8021494Sopenharmony_ci VRegister vn = VRegister(1, vn_bits); 2661b8021494Sopenharmony_ci VRegister vntmp = VRegister(4, vn_bits); 2662b8021494Sopenharmony_ci VRegister vres = VRegister(5, vn_bits); 2663b8021494Sopenharmony_ci 2664b8021494Sopenharmony_ci VRegister vn_helper = VRegister(1, vn_bits, vn_lane_count); 2665b8021494Sopenharmony_ci VRegister vres_helper = VRegister(5, vd_bits, vd_lane_count); 2666b8021494Sopenharmony_ci 2667b8021494Sopenharmony_ci // 'v*tmp_single' will be either 'Vt.B', 'Vt.H', 'Vt.S' or 'Vt.D'. 2668b8021494Sopenharmony_ci VRegister vntmp_single = VRegister(4, vn_lane_bits); 2669b8021494Sopenharmony_ci 2670b8021494Sopenharmony_ci // Same registers for use in the 'ext' instructions. 2671b8021494Sopenharmony_ci VRegister vn_ext = (kDRegSize == vn_bits) ? vn.V8B() : vn.V16B(); 2672b8021494Sopenharmony_ci VRegister vntmp_ext = (kDRegSize == vn_bits) ? vntmp.V8B() : vntmp.V16B(); 2673b8021494Sopenharmony_ci 2674b8021494Sopenharmony_ci __ Mov(out, results); 2675b8021494Sopenharmony_ci 2676b8021494Sopenharmony_ci __ Mov(inputs_d_base, inputs_d); 2677b8021494Sopenharmony_ci 2678b8021494Sopenharmony_ci __ Mov(inputs_n_base, inputs_n); 2679b8021494Sopenharmony_ci __ Mov(inputs_n_last_vector, 2680b8021494Sopenharmony_ci inputs_n + vn_lane_bytes * (inputs_n_length - vn_lane_count)); 2681b8021494Sopenharmony_ci 2682b8021494Sopenharmony_ci __ Ldr(vd, MemOperand(inputs_d_base)); 2683b8021494Sopenharmony_ci 2684b8021494Sopenharmony_ci __ Ldr(vn, MemOperand(inputs_n_last_vector)); 2685b8021494Sopenharmony_ci 2686b8021494Sopenharmony_ci __ Mov(index_n, 0); 2687b8021494Sopenharmony_ci __ Bind(&loop_n); 2688b8021494Sopenharmony_ci 2689b8021494Sopenharmony_ci __ Ldr(vntmp_single, 2690b8021494Sopenharmony_ci MemOperand(inputs_n_base, index_n, LSL, vn_lane_bytes_log2)); 2691b8021494Sopenharmony_ci __ Ext(vn_ext, vn_ext, vntmp_ext, vn_lane_bytes); 2692b8021494Sopenharmony_ci 2693b8021494Sopenharmony_ci { 2694b8021494Sopenharmony_ci EmissionCheckScope guard(&masm, 2695b8021494Sopenharmony_ci kInstructionSize * inputs_imm1_length * 2696b8021494Sopenharmony_ci inputs_imm2_length * 3); 2697b8021494Sopenharmony_ci for (unsigned i = 0; i < inputs_imm1_length; i++) { 2698b8021494Sopenharmony_ci for (unsigned j = 0; j < inputs_imm2_length; j++) { 2699b8021494Sopenharmony_ci __ Mov(vres, vd); 2700b8021494Sopenharmony_ci (masm.*helper)(vres_helper, inputs_imm1[i], vn_helper, inputs_imm2[j]); 2701b8021494Sopenharmony_ci __ Str(vres, MemOperand(out, vd.GetSizeInBytes(), PostIndex)); 2702b8021494Sopenharmony_ci } 2703b8021494Sopenharmony_ci } 2704b8021494Sopenharmony_ci } 2705b8021494Sopenharmony_ci 2706b8021494Sopenharmony_ci __ Add(index_n, index_n, 1); 2707b8021494Sopenharmony_ci __ Cmp(index_n, inputs_n_length); 2708b8021494Sopenharmony_ci __ B(lo, &loop_n); 2709b8021494Sopenharmony_ci 2710b8021494Sopenharmony_ci END(); 2711b8021494Sopenharmony_ci TRY_RUN(skipped); 2712b8021494Sopenharmony_ci} 2713b8021494Sopenharmony_ci 2714b8021494Sopenharmony_ci 2715b8021494Sopenharmony_ci// Test NEON instructions. The inputs_*[] and expected[] arrays should be 2716b8021494Sopenharmony_ci// arrays of rawbit representation of input values. This ensures that 2717b8021494Sopenharmony_ci// exact bit comparisons can be performed. 2718b8021494Sopenharmony_citemplate <typename Td, typename Tn> 2719b8021494Sopenharmony_cistatic void TestOpImmOpImmNEON(const char* name, 2720b8021494Sopenharmony_ci TestOpImmOpImmVdUpdateNEONHelper_t helper, 2721b8021494Sopenharmony_ci const Td inputs_d[], 2722b8021494Sopenharmony_ci const int inputs_imm1[], 2723b8021494Sopenharmony_ci unsigned inputs_imm1_length, 2724b8021494Sopenharmony_ci const Tn inputs_n[], 2725b8021494Sopenharmony_ci unsigned inputs_n_length, 2726b8021494Sopenharmony_ci const int inputs_imm2[], 2727b8021494Sopenharmony_ci unsigned inputs_imm2_length, 2728b8021494Sopenharmony_ci const Td expected[], 2729b8021494Sopenharmony_ci unsigned expected_length, 2730b8021494Sopenharmony_ci VectorFormat vd_form, 2731b8021494Sopenharmony_ci VectorFormat vn_form) { 2732b8021494Sopenharmony_ci VIXL_ASSERT(inputs_n_length > 0); 2733b8021494Sopenharmony_ci VIXL_ASSERT(inputs_imm1_length > 0); 2734b8021494Sopenharmony_ci VIXL_ASSERT(inputs_imm2_length > 0); 2735b8021494Sopenharmony_ci 2736b8021494Sopenharmony_ci const unsigned vd_lane_count = LaneCountFromFormat(vd_form); 2737b8021494Sopenharmony_ci 2738b8021494Sopenharmony_ci const unsigned results_length = 2739b8021494Sopenharmony_ci inputs_n_length * inputs_imm1_length * inputs_imm2_length; 2740b8021494Sopenharmony_ci 2741b8021494Sopenharmony_ci Td* results = new Td[results_length * vd_lane_count]; 2742b8021494Sopenharmony_ci const unsigned lane_bit = sizeof(Td) * 8; 2743b8021494Sopenharmony_ci const unsigned lane_len_in_hex = MaxHexCharCount<Td, Tn>(); 2744b8021494Sopenharmony_ci 2745b8021494Sopenharmony_ci bool skipped; 2746b8021494Sopenharmony_ci 2747b8021494Sopenharmony_ci TestOpImmOpImmNEON_Helper(helper, 2748b8021494Sopenharmony_ci reinterpret_cast<uintptr_t>(inputs_d), 2749b8021494Sopenharmony_ci inputs_imm1, 2750b8021494Sopenharmony_ci inputs_imm1_length, 2751b8021494Sopenharmony_ci reinterpret_cast<uintptr_t>(inputs_n), 2752b8021494Sopenharmony_ci inputs_n_length, 2753b8021494Sopenharmony_ci inputs_imm2, 2754b8021494Sopenharmony_ci inputs_imm2_length, 2755b8021494Sopenharmony_ci reinterpret_cast<uintptr_t>(results), 2756b8021494Sopenharmony_ci vd_form, 2757b8021494Sopenharmony_ci vn_form, 2758b8021494Sopenharmony_ci &skipped); 2759b8021494Sopenharmony_ci 2760b8021494Sopenharmony_ci if (Test::generate_test_trace()) { 2761b8021494Sopenharmony_ci // Print the results. 2762b8021494Sopenharmony_ci printf("const uint%u_t kExpected_NEON_%s[] = {\n", lane_bit, name); 2763b8021494Sopenharmony_ci for (unsigned iteration = 0; iteration < results_length; iteration++) { 2764b8021494Sopenharmony_ci printf(" "); 2765b8021494Sopenharmony_ci // Output a separate result for each element of the result vector. 2766b8021494Sopenharmony_ci for (unsigned lane = 0; lane < vd_lane_count; lane++) { 2767b8021494Sopenharmony_ci unsigned index = lane + (iteration * vd_lane_count); 2768b8021494Sopenharmony_ci printf(" 0x%0*" PRIx64 ",", 2769b8021494Sopenharmony_ci lane_len_in_hex, 2770b8021494Sopenharmony_ci static_cast<uint64_t>(results[index])); 2771b8021494Sopenharmony_ci } 2772b8021494Sopenharmony_ci printf("\n"); 2773b8021494Sopenharmony_ci } 2774b8021494Sopenharmony_ci 2775b8021494Sopenharmony_ci printf("};\n"); 2776b8021494Sopenharmony_ci printf("const unsigned kExpectedCount_NEON_%s = %u;\n", 2777b8021494Sopenharmony_ci name, 2778b8021494Sopenharmony_ci results_length); 2779b8021494Sopenharmony_ci } else if (!skipped) { 2780b8021494Sopenharmony_ci // Check the results. 2781b8021494Sopenharmony_ci VIXL_CHECK(expected_length == results_length); 2782b8021494Sopenharmony_ci unsigned error_count = 0; 2783b8021494Sopenharmony_ci unsigned counted_length = 0; 2784b8021494Sopenharmony_ci const char* padding = " "; 2785b8021494Sopenharmony_ci VIXL_ASSERT(strlen(padding) >= (lane_len_in_hex + 1)); 2786b8021494Sopenharmony_ci for (unsigned n = 0; n < inputs_n_length; n++) { 2787b8021494Sopenharmony_ci for (unsigned imm1 = 0; imm1 < inputs_imm1_length; imm1++) { 2788b8021494Sopenharmony_ci for (unsigned imm2 = 0; imm2 < inputs_imm2_length; imm2++) { 2789b8021494Sopenharmony_ci bool error_in_vector = false; 2790b8021494Sopenharmony_ci 2791b8021494Sopenharmony_ci counted_length++; 2792b8021494Sopenharmony_ci 2793b8021494Sopenharmony_ci for (unsigned lane = 0; lane < vd_lane_count; lane++) { 2794b8021494Sopenharmony_ci unsigned output_index = 2795b8021494Sopenharmony_ci (n * inputs_imm1_length * inputs_imm2_length * vd_lane_count) + 2796b8021494Sopenharmony_ci (imm1 * inputs_imm2_length * vd_lane_count) + 2797b8021494Sopenharmony_ci (imm2 * vd_lane_count) + lane; 2798b8021494Sopenharmony_ci 2799b8021494Sopenharmony_ci if (results[output_index] != expected[output_index]) { 2800b8021494Sopenharmony_ci error_in_vector = true; 2801b8021494Sopenharmony_ci break; 2802b8021494Sopenharmony_ci } 2803b8021494Sopenharmony_ci } 2804b8021494Sopenharmony_ci 2805b8021494Sopenharmony_ci if (error_in_vector && (++error_count <= kErrorReportLimit)) { 2806b8021494Sopenharmony_ci printf("%s\n", name); 2807b8021494Sopenharmony_ci printf(" Vd%.*s| Imm%.*s| Vn%.*s| Imm%.*s| Vd%.*s| Expected\n", 2808b8021494Sopenharmony_ci lane_len_in_hex + 1, 2809b8021494Sopenharmony_ci padding, 2810b8021494Sopenharmony_ci lane_len_in_hex, 2811b8021494Sopenharmony_ci padding, 2812b8021494Sopenharmony_ci lane_len_in_hex + 1, 2813b8021494Sopenharmony_ci padding, 2814b8021494Sopenharmony_ci lane_len_in_hex, 2815b8021494Sopenharmony_ci padding, 2816b8021494Sopenharmony_ci lane_len_in_hex + 1, 2817b8021494Sopenharmony_ci padding); 2818b8021494Sopenharmony_ci 2819b8021494Sopenharmony_ci for (unsigned lane = 0; lane < vd_lane_count; lane++) { 2820b8021494Sopenharmony_ci unsigned output_index = 2821b8021494Sopenharmony_ci (n * inputs_imm1_length * inputs_imm2_length * 2822b8021494Sopenharmony_ci vd_lane_count) + 2823b8021494Sopenharmony_ci (imm1 * inputs_imm2_length * vd_lane_count) + 2824b8021494Sopenharmony_ci (imm2 * vd_lane_count) + lane; 2825b8021494Sopenharmony_ci unsigned input_index_n = 2826b8021494Sopenharmony_ci (inputs_n_length - vd_lane_count + n + 1 + lane) % 2827b8021494Sopenharmony_ci inputs_n_length; 2828b8021494Sopenharmony_ci unsigned input_index_imm1 = imm1; 2829b8021494Sopenharmony_ci unsigned input_index_imm2 = imm2; 2830b8021494Sopenharmony_ci 2831b8021494Sopenharmony_ci printf("%c0x%0*" PRIx64 " | 0x%0*" PRIx64 " | 0x%0*" PRIx64 2832b8021494Sopenharmony_ci " " 2833b8021494Sopenharmony_ci "| 0x%0*" PRIx64 " | 0x%0*" PRIx64 " | 0x%0*" PRIx64 "\n", 2834b8021494Sopenharmony_ci results[output_index] != expected[output_index] ? '*' 2835b8021494Sopenharmony_ci : ' ', 2836b8021494Sopenharmony_ci lane_len_in_hex, 2837b8021494Sopenharmony_ci static_cast<uint64_t>(inputs_d[lane]), 2838b8021494Sopenharmony_ci lane_len_in_hex, 2839b8021494Sopenharmony_ci static_cast<uint64_t>(inputs_imm1[input_index_imm1]), 2840b8021494Sopenharmony_ci lane_len_in_hex, 2841b8021494Sopenharmony_ci static_cast<uint64_t>(inputs_n[input_index_n]), 2842b8021494Sopenharmony_ci lane_len_in_hex, 2843b8021494Sopenharmony_ci static_cast<uint64_t>(inputs_imm2[input_index_imm2]), 2844b8021494Sopenharmony_ci lane_len_in_hex, 2845b8021494Sopenharmony_ci static_cast<uint64_t>(results[output_index]), 2846b8021494Sopenharmony_ci lane_len_in_hex, 2847b8021494Sopenharmony_ci static_cast<uint64_t>(expected[output_index])); 2848b8021494Sopenharmony_ci } 2849b8021494Sopenharmony_ci } 2850b8021494Sopenharmony_ci } 2851b8021494Sopenharmony_ci } 2852b8021494Sopenharmony_ci } 2853b8021494Sopenharmony_ci VIXL_ASSERT(counted_length == expected_length); 2854b8021494Sopenharmony_ci if (error_count > kErrorReportLimit) { 2855b8021494Sopenharmony_ci printf("%u other errors follow.\n", error_count - kErrorReportLimit); 2856b8021494Sopenharmony_ci } 2857b8021494Sopenharmony_ci VIXL_CHECK(error_count == 0); 2858b8021494Sopenharmony_ci } 2859b8021494Sopenharmony_ci delete[] results; 2860b8021494Sopenharmony_ci} 2861b8021494Sopenharmony_ci 2862b8021494Sopenharmony_ci 2863b8021494Sopenharmony_ci// ==== Floating-point tests. ==== 2864b8021494Sopenharmony_ci 2865b8021494Sopenharmony_ci 2866b8021494Sopenharmony_ci// Standard floating-point test expansion for both double- and single-precision 2867b8021494Sopenharmony_ci// operations. 2868b8021494Sopenharmony_ci#define STRINGIFY(s) #s 2869b8021494Sopenharmony_ci 2870b8021494Sopenharmony_ci#define CALL_TEST_FP_HELPER(mnemonic, variant, type, input) \ 2871b8021494Sopenharmony_ci Test##type(STRINGIFY(mnemonic) "_" STRINGIFY(variant), \ 2872b8021494Sopenharmony_ci &MacroAssembler::mnemonic, \ 2873b8021494Sopenharmony_ci input, \ 2874b8021494Sopenharmony_ci sizeof(input) / sizeof(input[0]), \ 2875b8021494Sopenharmony_ci kExpected_##mnemonic##_##variant, \ 2876b8021494Sopenharmony_ci kExpectedCount_##mnemonic##_##variant) 2877b8021494Sopenharmony_ci 2878b8021494Sopenharmony_ci#define DEFINE_TEST_FP(mnemonic, type, input) \ 2879b8021494Sopenharmony_ci TEST(mnemonic##_d) { \ 2880b8021494Sopenharmony_ci CALL_TEST_FP_HELPER(mnemonic, d, type, kInputDouble##input); \ 2881b8021494Sopenharmony_ci } \ 2882b8021494Sopenharmony_ci TEST(mnemonic##_s) { \ 2883b8021494Sopenharmony_ci CALL_TEST_FP_HELPER(mnemonic, s, type, kInputFloat##input); \ 2884b8021494Sopenharmony_ci } 2885b8021494Sopenharmony_ci 2886b8021494Sopenharmony_ci#define DEFINE_TEST_FP_FP16(mnemonic, type, input) \ 2887b8021494Sopenharmony_ci TEST(mnemonic##_d) { \ 2888b8021494Sopenharmony_ci CALL_TEST_FP_HELPER(mnemonic, d, type, kInputDouble##input); \ 2889b8021494Sopenharmony_ci } \ 2890b8021494Sopenharmony_ci TEST(mnemonic##_s) { \ 2891b8021494Sopenharmony_ci CALL_TEST_FP_HELPER(mnemonic, s, type, kInputFloat##input); \ 2892b8021494Sopenharmony_ci } \ 2893b8021494Sopenharmony_ci TEST(mnemonic##_h) { \ 2894b8021494Sopenharmony_ci CALL_TEST_FP_HELPER(mnemonic, h, type, kInputFloat16##input); \ 2895b8021494Sopenharmony_ci } 2896b8021494Sopenharmony_ci 2897b8021494Sopenharmony_ci 2898b8021494Sopenharmony_ci// TODO: Test with a newer version of valgrind. 2899b8021494Sopenharmony_ci// 2900b8021494Sopenharmony_ci// Note: valgrind-3.10.0 does not properly interpret libm's fma() on x86_64. 2901b8021494Sopenharmony_ci// Therefore this test will be exiting though an ASSERT and thus leaking 2902b8021494Sopenharmony_ci// memory. 2903b8021494Sopenharmony_ciDEFINE_TEST_FP_FP16(fmadd, 3Op, Basic) 2904b8021494Sopenharmony_ciDEFINE_TEST_FP_FP16(fmsub, 3Op, Basic) 2905b8021494Sopenharmony_ciDEFINE_TEST_FP_FP16(fnmadd, 3Op, Basic) 2906b8021494Sopenharmony_ciDEFINE_TEST_FP_FP16(fnmsub, 3Op, Basic) 2907b8021494Sopenharmony_ci 2908b8021494Sopenharmony_ciDEFINE_TEST_FP_FP16(fadd, 2Op, Basic) 2909b8021494Sopenharmony_ciDEFINE_TEST_FP_FP16(fdiv, 2Op, Basic) 2910b8021494Sopenharmony_ciDEFINE_TEST_FP_FP16(fmax, 2Op, Basic) 2911b8021494Sopenharmony_ciDEFINE_TEST_FP_FP16(fmaxnm, 2Op, Basic) 2912b8021494Sopenharmony_ciDEFINE_TEST_FP_FP16(fmin, 2Op, Basic) 2913b8021494Sopenharmony_ciDEFINE_TEST_FP_FP16(fminnm, 2Op, Basic) 2914b8021494Sopenharmony_ciDEFINE_TEST_FP_FP16(fmul, 2Op, Basic) 2915b8021494Sopenharmony_ciDEFINE_TEST_FP_FP16(fsub, 2Op, Basic) 2916b8021494Sopenharmony_ciDEFINE_TEST_FP_FP16(fnmul, 2Op, Basic) 2917b8021494Sopenharmony_ci 2918b8021494Sopenharmony_ciDEFINE_TEST_FP_FP16(fabs, 1Op, Basic) 2919b8021494Sopenharmony_ciDEFINE_TEST_FP_FP16(fmov, 1Op, Basic) 2920b8021494Sopenharmony_ciDEFINE_TEST_FP_FP16(fneg, 1Op, Basic) 2921b8021494Sopenharmony_ciDEFINE_TEST_FP_FP16(fsqrt, 1Op, Basic) 2922b8021494Sopenharmony_ciDEFINE_TEST_FP(frint32x, 1Op, Conversions) 2923b8021494Sopenharmony_ciDEFINE_TEST_FP(frint64x, 1Op, Conversions) 2924b8021494Sopenharmony_ciDEFINE_TEST_FP(frint32z, 1Op, Conversions) 2925b8021494Sopenharmony_ciDEFINE_TEST_FP(frint64z, 1Op, Conversions) 2926b8021494Sopenharmony_ciDEFINE_TEST_FP_FP16(frinta, 1Op, Conversions) 2927b8021494Sopenharmony_ciDEFINE_TEST_FP_FP16(frinti, 1Op, Conversions) 2928b8021494Sopenharmony_ciDEFINE_TEST_FP_FP16(frintm, 1Op, Conversions) 2929b8021494Sopenharmony_ciDEFINE_TEST_FP_FP16(frintn, 1Op, Conversions) 2930b8021494Sopenharmony_ciDEFINE_TEST_FP_FP16(frintp, 1Op, Conversions) 2931b8021494Sopenharmony_ciDEFINE_TEST_FP_FP16(frintx, 1Op, Conversions) 2932b8021494Sopenharmony_ciDEFINE_TEST_FP_FP16(frintz, 1Op, Conversions) 2933b8021494Sopenharmony_ci 2934b8021494Sopenharmony_ciTEST(fcmp_d) { CALL_TEST_FP_HELPER(fcmp, d, Cmp, kInputDoubleBasic); } 2935b8021494Sopenharmony_ciTEST(fcmp_s) { CALL_TEST_FP_HELPER(fcmp, s, Cmp, kInputFloatBasic); } 2936b8021494Sopenharmony_ciTEST(fcmp_dz) { CALL_TEST_FP_HELPER(fcmp, dz, CmpZero, kInputDoubleBasic); } 2937b8021494Sopenharmony_ciTEST(fcmp_sz) { CALL_TEST_FP_HELPER(fcmp, sz, CmpZero, kInputFloatBasic); } 2938b8021494Sopenharmony_ci 2939b8021494Sopenharmony_ciTEST(fcvt_sd) { CALL_TEST_FP_HELPER(fcvt, sd, 1Op, kInputDoubleConversions); } 2940b8021494Sopenharmony_ciTEST(fcvt_ds) { CALL_TEST_FP_HELPER(fcvt, ds, 1Op, kInputFloatConversions); } 2941b8021494Sopenharmony_ci 2942b8021494Sopenharmony_ci#define DEFINE_TEST_FP_TO_INT(mnemonic, type, input) \ 2943b8021494Sopenharmony_ci TEST(mnemonic##_xd) { \ 2944b8021494Sopenharmony_ci CALL_TEST_FP_HELPER(mnemonic, xd, type, kInputDouble##input); \ 2945b8021494Sopenharmony_ci } \ 2946b8021494Sopenharmony_ci TEST(mnemonic##_xs) { \ 2947b8021494Sopenharmony_ci CALL_TEST_FP_HELPER(mnemonic, xs, type, kInputFloat##input); \ 2948b8021494Sopenharmony_ci } \ 2949b8021494Sopenharmony_ci TEST(mnemonic##_xh) { \ 2950b8021494Sopenharmony_ci CALL_TEST_FP_HELPER(mnemonic, xh, type, kInputFloat16##input); \ 2951b8021494Sopenharmony_ci } \ 2952b8021494Sopenharmony_ci TEST(mnemonic##_wd) { \ 2953b8021494Sopenharmony_ci CALL_TEST_FP_HELPER(mnemonic, wd, type, kInputDouble##input); \ 2954b8021494Sopenharmony_ci } \ 2955b8021494Sopenharmony_ci TEST(mnemonic##_ws) { \ 2956b8021494Sopenharmony_ci CALL_TEST_FP_HELPER(mnemonic, ws, type, kInputFloat##input); \ 2957b8021494Sopenharmony_ci } \ 2958b8021494Sopenharmony_ci TEST(mnemonic##_wh) { \ 2959b8021494Sopenharmony_ci CALL_TEST_FP_HELPER(mnemonic, wh, type, kInputFloat16##input); \ 2960b8021494Sopenharmony_ci } 2961b8021494Sopenharmony_ci 2962b8021494Sopenharmony_ciDEFINE_TEST_FP_TO_INT(fcvtas, FPToS, Conversions) 2963b8021494Sopenharmony_ciDEFINE_TEST_FP_TO_INT(fcvtau, FPToU, Conversions) 2964b8021494Sopenharmony_ciDEFINE_TEST_FP_TO_INT(fcvtms, FPToS, Conversions) 2965b8021494Sopenharmony_ciDEFINE_TEST_FP_TO_INT(fcvtmu, FPToU, Conversions) 2966b8021494Sopenharmony_ciDEFINE_TEST_FP_TO_INT(fcvtns, FPToS, Conversions) 2967b8021494Sopenharmony_ciDEFINE_TEST_FP_TO_INT(fcvtnu, FPToU, Conversions) 2968b8021494Sopenharmony_ciDEFINE_TEST_FP_TO_INT(fcvtzs, FPToFixedS, Conversions) 2969b8021494Sopenharmony_ciDEFINE_TEST_FP_TO_INT(fcvtzu, FPToFixedU, Conversions) 2970b8021494Sopenharmony_ci 2971b8021494Sopenharmony_ci#define DEFINE_TEST_FP_TO_JS_INT(mnemonic, type, input) \ 2972b8021494Sopenharmony_ci TEST(mnemonic##_wd) { \ 2973b8021494Sopenharmony_ci CALL_TEST_FP_HELPER(mnemonic, wd, type, kInputDouble##input); \ 2974b8021494Sopenharmony_ci } 2975b8021494Sopenharmony_ci 2976b8021494Sopenharmony_ciDEFINE_TEST_FP_TO_JS_INT(fjcvtzs, FPToS, Conversions) 2977b8021494Sopenharmony_ci 2978b8021494Sopenharmony_ci// TODO: Scvtf-fixed-point 2979b8021494Sopenharmony_ci// TODO: Scvtf-integer 2980b8021494Sopenharmony_ci// TODO: Ucvtf-fixed-point 2981b8021494Sopenharmony_ci// TODO: Ucvtf-integer 2982b8021494Sopenharmony_ci 2983b8021494Sopenharmony_ci// TODO: Fccmp 2984b8021494Sopenharmony_ci// TODO: Fcsel 2985b8021494Sopenharmony_ci 2986b8021494Sopenharmony_ci 2987b8021494Sopenharmony_ci// ==== NEON Tests. ==== 2988b8021494Sopenharmony_ci 2989b8021494Sopenharmony_ci#define CALL_TEST_NEON_HELPER_1Op(mnemonic, vdform, vnform, input_n) \ 2990b8021494Sopenharmony_ci Test1OpNEON(STRINGIFY(mnemonic) "_" STRINGIFY(vdform), \ 2991b8021494Sopenharmony_ci &MacroAssembler::mnemonic, \ 2992b8021494Sopenharmony_ci input_n, \ 2993b8021494Sopenharmony_ci (sizeof(input_n) / sizeof(input_n[0])), \ 2994b8021494Sopenharmony_ci kExpected_NEON_##mnemonic##_##vdform, \ 2995b8021494Sopenharmony_ci kExpectedCount_NEON_##mnemonic##_##vdform, \ 2996b8021494Sopenharmony_ci kFormat##vdform, \ 2997b8021494Sopenharmony_ci kFormat##vnform) 2998b8021494Sopenharmony_ci 2999b8021494Sopenharmony_ci#define CALL_TEST_NEON_HELPER_1OpAcross(mnemonic, vdform, vnform, input_n) \ 3000b8021494Sopenharmony_ci Test1OpAcrossNEON(STRINGIFY(mnemonic) "_" STRINGIFY(vdform) "_" STRINGIFY( \ 3001b8021494Sopenharmony_ci vnform), \ 3002b8021494Sopenharmony_ci &MacroAssembler::mnemonic, \ 3003b8021494Sopenharmony_ci input_n, \ 3004b8021494Sopenharmony_ci (sizeof(input_n) / sizeof(input_n[0])), \ 3005b8021494Sopenharmony_ci kExpected_NEON_##mnemonic##_##vdform##_##vnform, \ 3006b8021494Sopenharmony_ci kExpectedCount_NEON_##mnemonic##_##vdform##_##vnform, \ 3007b8021494Sopenharmony_ci kFormat##vdform, \ 3008b8021494Sopenharmony_ci kFormat##vnform) 3009b8021494Sopenharmony_ci 3010b8021494Sopenharmony_ci#define CALL_TEST_NEON_HELPER_2Op(mnemonic, \ 3011b8021494Sopenharmony_ci vdform, \ 3012b8021494Sopenharmony_ci vnform, \ 3013b8021494Sopenharmony_ci vmform, \ 3014b8021494Sopenharmony_ci input_d, \ 3015b8021494Sopenharmony_ci input_n, \ 3016b8021494Sopenharmony_ci input_m) \ 3017b8021494Sopenharmony_ci Test2OpNEON(STRINGIFY(mnemonic) "_" STRINGIFY(vdform), \ 3018b8021494Sopenharmony_ci &MacroAssembler::mnemonic, \ 3019b8021494Sopenharmony_ci input_d, \ 3020b8021494Sopenharmony_ci input_n, \ 3021b8021494Sopenharmony_ci (sizeof(input_n) / sizeof(input_n[0])), \ 3022b8021494Sopenharmony_ci input_m, \ 3023b8021494Sopenharmony_ci (sizeof(input_m) / sizeof(input_m[0])), \ 3024b8021494Sopenharmony_ci kExpected_NEON_##mnemonic##_##vdform, \ 3025b8021494Sopenharmony_ci kExpectedCount_NEON_##mnemonic##_##vdform, \ 3026b8021494Sopenharmony_ci kFormat##vdform, \ 3027b8021494Sopenharmony_ci kFormat##vnform, \ 3028b8021494Sopenharmony_ci kFormat##vmform) 3029b8021494Sopenharmony_ci 3030b8021494Sopenharmony_ci#define CALL_TEST_NEON_HELPER_2OpImm(mnemonic, \ 3031b8021494Sopenharmony_ci vdform, \ 3032b8021494Sopenharmony_ci vnform, \ 3033b8021494Sopenharmony_ci input_n, \ 3034b8021494Sopenharmony_ci input_m) \ 3035b8021494Sopenharmony_ci Test2OpImmNEON(STRINGIFY(mnemonic) "_" STRINGIFY(vdform) "_2OPIMM", \ 3036b8021494Sopenharmony_ci &MacroAssembler::mnemonic, \ 3037b8021494Sopenharmony_ci input_n, \ 3038b8021494Sopenharmony_ci (sizeof(input_n) / sizeof(input_n[0])), \ 3039b8021494Sopenharmony_ci input_m, \ 3040b8021494Sopenharmony_ci (sizeof(input_m) / sizeof(input_m[0])), \ 3041b8021494Sopenharmony_ci kExpected_NEON_##mnemonic##_##vdform##_2OPIMM, \ 3042b8021494Sopenharmony_ci kExpectedCount_NEON_##mnemonic##_##vdform##_2OPIMM, \ 3043b8021494Sopenharmony_ci kFormat##vdform, \ 3044b8021494Sopenharmony_ci kFormat##vnform) 3045b8021494Sopenharmony_ci 3046b8021494Sopenharmony_ci#define CALL_TEST_NEON_HELPER_ByElement(mnemonic, \ 3047b8021494Sopenharmony_ci vdform, \ 3048b8021494Sopenharmony_ci vnform, \ 3049b8021494Sopenharmony_ci vmform, \ 3050b8021494Sopenharmony_ci input_d, \ 3051b8021494Sopenharmony_ci input_n, \ 3052b8021494Sopenharmony_ci input_m, \ 3053b8021494Sopenharmony_ci indices) \ 3054b8021494Sopenharmony_ci TestByElementNEON( \ 3055b8021494Sopenharmony_ci STRINGIFY(mnemonic) "_" STRINGIFY(vdform) "_" STRINGIFY( \ 3056b8021494Sopenharmony_ci vnform) "_" STRINGIFY(vmform), \ 3057b8021494Sopenharmony_ci &MacroAssembler::mnemonic, \ 3058b8021494Sopenharmony_ci input_d, \ 3059b8021494Sopenharmony_ci input_n, \ 3060b8021494Sopenharmony_ci (sizeof(input_n) / sizeof(input_n[0])), \ 3061b8021494Sopenharmony_ci input_m, \ 3062b8021494Sopenharmony_ci (sizeof(input_m) / sizeof(input_m[0])), \ 3063b8021494Sopenharmony_ci indices, \ 3064b8021494Sopenharmony_ci (sizeof(indices) / sizeof(indices[0])), \ 3065b8021494Sopenharmony_ci kExpected_NEON_##mnemonic##_##vdform##_##vnform##_##vmform, \ 3066b8021494Sopenharmony_ci kExpectedCount_NEON_##mnemonic##_##vdform##_##vnform##_##vmform, \ 3067b8021494Sopenharmony_ci kFormat##vdform, \ 3068b8021494Sopenharmony_ci kFormat##vnform, \ 3069b8021494Sopenharmony_ci kFormat##vmform) 3070b8021494Sopenharmony_ci 3071b8021494Sopenharmony_ci#define CALL_TEST_NEON_HELPER_ByElement_Dot_Product(mnemonic, \ 3072b8021494Sopenharmony_ci vdform, \ 3073b8021494Sopenharmony_ci vnform, \ 3074b8021494Sopenharmony_ci vmform, \ 3075b8021494Sopenharmony_ci input_d, \ 3076b8021494Sopenharmony_ci input_n, \ 3077b8021494Sopenharmony_ci input_m, \ 3078b8021494Sopenharmony_ci indices, \ 3079b8021494Sopenharmony_ci vm_subvector_count) \ 3080b8021494Sopenharmony_ci TestByElementNEON( \ 3081b8021494Sopenharmony_ci STRINGIFY(mnemonic) "_" STRINGIFY(vdform) "_" STRINGIFY( \ 3082b8021494Sopenharmony_ci vnform) "_" STRINGIFY(vmform), \ 3083b8021494Sopenharmony_ci &MacroAssembler::mnemonic, \ 3084b8021494Sopenharmony_ci input_d, \ 3085b8021494Sopenharmony_ci input_n, \ 3086b8021494Sopenharmony_ci (sizeof(input_n) / sizeof(input_n[0])), \ 3087b8021494Sopenharmony_ci input_m, \ 3088b8021494Sopenharmony_ci (sizeof(input_m) / sizeof(input_m[0])), \ 3089b8021494Sopenharmony_ci indices, \ 3090b8021494Sopenharmony_ci (sizeof(indices) / sizeof(indices[0])), \ 3091b8021494Sopenharmony_ci kExpected_NEON_##mnemonic##_##vdform##_##vnform##_##vmform, \ 3092b8021494Sopenharmony_ci kExpectedCount_NEON_##mnemonic##_##vdform##_##vnform##_##vmform, \ 3093b8021494Sopenharmony_ci kFormat##vdform, \ 3094b8021494Sopenharmony_ci kFormat##vnform, \ 3095b8021494Sopenharmony_ci kFormat##vmform, \ 3096b8021494Sopenharmony_ci vm_subvector_count) 3097b8021494Sopenharmony_ci 3098b8021494Sopenharmony_ci#define CALL_TEST_NEON_HELPER_OpImmOpImm(helper, \ 3099b8021494Sopenharmony_ci mnemonic, \ 3100b8021494Sopenharmony_ci vdform, \ 3101b8021494Sopenharmony_ci vnform, \ 3102b8021494Sopenharmony_ci input_d, \ 3103b8021494Sopenharmony_ci input_imm1, \ 3104b8021494Sopenharmony_ci input_n, \ 3105b8021494Sopenharmony_ci input_imm2) \ 3106b8021494Sopenharmony_ci TestOpImmOpImmNEON(STRINGIFY(mnemonic) "_" STRINGIFY(vdform), \ 3107b8021494Sopenharmony_ci helper, \ 3108b8021494Sopenharmony_ci input_d, \ 3109b8021494Sopenharmony_ci input_imm1, \ 3110b8021494Sopenharmony_ci (sizeof(input_imm1) / sizeof(input_imm1[0])), \ 3111b8021494Sopenharmony_ci input_n, \ 3112b8021494Sopenharmony_ci (sizeof(input_n) / sizeof(input_n[0])), \ 3113b8021494Sopenharmony_ci input_imm2, \ 3114b8021494Sopenharmony_ci (sizeof(input_imm2) / sizeof(input_imm2[0])), \ 3115b8021494Sopenharmony_ci kExpected_NEON_##mnemonic##_##vdform, \ 3116b8021494Sopenharmony_ci kExpectedCount_NEON_##mnemonic##_##vdform, \ 3117b8021494Sopenharmony_ci kFormat##vdform, \ 3118b8021494Sopenharmony_ci kFormat##vnform) 3119b8021494Sopenharmony_ci 3120b8021494Sopenharmony_ci#define CALL_TEST_NEON_HELPER_2SAME(mnemonic, variant, input) \ 3121b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_1Op(mnemonic, variant, variant, input) 3122b8021494Sopenharmony_ci 3123b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_2SAME_8B_16B(mnemonic, input) \ 3124b8021494Sopenharmony_ci TEST(mnemonic##_8B) { \ 3125b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2SAME(mnemonic, 8B, kInput8bits##input); \ 3126b8021494Sopenharmony_ci } \ 3127b8021494Sopenharmony_ci TEST(mnemonic##_16B) { \ 3128b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2SAME(mnemonic, 16B, kInput8bits##input); \ 3129b8021494Sopenharmony_ci } 3130b8021494Sopenharmony_ci 3131b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_2SAME_4H_8H(mnemonic, input) \ 3132b8021494Sopenharmony_ci TEST(mnemonic##_4H) { \ 3133b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2SAME(mnemonic, 4H, kInput16bits##input); \ 3134b8021494Sopenharmony_ci } \ 3135b8021494Sopenharmony_ci TEST(mnemonic##_8H) { \ 3136b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2SAME(mnemonic, 8H, kInput16bits##input); \ 3137b8021494Sopenharmony_ci } 3138b8021494Sopenharmony_ci 3139b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_2SAME_2S_4S(mnemonic, input) \ 3140b8021494Sopenharmony_ci TEST(mnemonic##_2S) { \ 3141b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2SAME(mnemonic, 2S, kInput32bits##input); \ 3142b8021494Sopenharmony_ci } \ 3143b8021494Sopenharmony_ci TEST(mnemonic##_4S) { \ 3144b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2SAME(mnemonic, 4S, kInput32bits##input); \ 3145b8021494Sopenharmony_ci } 3146b8021494Sopenharmony_ci 3147b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_2SAME_BH(mnemonic, input) \ 3148b8021494Sopenharmony_ci DEFINE_TEST_NEON_2SAME_8B_16B(mnemonic, input) \ 3149b8021494Sopenharmony_ci DEFINE_TEST_NEON_2SAME_4H_8H(mnemonic, input) 3150b8021494Sopenharmony_ci 3151b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_2SAME_NO2D(mnemonic, input) \ 3152b8021494Sopenharmony_ci DEFINE_TEST_NEON_2SAME_BH(mnemonic, input) \ 3153b8021494Sopenharmony_ci DEFINE_TEST_NEON_2SAME_2S_4S(mnemonic, input) 3154b8021494Sopenharmony_ci 3155b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_2SAME(mnemonic, input) \ 3156b8021494Sopenharmony_ci DEFINE_TEST_NEON_2SAME_NO2D(mnemonic, input) \ 3157b8021494Sopenharmony_ci TEST(mnemonic##_2D) { \ 3158b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2SAME(mnemonic, 2D, kInput64bits##input); \ 3159b8021494Sopenharmony_ci } 3160b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_2SAME_SD(mnemonic, input) \ 3161b8021494Sopenharmony_ci DEFINE_TEST_NEON_2SAME_2S_4S(mnemonic, input) \ 3162b8021494Sopenharmony_ci TEST(mnemonic##_2D) { \ 3163b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2SAME(mnemonic, 2D, kInput64bits##input); \ 3164b8021494Sopenharmony_ci } 3165b8021494Sopenharmony_ci 3166b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_2SAME_FP(mnemonic, input) \ 3167b8021494Sopenharmony_ci TEST(mnemonic##_2S) { \ 3168b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2SAME(mnemonic, 2S, kInputFloat##input); \ 3169b8021494Sopenharmony_ci } \ 3170b8021494Sopenharmony_ci TEST(mnemonic##_4S) { \ 3171b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2SAME(mnemonic, 4S, kInputFloat##input); \ 3172b8021494Sopenharmony_ci } \ 3173b8021494Sopenharmony_ci TEST(mnemonic##_2D) { \ 3174b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2SAME(mnemonic, 2D, kInputDouble##input); \ 3175b8021494Sopenharmony_ci } 3176b8021494Sopenharmony_ci 3177b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_2SAME_FP_FP16(mnemonic, input) \ 3178b8021494Sopenharmony_ci DEFINE_TEST_NEON_2SAME_FP(mnemonic, input) \ 3179b8021494Sopenharmony_ci TEST(mnemonic##_4H) { \ 3180b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2SAME(mnemonic, 4H, kInputFloat16##input); \ 3181b8021494Sopenharmony_ci } \ 3182b8021494Sopenharmony_ci TEST(mnemonic##_8H) { \ 3183b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2SAME(mnemonic, 8H, kInputFloat16##input); \ 3184b8021494Sopenharmony_ci } 3185b8021494Sopenharmony_ci 3186b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_2SAME_FP_FP16_SCALAR(mnemonic, input) \ 3187b8021494Sopenharmony_ci TEST(mnemonic##_H) { \ 3188b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2SAME(mnemonic, H, kInputFloat16##input); \ 3189b8021494Sopenharmony_ci } \ 3190b8021494Sopenharmony_ci TEST(mnemonic##_S) { \ 3191b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2SAME(mnemonic, S, kInputFloat##input); \ 3192b8021494Sopenharmony_ci } \ 3193b8021494Sopenharmony_ci TEST(mnemonic##_D) { \ 3194b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2SAME(mnemonic, D, kInputDouble##input); \ 3195b8021494Sopenharmony_ci } 3196b8021494Sopenharmony_ci 3197b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_2SAME_SCALAR_B(mnemonic, input) \ 3198b8021494Sopenharmony_ci TEST(mnemonic##_B) { \ 3199b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2SAME(mnemonic, B, kInput8bits##input); \ 3200b8021494Sopenharmony_ci } 3201b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_2SAME_SCALAR_H(mnemonic, input) \ 3202b8021494Sopenharmony_ci TEST(mnemonic##_H) { \ 3203b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2SAME(mnemonic, H, kInput16bits##input); \ 3204b8021494Sopenharmony_ci } 3205b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_2SAME_SCALAR_S(mnemonic, input) \ 3206b8021494Sopenharmony_ci TEST(mnemonic##_S) { \ 3207b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2SAME(mnemonic, S, kInput32bits##input); \ 3208b8021494Sopenharmony_ci } 3209b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_2SAME_SCALAR_D(mnemonic, input) \ 3210b8021494Sopenharmony_ci TEST(mnemonic##_D) { \ 3211b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2SAME(mnemonic, D, kInput64bits##input); \ 3212b8021494Sopenharmony_ci } 3213b8021494Sopenharmony_ci 3214b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_2SAME_SCALAR(mnemonic, input) \ 3215b8021494Sopenharmony_ci DEFINE_TEST_NEON_2SAME_SCALAR_B(mnemonic, input) \ 3216b8021494Sopenharmony_ci DEFINE_TEST_NEON_2SAME_SCALAR_H(mnemonic, input) \ 3217b8021494Sopenharmony_ci DEFINE_TEST_NEON_2SAME_SCALAR_S(mnemonic, input) \ 3218b8021494Sopenharmony_ci DEFINE_TEST_NEON_2SAME_SCALAR_D(mnemonic, input) 3219b8021494Sopenharmony_ci 3220b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_2SAME_SCALAR_SD(mnemonic, input) \ 3221b8021494Sopenharmony_ci DEFINE_TEST_NEON_2SAME_SCALAR_S(mnemonic, input) \ 3222b8021494Sopenharmony_ci DEFINE_TEST_NEON_2SAME_SCALAR_D(mnemonic, input) 3223b8021494Sopenharmony_ci 3224b8021494Sopenharmony_ci 3225b8021494Sopenharmony_ci#define CALL_TEST_NEON_HELPER_ACROSS(mnemonic, vd_form, vn_form, input_n) \ 3226b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_1OpAcross(mnemonic, vd_form, vn_form, input_n) 3227b8021494Sopenharmony_ci 3228b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_ACROSS(mnemonic, input) \ 3229b8021494Sopenharmony_ci TEST(mnemonic##_B_8B) { \ 3230b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_ACROSS(mnemonic, B, 8B, kInput8bits##input); \ 3231b8021494Sopenharmony_ci } \ 3232b8021494Sopenharmony_ci TEST(mnemonic##_B_16B) { \ 3233b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_ACROSS(mnemonic, B, 16B, kInput8bits##input); \ 3234b8021494Sopenharmony_ci } \ 3235b8021494Sopenharmony_ci TEST(mnemonic##_H_4H) { \ 3236b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_ACROSS(mnemonic, H, 4H, kInput16bits##input); \ 3237b8021494Sopenharmony_ci } \ 3238b8021494Sopenharmony_ci TEST(mnemonic##_H_8H) { \ 3239b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_ACROSS(mnemonic, H, 8H, kInput16bits##input); \ 3240b8021494Sopenharmony_ci } \ 3241b8021494Sopenharmony_ci TEST(mnemonic##_S_4S) { \ 3242b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_ACROSS(mnemonic, S, 4S, kInput32bits##input); \ 3243b8021494Sopenharmony_ci } 3244b8021494Sopenharmony_ci 3245b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_ACROSS_LONG(mnemonic, input) \ 3246b8021494Sopenharmony_ci TEST(mnemonic##_H_8B) { \ 3247b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_ACROSS(mnemonic, H, 8B, kInput8bits##input); \ 3248b8021494Sopenharmony_ci } \ 3249b8021494Sopenharmony_ci TEST(mnemonic##_H_16B) { \ 3250b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_ACROSS(mnemonic, H, 16B, kInput8bits##input); \ 3251b8021494Sopenharmony_ci } \ 3252b8021494Sopenharmony_ci TEST(mnemonic##_S_4H) { \ 3253b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_ACROSS(mnemonic, S, 4H, kInput16bits##input); \ 3254b8021494Sopenharmony_ci } \ 3255b8021494Sopenharmony_ci TEST(mnemonic##_S_8H) { \ 3256b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_ACROSS(mnemonic, S, 8H, kInput16bits##input); \ 3257b8021494Sopenharmony_ci } \ 3258b8021494Sopenharmony_ci TEST(mnemonic##_D_4S) { \ 3259b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_ACROSS(mnemonic, D, 4S, kInput32bits##input); \ 3260b8021494Sopenharmony_ci } 3261b8021494Sopenharmony_ci 3262b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_ACROSS_FP(mnemonic, input) \ 3263b8021494Sopenharmony_ci TEST(mnemonic##_H_4H) { \ 3264b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_ACROSS(mnemonic, H, 4H, kInputFloat16##input); \ 3265b8021494Sopenharmony_ci } \ 3266b8021494Sopenharmony_ci TEST(mnemonic##_H_8H) { \ 3267b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_ACROSS(mnemonic, H, 8H, kInputFloat16##input); \ 3268b8021494Sopenharmony_ci } \ 3269b8021494Sopenharmony_ci TEST(mnemonic##_S_4S) { \ 3270b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_ACROSS(mnemonic, S, 4S, kInputFloat##input); \ 3271b8021494Sopenharmony_ci } 3272b8021494Sopenharmony_ci 3273b8021494Sopenharmony_ci#define CALL_TEST_NEON_HELPER_2DIFF(mnemonic, vdform, vnform, input_n) \ 3274b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_1Op(mnemonic, vdform, vnform, input_n) 3275b8021494Sopenharmony_ci 3276b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_2DIFF_LONG(mnemonic, input) \ 3277b8021494Sopenharmony_ci TEST(mnemonic##_4H) { \ 3278b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2DIFF(mnemonic, 4H, 8B, kInput8bits##input); \ 3279b8021494Sopenharmony_ci } \ 3280b8021494Sopenharmony_ci TEST(mnemonic##_8H) { \ 3281b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2DIFF(mnemonic, 8H, 16B, kInput8bits##input); \ 3282b8021494Sopenharmony_ci } \ 3283b8021494Sopenharmony_ci TEST(mnemonic##_2S) { \ 3284b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2DIFF(mnemonic, 2S, 4H, kInput16bits##input); \ 3285b8021494Sopenharmony_ci } \ 3286b8021494Sopenharmony_ci TEST(mnemonic##_4S) { \ 3287b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2DIFF(mnemonic, 4S, 8H, kInput16bits##input); \ 3288b8021494Sopenharmony_ci } \ 3289b8021494Sopenharmony_ci TEST(mnemonic##_1D) { \ 3290b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2DIFF(mnemonic, 1D, 2S, kInput32bits##input); \ 3291b8021494Sopenharmony_ci } \ 3292b8021494Sopenharmony_ci TEST(mnemonic##_2D) { \ 3293b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2DIFF(mnemonic, 2D, 4S, kInput32bits##input); \ 3294b8021494Sopenharmony_ci } 3295b8021494Sopenharmony_ci 3296b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_2DIFF_NARROW(mnemonic, input) \ 3297b8021494Sopenharmony_ci TEST(mnemonic##_8B) { \ 3298b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2DIFF(mnemonic, 8B, 8H, kInput16bits##input); \ 3299b8021494Sopenharmony_ci } \ 3300b8021494Sopenharmony_ci TEST(mnemonic##_4H) { \ 3301b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2DIFF(mnemonic, 4H, 4S, kInput32bits##input); \ 3302b8021494Sopenharmony_ci } \ 3303b8021494Sopenharmony_ci TEST(mnemonic##_2S) { \ 3304b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2DIFF(mnemonic, 2S, 2D, kInput64bits##input); \ 3305b8021494Sopenharmony_ci } \ 3306b8021494Sopenharmony_ci TEST(mnemonic##2_16B) { \ 3307b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2DIFF(mnemonic##2, 16B, 8H, kInput16bits##input); \ 3308b8021494Sopenharmony_ci } \ 3309b8021494Sopenharmony_ci TEST(mnemonic##2_8H) { \ 3310b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2DIFF(mnemonic##2, 8H, 4S, kInput32bits##input); \ 3311b8021494Sopenharmony_ci } \ 3312b8021494Sopenharmony_ci TEST(mnemonic##2_4S) { \ 3313b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2DIFF(mnemonic##2, 4S, 2D, kInput64bits##input); \ 3314b8021494Sopenharmony_ci } 3315b8021494Sopenharmony_ci 3316b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_2DIFF_FP_LONG(mnemonic, input) \ 3317b8021494Sopenharmony_ci TEST(mnemonic##_4S) { \ 3318b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2DIFF(mnemonic, 4S, 4H, kInputFloat16##input); \ 3319b8021494Sopenharmony_ci } \ 3320b8021494Sopenharmony_ci TEST(mnemonic##_2D) { \ 3321b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2DIFF(mnemonic, 2D, 2S, kInputFloat##input); \ 3322b8021494Sopenharmony_ci } \ 3323b8021494Sopenharmony_ci TEST(mnemonic##2_4S) { \ 3324b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2DIFF(mnemonic##2, 4S, 8H, kInputFloat16##input); \ 3325b8021494Sopenharmony_ci } \ 3326b8021494Sopenharmony_ci TEST(mnemonic##2_2D) { \ 3327b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2DIFF(mnemonic##2, 2D, 4S, kInputFloat##input); \ 3328b8021494Sopenharmony_ci } 3329b8021494Sopenharmony_ci 3330b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_2DIFF_FP_NARROW(mnemonic, input) \ 3331b8021494Sopenharmony_ci TEST(mnemonic##_4H) { \ 3332b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2DIFF(mnemonic, 4H, 4S, kInputFloat##input); \ 3333b8021494Sopenharmony_ci } \ 3334b8021494Sopenharmony_ci TEST(mnemonic##_2S) { \ 3335b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2DIFF(mnemonic, 2S, 2D, kInputDouble##input); \ 3336b8021494Sopenharmony_ci } \ 3337b8021494Sopenharmony_ci TEST(mnemonic##2_8H) { \ 3338b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2DIFF(mnemonic##2, 8H, 4S, kInputFloat##input); \ 3339b8021494Sopenharmony_ci } \ 3340b8021494Sopenharmony_ci TEST(mnemonic##2_4S) { \ 3341b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2DIFF(mnemonic##2, 4S, 2D, kInputDouble##input); \ 3342b8021494Sopenharmony_ci } 3343b8021494Sopenharmony_ci 3344b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_2DIFF_FP_NARROW_2S(mnemonic, input) \ 3345b8021494Sopenharmony_ci TEST(mnemonic##_2S) { \ 3346b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2DIFF(mnemonic, 2S, 2D, kInputDouble##input); \ 3347b8021494Sopenharmony_ci } \ 3348b8021494Sopenharmony_ci TEST(mnemonic##2_4S) { \ 3349b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2DIFF(mnemonic##2, 4S, 2D, kInputDouble##input); \ 3350b8021494Sopenharmony_ci } 3351b8021494Sopenharmony_ci 3352b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_2DIFF_SCALAR_NARROW(mnemonic, input) \ 3353b8021494Sopenharmony_ci TEST(mnemonic##_B) { \ 3354b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2DIFF(mnemonic, B, H, kInput16bits##input); \ 3355b8021494Sopenharmony_ci } \ 3356b8021494Sopenharmony_ci TEST(mnemonic##_H) { \ 3357b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2DIFF(mnemonic, H, S, kInput32bits##input); \ 3358b8021494Sopenharmony_ci } \ 3359b8021494Sopenharmony_ci TEST(mnemonic##_S) { \ 3360b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2DIFF(mnemonic, S, D, kInput64bits##input); \ 3361b8021494Sopenharmony_ci } 3362b8021494Sopenharmony_ci 3363b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_2DIFF_FP_SCALAR_SD(mnemonic, input) \ 3364b8021494Sopenharmony_ci TEST(mnemonic##_S) { \ 3365b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2DIFF(mnemonic, S, 2S, kInputFloat##input); \ 3366b8021494Sopenharmony_ci } \ 3367b8021494Sopenharmony_ci TEST(mnemonic##_D) { \ 3368b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2DIFF(mnemonic, D, 2D, kInputDouble##input); \ 3369b8021494Sopenharmony_ci } \ 3370b8021494Sopenharmony_ci TEST(mnemonic##_H) { \ 3371b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2DIFF(mnemonic, H, 2H, kInputFloat16##input); \ 3372b8021494Sopenharmony_ci } 3373b8021494Sopenharmony_ci 3374b8021494Sopenharmony_ci#define CALL_TEST_NEON_HELPER_3SAME(mnemonic, variant, input_d, input_nm) \ 3375b8021494Sopenharmony_ci { \ 3376b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2Op(mnemonic, \ 3377b8021494Sopenharmony_ci variant, \ 3378b8021494Sopenharmony_ci variant, \ 3379b8021494Sopenharmony_ci variant, \ 3380b8021494Sopenharmony_ci input_d, \ 3381b8021494Sopenharmony_ci input_nm, \ 3382b8021494Sopenharmony_ci input_nm); \ 3383b8021494Sopenharmony_ci } 3384b8021494Sopenharmony_ci 3385b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_3SAME_8B_16B(mnemonic, input) \ 3386b8021494Sopenharmony_ci TEST(mnemonic##_8B) { \ 3387b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3SAME(mnemonic, \ 3388b8021494Sopenharmony_ci 8B, \ 3389b8021494Sopenharmony_ci kInput8bitsAccDestination, \ 3390b8021494Sopenharmony_ci kInput8bits##input); \ 3391b8021494Sopenharmony_ci } \ 3392b8021494Sopenharmony_ci TEST(mnemonic##_16B) { \ 3393b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3SAME(mnemonic, \ 3394b8021494Sopenharmony_ci 16B, \ 3395b8021494Sopenharmony_ci kInput8bitsAccDestination, \ 3396b8021494Sopenharmony_ci kInput8bits##input); \ 3397b8021494Sopenharmony_ci } 3398b8021494Sopenharmony_ci 3399b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_3SAME_HS(mnemonic, input) \ 3400b8021494Sopenharmony_ci TEST(mnemonic##_4H) { \ 3401b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3SAME(mnemonic, \ 3402b8021494Sopenharmony_ci 4H, \ 3403b8021494Sopenharmony_ci kInput16bitsAccDestination, \ 3404b8021494Sopenharmony_ci kInput16bits##input); \ 3405b8021494Sopenharmony_ci } \ 3406b8021494Sopenharmony_ci TEST(mnemonic##_8H) { \ 3407b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3SAME(mnemonic, \ 3408b8021494Sopenharmony_ci 8H, \ 3409b8021494Sopenharmony_ci kInput16bitsAccDestination, \ 3410b8021494Sopenharmony_ci kInput16bits##input); \ 3411b8021494Sopenharmony_ci } \ 3412b8021494Sopenharmony_ci TEST(mnemonic##_2S) { \ 3413b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3SAME(mnemonic, \ 3414b8021494Sopenharmony_ci 2S, \ 3415b8021494Sopenharmony_ci kInput32bitsAccDestination, \ 3416b8021494Sopenharmony_ci kInput32bits##input); \ 3417b8021494Sopenharmony_ci } \ 3418b8021494Sopenharmony_ci TEST(mnemonic##_4S) { \ 3419b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3SAME(mnemonic, \ 3420b8021494Sopenharmony_ci 4S, \ 3421b8021494Sopenharmony_ci kInput32bitsAccDestination, \ 3422b8021494Sopenharmony_ci kInput32bits##input); \ 3423b8021494Sopenharmony_ci } 3424b8021494Sopenharmony_ci 3425b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_3SAME_NO2D(mnemonic, input) \ 3426b8021494Sopenharmony_ci DEFINE_TEST_NEON_3SAME_8B_16B(mnemonic, input) \ 3427b8021494Sopenharmony_ci DEFINE_TEST_NEON_3SAME_HS(mnemonic, input) 3428b8021494Sopenharmony_ci 3429b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_3SAME(mnemonic, input) \ 3430b8021494Sopenharmony_ci DEFINE_TEST_NEON_3SAME_NO2D(mnemonic, input) \ 3431b8021494Sopenharmony_ci TEST(mnemonic##_2D) { \ 3432b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3SAME(mnemonic, \ 3433b8021494Sopenharmony_ci 2D, \ 3434b8021494Sopenharmony_ci kInput64bitsAccDestination, \ 3435b8021494Sopenharmony_ci kInput64bits##input); \ 3436b8021494Sopenharmony_ci } 3437b8021494Sopenharmony_ci 3438b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_3SAME_FP(mnemonic, input) \ 3439b8021494Sopenharmony_ci TEST(mnemonic##_4H) { \ 3440b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3SAME(mnemonic, \ 3441b8021494Sopenharmony_ci 4H, \ 3442b8021494Sopenharmony_ci kInputFloat16AccDestination, \ 3443b8021494Sopenharmony_ci kInputFloat16##input); \ 3444b8021494Sopenharmony_ci } \ 3445b8021494Sopenharmony_ci TEST(mnemonic##_8H) { \ 3446b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3SAME(mnemonic, \ 3447b8021494Sopenharmony_ci 8H, \ 3448b8021494Sopenharmony_ci kInputFloat16AccDestination, \ 3449b8021494Sopenharmony_ci kInputFloat16##input); \ 3450b8021494Sopenharmony_ci } \ 3451b8021494Sopenharmony_ci TEST(mnemonic##_2S) { \ 3452b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3SAME(mnemonic, \ 3453b8021494Sopenharmony_ci 2S, \ 3454b8021494Sopenharmony_ci kInputFloatAccDestination, \ 3455b8021494Sopenharmony_ci kInputFloat##input); \ 3456b8021494Sopenharmony_ci } \ 3457b8021494Sopenharmony_ci TEST(mnemonic##_4S) { \ 3458b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3SAME(mnemonic, \ 3459b8021494Sopenharmony_ci 4S, \ 3460b8021494Sopenharmony_ci kInputFloatAccDestination, \ 3461b8021494Sopenharmony_ci kInputFloat##input); \ 3462b8021494Sopenharmony_ci } \ 3463b8021494Sopenharmony_ci TEST(mnemonic##_2D) { \ 3464b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3SAME(mnemonic, \ 3465b8021494Sopenharmony_ci 2D, \ 3466b8021494Sopenharmony_ci kInputDoubleAccDestination, \ 3467b8021494Sopenharmony_ci kInputDouble##input); \ 3468b8021494Sopenharmony_ci } 3469b8021494Sopenharmony_ci 3470b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_3SAME_SCALAR_D(mnemonic, input) \ 3471b8021494Sopenharmony_ci TEST(mnemonic##_D) { \ 3472b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3SAME(mnemonic, \ 3473b8021494Sopenharmony_ci D, \ 3474b8021494Sopenharmony_ci kInput64bitsAccDestination, \ 3475b8021494Sopenharmony_ci kInput64bits##input); \ 3476b8021494Sopenharmony_ci } 3477b8021494Sopenharmony_ci 3478b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_3SAME_SCALAR_HS(mnemonic, input) \ 3479b8021494Sopenharmony_ci TEST(mnemonic##_H) { \ 3480b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3SAME(mnemonic, \ 3481b8021494Sopenharmony_ci H, \ 3482b8021494Sopenharmony_ci kInput16bitsAccDestination, \ 3483b8021494Sopenharmony_ci kInput16bits##input); \ 3484b8021494Sopenharmony_ci } \ 3485b8021494Sopenharmony_ci TEST(mnemonic##_S) { \ 3486b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3SAME(mnemonic, \ 3487b8021494Sopenharmony_ci S, \ 3488b8021494Sopenharmony_ci kInput32bitsAccDestination, \ 3489b8021494Sopenharmony_ci kInput32bits##input); \ 3490b8021494Sopenharmony_ci } 3491b8021494Sopenharmony_ci 3492b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_3SAME_SCALAR(mnemonic, input) \ 3493b8021494Sopenharmony_ci TEST(mnemonic##_B) { \ 3494b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3SAME(mnemonic, \ 3495b8021494Sopenharmony_ci B, \ 3496b8021494Sopenharmony_ci kInput8bitsAccDestination, \ 3497b8021494Sopenharmony_ci kInput8bits##input); \ 3498b8021494Sopenharmony_ci } \ 3499b8021494Sopenharmony_ci TEST(mnemonic##_H) { \ 3500b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3SAME(mnemonic, \ 3501b8021494Sopenharmony_ci H, \ 3502b8021494Sopenharmony_ci kInput16bitsAccDestination, \ 3503b8021494Sopenharmony_ci kInput16bits##input); \ 3504b8021494Sopenharmony_ci } \ 3505b8021494Sopenharmony_ci TEST(mnemonic##_S) { \ 3506b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3SAME(mnemonic, \ 3507b8021494Sopenharmony_ci S, \ 3508b8021494Sopenharmony_ci kInput32bitsAccDestination, \ 3509b8021494Sopenharmony_ci kInput32bits##input); \ 3510b8021494Sopenharmony_ci } \ 3511b8021494Sopenharmony_ci TEST(mnemonic##_D) { \ 3512b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3SAME(mnemonic, \ 3513b8021494Sopenharmony_ci D, \ 3514b8021494Sopenharmony_ci kInput64bitsAccDestination, \ 3515b8021494Sopenharmony_ci kInput64bits##input); \ 3516b8021494Sopenharmony_ci } 3517b8021494Sopenharmony_ci 3518b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_3SAME_FP_SCALAR(mnemonic, input) \ 3519b8021494Sopenharmony_ci TEST(mnemonic##_H) { \ 3520b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3SAME(mnemonic, \ 3521b8021494Sopenharmony_ci H, \ 3522b8021494Sopenharmony_ci kInputFloat16AccDestination, \ 3523b8021494Sopenharmony_ci kInputFloat16##input); \ 3524b8021494Sopenharmony_ci } \ 3525b8021494Sopenharmony_ci TEST(mnemonic##_S) { \ 3526b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3SAME(mnemonic, \ 3527b8021494Sopenharmony_ci S, \ 3528b8021494Sopenharmony_ci kInputFloatAccDestination, \ 3529b8021494Sopenharmony_ci kInputFloat##input); \ 3530b8021494Sopenharmony_ci } \ 3531b8021494Sopenharmony_ci TEST(mnemonic##_D) { \ 3532b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3SAME(mnemonic, \ 3533b8021494Sopenharmony_ci D, \ 3534b8021494Sopenharmony_ci kInputDoubleAccDestination, \ 3535b8021494Sopenharmony_ci kInputDouble##input); \ 3536b8021494Sopenharmony_ci } 3537b8021494Sopenharmony_ci 3538b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_FHM(mnemonic, input_d, input_n, input_m) \ 3539b8021494Sopenharmony_ci TEST(mnemonic##_2S) { \ 3540b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3DIFF(mnemonic, \ 3541b8021494Sopenharmony_ci 2S, \ 3542b8021494Sopenharmony_ci 2H, \ 3543b8021494Sopenharmony_ci 2H, \ 3544b8021494Sopenharmony_ci kInputFloatAccDestination, \ 3545b8021494Sopenharmony_ci kInputFloat16##input_n, \ 3546b8021494Sopenharmony_ci kInputFloat16##input_m); \ 3547b8021494Sopenharmony_ci } \ 3548b8021494Sopenharmony_ci TEST(mnemonic##_4S) { \ 3549b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3DIFF(mnemonic, \ 3550b8021494Sopenharmony_ci 4S, \ 3551b8021494Sopenharmony_ci 4H, \ 3552b8021494Sopenharmony_ci 4H, \ 3553b8021494Sopenharmony_ci kInputFloatAccDestination, \ 3554b8021494Sopenharmony_ci kInputFloat16##input_n, \ 3555b8021494Sopenharmony_ci kInputFloat16##input_m); \ 3556b8021494Sopenharmony_ci } 3557b8021494Sopenharmony_ci 3558b8021494Sopenharmony_ci#define CALL_TEST_NEON_HELPER_3DIFF(mnemonic, \ 3559b8021494Sopenharmony_ci vdform, \ 3560b8021494Sopenharmony_ci vnform, \ 3561b8021494Sopenharmony_ci vmform, \ 3562b8021494Sopenharmony_ci input_d, \ 3563b8021494Sopenharmony_ci input_n, \ 3564b8021494Sopenharmony_ci input_m) \ 3565b8021494Sopenharmony_ci { \ 3566b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2Op(mnemonic, \ 3567b8021494Sopenharmony_ci vdform, \ 3568b8021494Sopenharmony_ci vnform, \ 3569b8021494Sopenharmony_ci vmform, \ 3570b8021494Sopenharmony_ci input_d, \ 3571b8021494Sopenharmony_ci input_n, \ 3572b8021494Sopenharmony_ci input_m); \ 3573b8021494Sopenharmony_ci } 3574b8021494Sopenharmony_ci 3575b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_3DIFF_LONG_8H(mnemonic, input) \ 3576b8021494Sopenharmony_ci TEST(mnemonic##_8H) { \ 3577b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3DIFF(mnemonic, \ 3578b8021494Sopenharmony_ci 8H, \ 3579b8021494Sopenharmony_ci 8B, \ 3580b8021494Sopenharmony_ci 8B, \ 3581b8021494Sopenharmony_ci kInput16bitsAccDestination, \ 3582b8021494Sopenharmony_ci kInput8bits##input, \ 3583b8021494Sopenharmony_ci kInput8bits##input); \ 3584b8021494Sopenharmony_ci } \ 3585b8021494Sopenharmony_ci TEST(mnemonic##2_8H) { \ 3586b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3DIFF(mnemonic##2, \ 3587b8021494Sopenharmony_ci 8H, \ 3588b8021494Sopenharmony_ci 16B, \ 3589b8021494Sopenharmony_ci 16B, \ 3590b8021494Sopenharmony_ci kInput16bitsAccDestination, \ 3591b8021494Sopenharmony_ci kInput8bits##input, \ 3592b8021494Sopenharmony_ci kInput8bits##input); \ 3593b8021494Sopenharmony_ci } 3594b8021494Sopenharmony_ci 3595b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_3DIFF_LONG_4S(mnemonic, input) \ 3596b8021494Sopenharmony_ci TEST(mnemonic##_4S) { \ 3597b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3DIFF(mnemonic, \ 3598b8021494Sopenharmony_ci 4S, \ 3599b8021494Sopenharmony_ci 4H, \ 3600b8021494Sopenharmony_ci 4H, \ 3601b8021494Sopenharmony_ci kInput32bitsAccDestination, \ 3602b8021494Sopenharmony_ci kInput16bits##input, \ 3603b8021494Sopenharmony_ci kInput16bits##input); \ 3604b8021494Sopenharmony_ci } \ 3605b8021494Sopenharmony_ci TEST(mnemonic##2_4S) { \ 3606b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3DIFF(mnemonic##2, \ 3607b8021494Sopenharmony_ci 4S, \ 3608b8021494Sopenharmony_ci 8H, \ 3609b8021494Sopenharmony_ci 8H, \ 3610b8021494Sopenharmony_ci kInput32bitsAccDestination, \ 3611b8021494Sopenharmony_ci kInput16bits##input, \ 3612b8021494Sopenharmony_ci kInput16bits##input); \ 3613b8021494Sopenharmony_ci } 3614b8021494Sopenharmony_ci 3615b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_3DIFF_LONG_2D(mnemonic, input) \ 3616b8021494Sopenharmony_ci TEST(mnemonic##_2D) { \ 3617b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3DIFF(mnemonic, \ 3618b8021494Sopenharmony_ci 2D, \ 3619b8021494Sopenharmony_ci 2S, \ 3620b8021494Sopenharmony_ci 2S, \ 3621b8021494Sopenharmony_ci kInput64bitsAccDestination, \ 3622b8021494Sopenharmony_ci kInput32bits##input, \ 3623b8021494Sopenharmony_ci kInput32bits##input); \ 3624b8021494Sopenharmony_ci } \ 3625b8021494Sopenharmony_ci TEST(mnemonic##2_2D) { \ 3626b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3DIFF(mnemonic##2, \ 3627b8021494Sopenharmony_ci 2D, \ 3628b8021494Sopenharmony_ci 4S, \ 3629b8021494Sopenharmony_ci 4S, \ 3630b8021494Sopenharmony_ci kInput64bitsAccDestination, \ 3631b8021494Sopenharmony_ci kInput32bits##input, \ 3632b8021494Sopenharmony_ci kInput32bits##input); \ 3633b8021494Sopenharmony_ci } 3634b8021494Sopenharmony_ci 3635b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_3DIFF_LONG_SD(mnemonic, input) \ 3636b8021494Sopenharmony_ci DEFINE_TEST_NEON_3DIFF_LONG_4S(mnemonic, input) \ 3637b8021494Sopenharmony_ci DEFINE_TEST_NEON_3DIFF_LONG_2D(mnemonic, input) 3638b8021494Sopenharmony_ci 3639b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_3DIFF_LONG(mnemonic, input) \ 3640b8021494Sopenharmony_ci DEFINE_TEST_NEON_3DIFF_LONG_8H(mnemonic, input) \ 3641b8021494Sopenharmony_ci DEFINE_TEST_NEON_3DIFF_LONG_4S(mnemonic, input) \ 3642b8021494Sopenharmony_ci DEFINE_TEST_NEON_3DIFF_LONG_2D(mnemonic, input) 3643b8021494Sopenharmony_ci 3644b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_3DIFF_SCALAR_LONG_S(mnemonic, input) \ 3645b8021494Sopenharmony_ci TEST(mnemonic##_S) { \ 3646b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3DIFF(mnemonic, \ 3647b8021494Sopenharmony_ci S, \ 3648b8021494Sopenharmony_ci H, \ 3649b8021494Sopenharmony_ci H, \ 3650b8021494Sopenharmony_ci kInput32bitsAccDestination, \ 3651b8021494Sopenharmony_ci kInput16bits##input, \ 3652b8021494Sopenharmony_ci kInput16bits##input); \ 3653b8021494Sopenharmony_ci } 3654b8021494Sopenharmony_ci 3655b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_3DIFF_SCALAR_LONG_D(mnemonic, input) \ 3656b8021494Sopenharmony_ci TEST(mnemonic##_D) { \ 3657b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3DIFF(mnemonic, \ 3658b8021494Sopenharmony_ci D, \ 3659b8021494Sopenharmony_ci S, \ 3660b8021494Sopenharmony_ci S, \ 3661b8021494Sopenharmony_ci kInput64bitsAccDestination, \ 3662b8021494Sopenharmony_ci kInput32bits##input, \ 3663b8021494Sopenharmony_ci kInput32bits##input); \ 3664b8021494Sopenharmony_ci } 3665b8021494Sopenharmony_ci 3666b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_3DIFF_SCALAR_LONG_SD(mnemonic, input) \ 3667b8021494Sopenharmony_ci DEFINE_TEST_NEON_3DIFF_SCALAR_LONG_S(mnemonic, input) \ 3668b8021494Sopenharmony_ci DEFINE_TEST_NEON_3DIFF_SCALAR_LONG_D(mnemonic, input) 3669b8021494Sopenharmony_ci 3670b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_3DIFF_WIDE(mnemonic, input) \ 3671b8021494Sopenharmony_ci TEST(mnemonic##_8H) { \ 3672b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3DIFF(mnemonic, \ 3673b8021494Sopenharmony_ci 8H, \ 3674b8021494Sopenharmony_ci 8H, \ 3675b8021494Sopenharmony_ci 8B, \ 3676b8021494Sopenharmony_ci kInput16bitsAccDestination, \ 3677b8021494Sopenharmony_ci kInput16bits##input, \ 3678b8021494Sopenharmony_ci kInput8bits##input); \ 3679b8021494Sopenharmony_ci } \ 3680b8021494Sopenharmony_ci TEST(mnemonic##_4S) { \ 3681b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3DIFF(mnemonic, \ 3682b8021494Sopenharmony_ci 4S, \ 3683b8021494Sopenharmony_ci 4S, \ 3684b8021494Sopenharmony_ci 4H, \ 3685b8021494Sopenharmony_ci kInput32bitsAccDestination, \ 3686b8021494Sopenharmony_ci kInput32bits##input, \ 3687b8021494Sopenharmony_ci kInput16bits##input); \ 3688b8021494Sopenharmony_ci } \ 3689b8021494Sopenharmony_ci TEST(mnemonic##_2D) { \ 3690b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3DIFF(mnemonic, \ 3691b8021494Sopenharmony_ci 2D, \ 3692b8021494Sopenharmony_ci 2D, \ 3693b8021494Sopenharmony_ci 2S, \ 3694b8021494Sopenharmony_ci kInput64bitsAccDestination, \ 3695b8021494Sopenharmony_ci kInput64bits##input, \ 3696b8021494Sopenharmony_ci kInput32bits##input); \ 3697b8021494Sopenharmony_ci } \ 3698b8021494Sopenharmony_ci TEST(mnemonic##2_8H) { \ 3699b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3DIFF(mnemonic##2, \ 3700b8021494Sopenharmony_ci 8H, \ 3701b8021494Sopenharmony_ci 8H, \ 3702b8021494Sopenharmony_ci 16B, \ 3703b8021494Sopenharmony_ci kInput16bitsAccDestination, \ 3704b8021494Sopenharmony_ci kInput16bits##input, \ 3705b8021494Sopenharmony_ci kInput8bits##input); \ 3706b8021494Sopenharmony_ci } \ 3707b8021494Sopenharmony_ci TEST(mnemonic##2_4S) { \ 3708b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3DIFF(mnemonic##2, \ 3709b8021494Sopenharmony_ci 4S, \ 3710b8021494Sopenharmony_ci 4S, \ 3711b8021494Sopenharmony_ci 8H, \ 3712b8021494Sopenharmony_ci kInput32bitsAccDestination, \ 3713b8021494Sopenharmony_ci kInput32bits##input, \ 3714b8021494Sopenharmony_ci kInput16bits##input); \ 3715b8021494Sopenharmony_ci } \ 3716b8021494Sopenharmony_ci TEST(mnemonic##2_2D) { \ 3717b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3DIFF(mnemonic##2, \ 3718b8021494Sopenharmony_ci 2D, \ 3719b8021494Sopenharmony_ci 2D, \ 3720b8021494Sopenharmony_ci 4S, \ 3721b8021494Sopenharmony_ci kInput64bitsAccDestination, \ 3722b8021494Sopenharmony_ci kInput64bits##input, \ 3723b8021494Sopenharmony_ci kInput32bits##input); \ 3724b8021494Sopenharmony_ci } 3725b8021494Sopenharmony_ci 3726b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_3DIFF_NARROW(mnemonic, input) \ 3727b8021494Sopenharmony_ci TEST(mnemonic##_8B) { \ 3728b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3DIFF(mnemonic, \ 3729b8021494Sopenharmony_ci 8B, \ 3730b8021494Sopenharmony_ci 8H, \ 3731b8021494Sopenharmony_ci 8H, \ 3732b8021494Sopenharmony_ci kInput8bitsAccDestination, \ 3733b8021494Sopenharmony_ci kInput16bits##input, \ 3734b8021494Sopenharmony_ci kInput16bits##input); \ 3735b8021494Sopenharmony_ci } \ 3736b8021494Sopenharmony_ci TEST(mnemonic##_4H) { \ 3737b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3DIFF(mnemonic, \ 3738b8021494Sopenharmony_ci 4H, \ 3739b8021494Sopenharmony_ci 4S, \ 3740b8021494Sopenharmony_ci 4S, \ 3741b8021494Sopenharmony_ci kInput16bitsAccDestination, \ 3742b8021494Sopenharmony_ci kInput32bits##input, \ 3743b8021494Sopenharmony_ci kInput32bits##input); \ 3744b8021494Sopenharmony_ci } \ 3745b8021494Sopenharmony_ci TEST(mnemonic##_2S) { \ 3746b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3DIFF(mnemonic, \ 3747b8021494Sopenharmony_ci 2S, \ 3748b8021494Sopenharmony_ci 2D, \ 3749b8021494Sopenharmony_ci 2D, \ 3750b8021494Sopenharmony_ci kInput32bitsAccDestination, \ 3751b8021494Sopenharmony_ci kInput64bits##input, \ 3752b8021494Sopenharmony_ci kInput64bits##input); \ 3753b8021494Sopenharmony_ci } \ 3754b8021494Sopenharmony_ci TEST(mnemonic##2_16B) { \ 3755b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3DIFF(mnemonic##2, \ 3756b8021494Sopenharmony_ci 16B, \ 3757b8021494Sopenharmony_ci 8H, \ 3758b8021494Sopenharmony_ci 8H, \ 3759b8021494Sopenharmony_ci kInput8bitsAccDestination, \ 3760b8021494Sopenharmony_ci kInput16bits##input, \ 3761b8021494Sopenharmony_ci kInput16bits##input); \ 3762b8021494Sopenharmony_ci } \ 3763b8021494Sopenharmony_ci TEST(mnemonic##2_8H) { \ 3764b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3DIFF(mnemonic##2, \ 3765b8021494Sopenharmony_ci 8H, \ 3766b8021494Sopenharmony_ci 4S, \ 3767b8021494Sopenharmony_ci 4S, \ 3768b8021494Sopenharmony_ci kInput16bitsAccDestination, \ 3769b8021494Sopenharmony_ci kInput32bits##input, \ 3770b8021494Sopenharmony_ci kInput32bits##input); \ 3771b8021494Sopenharmony_ci } \ 3772b8021494Sopenharmony_ci TEST(mnemonic##2_4S) { \ 3773b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3DIFF(mnemonic##2, \ 3774b8021494Sopenharmony_ci 4S, \ 3775b8021494Sopenharmony_ci 2D, \ 3776b8021494Sopenharmony_ci 2D, \ 3777b8021494Sopenharmony_ci kInput32bitsAccDestination, \ 3778b8021494Sopenharmony_ci kInput64bits##input, \ 3779b8021494Sopenharmony_ci kInput64bits##input); \ 3780b8021494Sopenharmony_ci } 3781b8021494Sopenharmony_ci 3782b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_3DIFF_DOUBLE_WIDE(mnemonic, input) \ 3783b8021494Sopenharmony_ci TEST(mnemonic##_2S) { \ 3784b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3DIFF(mnemonic, \ 3785b8021494Sopenharmony_ci 2S, \ 3786b8021494Sopenharmony_ci 8B, \ 3787b8021494Sopenharmony_ci 8B, \ 3788b8021494Sopenharmony_ci kInput32bitsAccDestination, \ 3789b8021494Sopenharmony_ci kInput8bits##input, \ 3790b8021494Sopenharmony_ci kInput8bits##input); \ 3791b8021494Sopenharmony_ci } \ 3792b8021494Sopenharmony_ci TEST(mnemonic##_4S) { \ 3793b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_3DIFF(mnemonic, \ 3794b8021494Sopenharmony_ci 4S, \ 3795b8021494Sopenharmony_ci 16B, \ 3796b8021494Sopenharmony_ci 16B, \ 3797b8021494Sopenharmony_ci kInput32bitsAccDestination, \ 3798b8021494Sopenharmony_ci kInput8bits##input, \ 3799b8021494Sopenharmony_ci kInput8bits##input); \ 3800b8021494Sopenharmony_ci } 3801b8021494Sopenharmony_ci 3802b8021494Sopenharmony_ci 3803b8021494Sopenharmony_ci#define CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 3804b8021494Sopenharmony_ci vdform, \ 3805b8021494Sopenharmony_ci vnform, \ 3806b8021494Sopenharmony_ci input_n, \ 3807b8021494Sopenharmony_ci input_imm) \ 3808b8021494Sopenharmony_ci { \ 3809b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OpImm(mnemonic, \ 3810b8021494Sopenharmony_ci vdform, \ 3811b8021494Sopenharmony_ci vnform, \ 3812b8021494Sopenharmony_ci input_n, \ 3813b8021494Sopenharmony_ci input_imm); \ 3814b8021494Sopenharmony_ci } 3815b8021494Sopenharmony_ci 3816b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_2OPIMM(mnemonic, input, input_imm) \ 3817b8021494Sopenharmony_ci TEST(mnemonic##_8B_2OPIMM) { \ 3818b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 3819b8021494Sopenharmony_ci 8B, \ 3820b8021494Sopenharmony_ci 8B, \ 3821b8021494Sopenharmony_ci kInput8bits##input, \ 3822b8021494Sopenharmony_ci kInput8bitsImm##input_imm); \ 3823b8021494Sopenharmony_ci } \ 3824b8021494Sopenharmony_ci TEST(mnemonic##_16B_2OPIMM) { \ 3825b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 3826b8021494Sopenharmony_ci 16B, \ 3827b8021494Sopenharmony_ci 16B, \ 3828b8021494Sopenharmony_ci kInput8bits##input, \ 3829b8021494Sopenharmony_ci kInput8bitsImm##input_imm); \ 3830b8021494Sopenharmony_ci } \ 3831b8021494Sopenharmony_ci TEST(mnemonic##_4H_2OPIMM) { \ 3832b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 3833b8021494Sopenharmony_ci 4H, \ 3834b8021494Sopenharmony_ci 4H, \ 3835b8021494Sopenharmony_ci kInput16bits##input, \ 3836b8021494Sopenharmony_ci kInput16bitsImm##input_imm); \ 3837b8021494Sopenharmony_ci } \ 3838b8021494Sopenharmony_ci TEST(mnemonic##_8H_2OPIMM) { \ 3839b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 3840b8021494Sopenharmony_ci 8H, \ 3841b8021494Sopenharmony_ci 8H, \ 3842b8021494Sopenharmony_ci kInput16bits##input, \ 3843b8021494Sopenharmony_ci kInput16bitsImm##input_imm); \ 3844b8021494Sopenharmony_ci } \ 3845b8021494Sopenharmony_ci TEST(mnemonic##_2S_2OPIMM) { \ 3846b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 3847b8021494Sopenharmony_ci 2S, \ 3848b8021494Sopenharmony_ci 2S, \ 3849b8021494Sopenharmony_ci kInput32bits##input, \ 3850b8021494Sopenharmony_ci kInput32bitsImm##input_imm); \ 3851b8021494Sopenharmony_ci } \ 3852b8021494Sopenharmony_ci TEST(mnemonic##_4S_2OPIMM) { \ 3853b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 3854b8021494Sopenharmony_ci 4S, \ 3855b8021494Sopenharmony_ci 4S, \ 3856b8021494Sopenharmony_ci kInput32bits##input, \ 3857b8021494Sopenharmony_ci kInput32bitsImm##input_imm); \ 3858b8021494Sopenharmony_ci } \ 3859b8021494Sopenharmony_ci TEST(mnemonic##_2D_2OPIMM) { \ 3860b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 3861b8021494Sopenharmony_ci 2D, \ 3862b8021494Sopenharmony_ci 2D, \ 3863b8021494Sopenharmony_ci kInput64bits##input, \ 3864b8021494Sopenharmony_ci kInput64bitsImm##input_imm); \ 3865b8021494Sopenharmony_ci } 3866b8021494Sopenharmony_ci 3867b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_2OPIMM_COPY(mnemonic, input, input_imm) \ 3868b8021494Sopenharmony_ci TEST(mnemonic##_8B_2OPIMM) { \ 3869b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 3870b8021494Sopenharmony_ci 8B, \ 3871b8021494Sopenharmony_ci B, \ 3872b8021494Sopenharmony_ci kInput8bits##input, \ 3873b8021494Sopenharmony_ci kInput8bitsImm##input_imm); \ 3874b8021494Sopenharmony_ci } \ 3875b8021494Sopenharmony_ci TEST(mnemonic##_16B_2OPIMM) { \ 3876b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 3877b8021494Sopenharmony_ci 16B, \ 3878b8021494Sopenharmony_ci B, \ 3879b8021494Sopenharmony_ci kInput8bits##input, \ 3880b8021494Sopenharmony_ci kInput8bitsImm##input_imm); \ 3881b8021494Sopenharmony_ci } \ 3882b8021494Sopenharmony_ci TEST(mnemonic##_4H_2OPIMM) { \ 3883b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 3884b8021494Sopenharmony_ci 4H, \ 3885b8021494Sopenharmony_ci H, \ 3886b8021494Sopenharmony_ci kInput16bits##input, \ 3887b8021494Sopenharmony_ci kInput16bitsImm##input_imm); \ 3888b8021494Sopenharmony_ci } \ 3889b8021494Sopenharmony_ci TEST(mnemonic##_8H_2OPIMM) { \ 3890b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 3891b8021494Sopenharmony_ci 8H, \ 3892b8021494Sopenharmony_ci H, \ 3893b8021494Sopenharmony_ci kInput16bits##input, \ 3894b8021494Sopenharmony_ci kInput16bitsImm##input_imm); \ 3895b8021494Sopenharmony_ci } \ 3896b8021494Sopenharmony_ci TEST(mnemonic##_2S_2OPIMM) { \ 3897b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 3898b8021494Sopenharmony_ci 2S, \ 3899b8021494Sopenharmony_ci S, \ 3900b8021494Sopenharmony_ci kInput32bits##input, \ 3901b8021494Sopenharmony_ci kInput32bitsImm##input_imm); \ 3902b8021494Sopenharmony_ci } \ 3903b8021494Sopenharmony_ci TEST(mnemonic##_4S_2OPIMM) { \ 3904b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 3905b8021494Sopenharmony_ci 4S, \ 3906b8021494Sopenharmony_ci S, \ 3907b8021494Sopenharmony_ci kInput32bits##input, \ 3908b8021494Sopenharmony_ci kInput32bitsImm##input_imm); \ 3909b8021494Sopenharmony_ci } \ 3910b8021494Sopenharmony_ci TEST(mnemonic##_2D_2OPIMM) { \ 3911b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 3912b8021494Sopenharmony_ci 2D, \ 3913b8021494Sopenharmony_ci D, \ 3914b8021494Sopenharmony_ci kInput64bits##input, \ 3915b8021494Sopenharmony_ci kInput64bitsImm##input_imm); \ 3916b8021494Sopenharmony_ci } 3917b8021494Sopenharmony_ci 3918b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_2OPIMM_NARROW(mnemonic, input, input_imm) \ 3919b8021494Sopenharmony_ci TEST(mnemonic##_8B_2OPIMM) { \ 3920b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 3921b8021494Sopenharmony_ci 8B, \ 3922b8021494Sopenharmony_ci 8H, \ 3923b8021494Sopenharmony_ci kInput16bits##input, \ 3924b8021494Sopenharmony_ci kInput8bitsImm##input_imm); \ 3925b8021494Sopenharmony_ci } \ 3926b8021494Sopenharmony_ci TEST(mnemonic##_4H_2OPIMM) { \ 3927b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 3928b8021494Sopenharmony_ci 4H, \ 3929b8021494Sopenharmony_ci 4S, \ 3930b8021494Sopenharmony_ci kInput32bits##input, \ 3931b8021494Sopenharmony_ci kInput16bitsImm##input_imm); \ 3932b8021494Sopenharmony_ci } \ 3933b8021494Sopenharmony_ci TEST(mnemonic##_2S_2OPIMM) { \ 3934b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 3935b8021494Sopenharmony_ci 2S, \ 3936b8021494Sopenharmony_ci 2D, \ 3937b8021494Sopenharmony_ci kInput64bits##input, \ 3938b8021494Sopenharmony_ci kInput32bitsImm##input_imm); \ 3939b8021494Sopenharmony_ci } \ 3940b8021494Sopenharmony_ci TEST(mnemonic##2_16B_2OPIMM) { \ 3941b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic##2, \ 3942b8021494Sopenharmony_ci 16B, \ 3943b8021494Sopenharmony_ci 8H, \ 3944b8021494Sopenharmony_ci kInput16bits##input, \ 3945b8021494Sopenharmony_ci kInput8bitsImm##input_imm); \ 3946b8021494Sopenharmony_ci } \ 3947b8021494Sopenharmony_ci TEST(mnemonic##2_8H_2OPIMM) { \ 3948b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic##2, \ 3949b8021494Sopenharmony_ci 8H, \ 3950b8021494Sopenharmony_ci 4S, \ 3951b8021494Sopenharmony_ci kInput32bits##input, \ 3952b8021494Sopenharmony_ci kInput16bitsImm##input_imm); \ 3953b8021494Sopenharmony_ci } \ 3954b8021494Sopenharmony_ci TEST(mnemonic##2_4S_2OPIMM) { \ 3955b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic##2, \ 3956b8021494Sopenharmony_ci 4S, \ 3957b8021494Sopenharmony_ci 2D, \ 3958b8021494Sopenharmony_ci kInput64bits##input, \ 3959b8021494Sopenharmony_ci kInput32bitsImm##input_imm); \ 3960b8021494Sopenharmony_ci } 3961b8021494Sopenharmony_ci 3962b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_2OPIMM_SCALAR_NARROW(mnemonic, input, input_imm) \ 3963b8021494Sopenharmony_ci TEST(mnemonic##_B_2OPIMM) { \ 3964b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 3965b8021494Sopenharmony_ci B, \ 3966b8021494Sopenharmony_ci H, \ 3967b8021494Sopenharmony_ci kInput16bits##input, \ 3968b8021494Sopenharmony_ci kInput8bitsImm##input_imm); \ 3969b8021494Sopenharmony_ci } \ 3970b8021494Sopenharmony_ci TEST(mnemonic##_H_2OPIMM) { \ 3971b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 3972b8021494Sopenharmony_ci H, \ 3973b8021494Sopenharmony_ci S, \ 3974b8021494Sopenharmony_ci kInput32bits##input, \ 3975b8021494Sopenharmony_ci kInput16bitsImm##input_imm); \ 3976b8021494Sopenharmony_ci } \ 3977b8021494Sopenharmony_ci TEST(mnemonic##_S_2OPIMM) { \ 3978b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 3979b8021494Sopenharmony_ci S, \ 3980b8021494Sopenharmony_ci D, \ 3981b8021494Sopenharmony_ci kInput64bits##input, \ 3982b8021494Sopenharmony_ci kInput32bitsImm##input_imm); \ 3983b8021494Sopenharmony_ci } 3984b8021494Sopenharmony_ci 3985b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_2OPIMM_FCMP_ZERO(mnemonic, input, input_imm) \ 3986b8021494Sopenharmony_ci TEST(mnemonic##_4H_2OPIMM) { \ 3987b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 3988b8021494Sopenharmony_ci 4H, \ 3989b8021494Sopenharmony_ci 4H, \ 3990b8021494Sopenharmony_ci kInputFloat16##input, \ 3991b8021494Sopenharmony_ci kInputDoubleImm##input_imm); \ 3992b8021494Sopenharmony_ci } \ 3993b8021494Sopenharmony_ci TEST(mnemonic##_8H_2OPIMM) { \ 3994b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 3995b8021494Sopenharmony_ci 8H, \ 3996b8021494Sopenharmony_ci 8H, \ 3997b8021494Sopenharmony_ci kInputFloat16##input, \ 3998b8021494Sopenharmony_ci kInputDoubleImm##input_imm); \ 3999b8021494Sopenharmony_ci } \ 4000b8021494Sopenharmony_ci TEST(mnemonic##_2S_2OPIMM) { \ 4001b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 4002b8021494Sopenharmony_ci 2S, \ 4003b8021494Sopenharmony_ci 2S, \ 4004b8021494Sopenharmony_ci kInputFloat##Basic, \ 4005b8021494Sopenharmony_ci kInputDoubleImm##input_imm); \ 4006b8021494Sopenharmony_ci } \ 4007b8021494Sopenharmony_ci TEST(mnemonic##_4S_2OPIMM) { \ 4008b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 4009b8021494Sopenharmony_ci 4S, \ 4010b8021494Sopenharmony_ci 4S, \ 4011b8021494Sopenharmony_ci kInputFloat##input, \ 4012b8021494Sopenharmony_ci kInputDoubleImm##input_imm); \ 4013b8021494Sopenharmony_ci } \ 4014b8021494Sopenharmony_ci TEST(mnemonic##_2D_2OPIMM) { \ 4015b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 4016b8021494Sopenharmony_ci 2D, \ 4017b8021494Sopenharmony_ci 2D, \ 4018b8021494Sopenharmony_ci kInputDouble##input, \ 4019b8021494Sopenharmony_ci kInputDoubleImm##input_imm); \ 4020b8021494Sopenharmony_ci } 4021b8021494Sopenharmony_ci 4022b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_2OPIMM_FP(mnemonic, input, input_imm) \ 4023b8021494Sopenharmony_ci TEST(mnemonic##_4H_2OPIMM) { \ 4024b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 4025b8021494Sopenharmony_ci 4H, \ 4026b8021494Sopenharmony_ci 4H, \ 4027b8021494Sopenharmony_ci kInputFloat16##input, \ 4028b8021494Sopenharmony_ci kInput16bitsImm##input_imm); \ 4029b8021494Sopenharmony_ci } \ 4030b8021494Sopenharmony_ci TEST(mnemonic##_8H_2OPIMM) { \ 4031b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 4032b8021494Sopenharmony_ci 8H, \ 4033b8021494Sopenharmony_ci 8H, \ 4034b8021494Sopenharmony_ci kInputFloat16##input, \ 4035b8021494Sopenharmony_ci kInput16bitsImm##input_imm); \ 4036b8021494Sopenharmony_ci } \ 4037b8021494Sopenharmony_ci TEST(mnemonic##_2S_2OPIMM) { \ 4038b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 4039b8021494Sopenharmony_ci 2S, \ 4040b8021494Sopenharmony_ci 2S, \ 4041b8021494Sopenharmony_ci kInputFloat##Basic, \ 4042b8021494Sopenharmony_ci kInput32bitsImm##input_imm); \ 4043b8021494Sopenharmony_ci } \ 4044b8021494Sopenharmony_ci TEST(mnemonic##_4S_2OPIMM) { \ 4045b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 4046b8021494Sopenharmony_ci 4S, \ 4047b8021494Sopenharmony_ci 4S, \ 4048b8021494Sopenharmony_ci kInputFloat##input, \ 4049b8021494Sopenharmony_ci kInput32bitsImm##input_imm); \ 4050b8021494Sopenharmony_ci } \ 4051b8021494Sopenharmony_ci TEST(mnemonic##_2D_2OPIMM) { \ 4052b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 4053b8021494Sopenharmony_ci 2D, \ 4054b8021494Sopenharmony_ci 2D, \ 4055b8021494Sopenharmony_ci kInputDouble##input, \ 4056b8021494Sopenharmony_ci kInput64bitsImm##input_imm); \ 4057b8021494Sopenharmony_ci } 4058b8021494Sopenharmony_ci 4059b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_2OPIMM_FP_SCALAR(mnemonic, input, input_imm) \ 4060b8021494Sopenharmony_ci TEST(mnemonic##_H_2OPIMM) { \ 4061b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 4062b8021494Sopenharmony_ci H, \ 4063b8021494Sopenharmony_ci H, \ 4064b8021494Sopenharmony_ci kInputFloat16##Basic, \ 4065b8021494Sopenharmony_ci kInput16bitsImm##input_imm); \ 4066b8021494Sopenharmony_ci } \ 4067b8021494Sopenharmony_ci TEST(mnemonic##_S_2OPIMM) { \ 4068b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 4069b8021494Sopenharmony_ci S, \ 4070b8021494Sopenharmony_ci S, \ 4071b8021494Sopenharmony_ci kInputFloat##Basic, \ 4072b8021494Sopenharmony_ci kInput32bitsImm##input_imm); \ 4073b8021494Sopenharmony_ci } \ 4074b8021494Sopenharmony_ci TEST(mnemonic##_D_2OPIMM) { \ 4075b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 4076b8021494Sopenharmony_ci D, \ 4077b8021494Sopenharmony_ci D, \ 4078b8021494Sopenharmony_ci kInputDouble##input, \ 4079b8021494Sopenharmony_ci kInput64bitsImm##input_imm); \ 4080b8021494Sopenharmony_ci } 4081b8021494Sopenharmony_ci 4082b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_2OPIMM_HSD(mnemonic, input, input_imm) \ 4083b8021494Sopenharmony_ci TEST(mnemonic##_4H_2OPIMM) { \ 4084b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 4085b8021494Sopenharmony_ci 4H, \ 4086b8021494Sopenharmony_ci 4H, \ 4087b8021494Sopenharmony_ci kInput16bits##input, \ 4088b8021494Sopenharmony_ci kInput16bitsImm##input_imm); \ 4089b8021494Sopenharmony_ci } \ 4090b8021494Sopenharmony_ci TEST(mnemonic##_8H_2OPIMM) { \ 4091b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 4092b8021494Sopenharmony_ci 8H, \ 4093b8021494Sopenharmony_ci 8H, \ 4094b8021494Sopenharmony_ci kInput16bits##input, \ 4095b8021494Sopenharmony_ci kInput16bitsImm##input_imm); \ 4096b8021494Sopenharmony_ci } \ 4097b8021494Sopenharmony_ci TEST(mnemonic##_2S_2OPIMM) { \ 4098b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 4099b8021494Sopenharmony_ci 2S, \ 4100b8021494Sopenharmony_ci 2S, \ 4101b8021494Sopenharmony_ci kInput32bits##input, \ 4102b8021494Sopenharmony_ci kInput32bitsImm##input_imm); \ 4103b8021494Sopenharmony_ci } \ 4104b8021494Sopenharmony_ci TEST(mnemonic##_4S_2OPIMM) { \ 4105b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 4106b8021494Sopenharmony_ci 4S, \ 4107b8021494Sopenharmony_ci 4S, \ 4108b8021494Sopenharmony_ci kInput32bits##input, \ 4109b8021494Sopenharmony_ci kInput32bitsImm##input_imm); \ 4110b8021494Sopenharmony_ci } \ 4111b8021494Sopenharmony_ci TEST(mnemonic##_2D_2OPIMM) { \ 4112b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 4113b8021494Sopenharmony_ci 2D, \ 4114b8021494Sopenharmony_ci 2D, \ 4115b8021494Sopenharmony_ci kInput64bits##input, \ 4116b8021494Sopenharmony_ci kInput64bitsImm##input_imm); \ 4117b8021494Sopenharmony_ci } 4118b8021494Sopenharmony_ci 4119b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_2OPIMM_SCALAR_D(mnemonic, input, input_imm) \ 4120b8021494Sopenharmony_ci TEST(mnemonic##_D_2OPIMM) { \ 4121b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 4122b8021494Sopenharmony_ci D, \ 4123b8021494Sopenharmony_ci D, \ 4124b8021494Sopenharmony_ci kInput64bits##input, \ 4125b8021494Sopenharmony_ci kInput64bitsImm##input_imm); \ 4126b8021494Sopenharmony_ci } 4127b8021494Sopenharmony_ci 4128b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_2OPIMM_SCALAR_HSD(mnemonic, input, input_imm) \ 4129b8021494Sopenharmony_ci TEST(mnemonic##_H_2OPIMM) { \ 4130b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 4131b8021494Sopenharmony_ci H, \ 4132b8021494Sopenharmony_ci H, \ 4133b8021494Sopenharmony_ci kInput16bits##input, \ 4134b8021494Sopenharmony_ci kInput16bitsImm##input_imm); \ 4135b8021494Sopenharmony_ci } \ 4136b8021494Sopenharmony_ci TEST(mnemonic##_S_2OPIMM) { \ 4137b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 4138b8021494Sopenharmony_ci S, \ 4139b8021494Sopenharmony_ci S, \ 4140b8021494Sopenharmony_ci kInput32bits##input, \ 4141b8021494Sopenharmony_ci kInput32bitsImm##input_imm); \ 4142b8021494Sopenharmony_ci } \ 4143b8021494Sopenharmony_ci DEFINE_TEST_NEON_2OPIMM_SCALAR_D(mnemonic, input, input_imm) 4144b8021494Sopenharmony_ci 4145b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_2OPIMM_FP_SCALAR_D(mnemonic, input, input_imm) \ 4146b8021494Sopenharmony_ci TEST(mnemonic##_D_2OPIMM) { \ 4147b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 4148b8021494Sopenharmony_ci D, \ 4149b8021494Sopenharmony_ci D, \ 4150b8021494Sopenharmony_ci kInputDouble##input, \ 4151b8021494Sopenharmony_ci kInputDoubleImm##input_imm); \ 4152b8021494Sopenharmony_ci } 4153b8021494Sopenharmony_ci 4154b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_2OPIMM_FP_SCALAR_HSD(mnemonic, input, input_imm) \ 4155b8021494Sopenharmony_ci TEST(mnemonic##_H_2OPIMM) { \ 4156b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 4157b8021494Sopenharmony_ci H, \ 4158b8021494Sopenharmony_ci H, \ 4159b8021494Sopenharmony_ci kInputFloat16##input, \ 4160b8021494Sopenharmony_ci kInputDoubleImm##input_imm); \ 4161b8021494Sopenharmony_ci } \ 4162b8021494Sopenharmony_ci TEST(mnemonic##_S_2OPIMM) { \ 4163b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 4164b8021494Sopenharmony_ci S, \ 4165b8021494Sopenharmony_ci S, \ 4166b8021494Sopenharmony_ci kInputFloat##input, \ 4167b8021494Sopenharmony_ci kInputDoubleImm##input_imm); \ 4168b8021494Sopenharmony_ci } \ 4169b8021494Sopenharmony_ci DEFINE_TEST_NEON_2OPIMM_FP_SCALAR_D(mnemonic, input, input_imm) 4170b8021494Sopenharmony_ci 4171b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_2OPIMM_SCALAR(mnemonic, input, input_imm) \ 4172b8021494Sopenharmony_ci TEST(mnemonic##_B_2OPIMM) { \ 4173b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 4174b8021494Sopenharmony_ci B, \ 4175b8021494Sopenharmony_ci B, \ 4176b8021494Sopenharmony_ci kInput8bits##input, \ 4177b8021494Sopenharmony_ci kInput8bitsImm##input_imm); \ 4178b8021494Sopenharmony_ci } \ 4179b8021494Sopenharmony_ci DEFINE_TEST_NEON_2OPIMM_SCALAR_HSD(mnemonic, input, input_imm) 4180b8021494Sopenharmony_ci 4181b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_2OPIMM_LONG(mnemonic, input, input_imm) \ 4182b8021494Sopenharmony_ci TEST(mnemonic##_8H_2OPIMM) { \ 4183b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 4184b8021494Sopenharmony_ci 8H, \ 4185b8021494Sopenharmony_ci 8B, \ 4186b8021494Sopenharmony_ci kInput8bits##input, \ 4187b8021494Sopenharmony_ci kInput8bitsImm##input_imm); \ 4188b8021494Sopenharmony_ci } \ 4189b8021494Sopenharmony_ci TEST(mnemonic##_4S_2OPIMM) { \ 4190b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 4191b8021494Sopenharmony_ci 4S, \ 4192b8021494Sopenharmony_ci 4H, \ 4193b8021494Sopenharmony_ci kInput16bits##input, \ 4194b8021494Sopenharmony_ci kInput16bitsImm##input_imm); \ 4195b8021494Sopenharmony_ci } \ 4196b8021494Sopenharmony_ci TEST(mnemonic##_2D_2OPIMM) { \ 4197b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic, \ 4198b8021494Sopenharmony_ci 2D, \ 4199b8021494Sopenharmony_ci 2S, \ 4200b8021494Sopenharmony_ci kInput32bits##input, \ 4201b8021494Sopenharmony_ci kInput32bitsImm##input_imm); \ 4202b8021494Sopenharmony_ci } \ 4203b8021494Sopenharmony_ci TEST(mnemonic##2_8H_2OPIMM) { \ 4204b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic##2, \ 4205b8021494Sopenharmony_ci 8H, \ 4206b8021494Sopenharmony_ci 16B, \ 4207b8021494Sopenharmony_ci kInput8bits##input, \ 4208b8021494Sopenharmony_ci kInput8bitsImm##input_imm); \ 4209b8021494Sopenharmony_ci } \ 4210b8021494Sopenharmony_ci TEST(mnemonic##2_4S_2OPIMM) { \ 4211b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic##2, \ 4212b8021494Sopenharmony_ci 4S, \ 4213b8021494Sopenharmony_ci 8H, \ 4214b8021494Sopenharmony_ci kInput16bits##input, \ 4215b8021494Sopenharmony_ci kInput16bitsImm##input_imm); \ 4216b8021494Sopenharmony_ci } \ 4217b8021494Sopenharmony_ci TEST(mnemonic##2_2D_2OPIMM) { \ 4218b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OPIMM(mnemonic##2, \ 4219b8021494Sopenharmony_ci 2D, \ 4220b8021494Sopenharmony_ci 4S, \ 4221b8021494Sopenharmony_ci kInput32bits##input, \ 4222b8021494Sopenharmony_ci kInput32bitsImm##input_imm); \ 4223b8021494Sopenharmony_ci } 4224b8021494Sopenharmony_ci 4225b8021494Sopenharmony_ci#define CALL_TEST_NEON_HELPER_BYELEMENT_DOT_PRODUCT(mnemonic, \ 4226b8021494Sopenharmony_ci vdform, \ 4227b8021494Sopenharmony_ci vnform, \ 4228b8021494Sopenharmony_ci vmform, \ 4229b8021494Sopenharmony_ci input_d, \ 4230b8021494Sopenharmony_ci input_n, \ 4231b8021494Sopenharmony_ci input_m, \ 4232b8021494Sopenharmony_ci indices, \ 4233b8021494Sopenharmony_ci vm_subvector_count) \ 4234b8021494Sopenharmony_ci { \ 4235b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_ByElement_Dot_Product(mnemonic, \ 4236b8021494Sopenharmony_ci vdform, \ 4237b8021494Sopenharmony_ci vnform, \ 4238b8021494Sopenharmony_ci vmform, \ 4239b8021494Sopenharmony_ci input_d, \ 4240b8021494Sopenharmony_ci input_n, \ 4241b8021494Sopenharmony_ci input_m, \ 4242b8021494Sopenharmony_ci indices, \ 4243b8021494Sopenharmony_ci vm_subvector_count); \ 4244b8021494Sopenharmony_ci } 4245b8021494Sopenharmony_ci 4246b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_BYELEMENT_DOT_PRODUCT(mnemonic, \ 4247b8021494Sopenharmony_ci input_d, \ 4248b8021494Sopenharmony_ci input_n, \ 4249b8021494Sopenharmony_ci input_m) \ 4250b8021494Sopenharmony_ci TEST(mnemonic##_2S_8B_B) { \ 4251b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_BYELEMENT_DOT_PRODUCT(mnemonic, \ 4252b8021494Sopenharmony_ci 2S, \ 4253b8021494Sopenharmony_ci 8B, \ 4254b8021494Sopenharmony_ci B, \ 4255b8021494Sopenharmony_ci kInput32bits##input_d, \ 4256b8021494Sopenharmony_ci kInput8bits##input_n, \ 4257b8021494Sopenharmony_ci kInput8bits##input_m, \ 4258b8021494Sopenharmony_ci kInputSIndices, \ 4259b8021494Sopenharmony_ci 4); \ 4260b8021494Sopenharmony_ci } \ 4261b8021494Sopenharmony_ci TEST(mnemonic##_4S_16B_B) { \ 4262b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_BYELEMENT_DOT_PRODUCT(mnemonic, \ 4263b8021494Sopenharmony_ci 4S, \ 4264b8021494Sopenharmony_ci 16B, \ 4265b8021494Sopenharmony_ci B, \ 4266b8021494Sopenharmony_ci kInput32bits##input_d, \ 4267b8021494Sopenharmony_ci kInput8bits##input_n, \ 4268b8021494Sopenharmony_ci kInput8bits##input_m, \ 4269b8021494Sopenharmony_ci kInputSIndices, \ 4270b8021494Sopenharmony_ci 4); \ 4271b8021494Sopenharmony_ci } 4272b8021494Sopenharmony_ci 4273b8021494Sopenharmony_ci#define CALL_TEST_NEON_HELPER_BYELEMENT(mnemonic, \ 4274b8021494Sopenharmony_ci vdform, \ 4275b8021494Sopenharmony_ci vnform, \ 4276b8021494Sopenharmony_ci vmform, \ 4277b8021494Sopenharmony_ci input_d, \ 4278b8021494Sopenharmony_ci input_n, \ 4279b8021494Sopenharmony_ci input_m, \ 4280b8021494Sopenharmony_ci indices) \ 4281b8021494Sopenharmony_ci { \ 4282b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_ByElement(mnemonic, \ 4283b8021494Sopenharmony_ci vdform, \ 4284b8021494Sopenharmony_ci vnform, \ 4285b8021494Sopenharmony_ci vmform, \ 4286b8021494Sopenharmony_ci input_d, \ 4287b8021494Sopenharmony_ci input_n, \ 4288b8021494Sopenharmony_ci input_m, \ 4289b8021494Sopenharmony_ci indices); \ 4290b8021494Sopenharmony_ci } 4291b8021494Sopenharmony_ci 4292b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_BYELEMENT(mnemonic, input_d, input_n, input_m) \ 4293b8021494Sopenharmony_ci TEST(mnemonic##_4H_4H_H) { \ 4294b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_BYELEMENT(mnemonic, \ 4295b8021494Sopenharmony_ci 4H, \ 4296b8021494Sopenharmony_ci 4H, \ 4297b8021494Sopenharmony_ci H, \ 4298b8021494Sopenharmony_ci kInput16bits##input_d, \ 4299b8021494Sopenharmony_ci kInput16bits##input_n, \ 4300b8021494Sopenharmony_ci kInput16bits##input_m, \ 4301b8021494Sopenharmony_ci kInputHIndices); \ 4302b8021494Sopenharmony_ci } \ 4303b8021494Sopenharmony_ci TEST(mnemonic##_8H_8H_H) { \ 4304b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_BYELEMENT(mnemonic, \ 4305b8021494Sopenharmony_ci 8H, \ 4306b8021494Sopenharmony_ci 8H, \ 4307b8021494Sopenharmony_ci H, \ 4308b8021494Sopenharmony_ci kInput16bits##input_d, \ 4309b8021494Sopenharmony_ci kInput16bits##input_n, \ 4310b8021494Sopenharmony_ci kInput16bits##input_m, \ 4311b8021494Sopenharmony_ci kInputHIndices); \ 4312b8021494Sopenharmony_ci } \ 4313b8021494Sopenharmony_ci TEST(mnemonic##_2S_2S_S) { \ 4314b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_BYELEMENT(mnemonic, \ 4315b8021494Sopenharmony_ci 2S, \ 4316b8021494Sopenharmony_ci 2S, \ 4317b8021494Sopenharmony_ci S, \ 4318b8021494Sopenharmony_ci kInput32bits##input_d, \ 4319b8021494Sopenharmony_ci kInput32bits##input_n, \ 4320b8021494Sopenharmony_ci kInput32bits##input_m, \ 4321b8021494Sopenharmony_ci kInputSIndices); \ 4322b8021494Sopenharmony_ci } \ 4323b8021494Sopenharmony_ci TEST(mnemonic##_4S_4S_S) { \ 4324b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_BYELEMENT(mnemonic, \ 4325b8021494Sopenharmony_ci 4S, \ 4326b8021494Sopenharmony_ci 4S, \ 4327b8021494Sopenharmony_ci S, \ 4328b8021494Sopenharmony_ci kInput32bits##input_d, \ 4329b8021494Sopenharmony_ci kInput32bits##input_n, \ 4330b8021494Sopenharmony_ci kInput32bits##input_m, \ 4331b8021494Sopenharmony_ci kInputSIndices); \ 4332b8021494Sopenharmony_ci } 4333b8021494Sopenharmony_ci 4334b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_BYELEMENT_SCALAR(mnemonic, input_d, input_n, input_m) \ 4335b8021494Sopenharmony_ci TEST(mnemonic##_H_H_H) { \ 4336b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_BYELEMENT(mnemonic, \ 4337b8021494Sopenharmony_ci H, \ 4338b8021494Sopenharmony_ci H, \ 4339b8021494Sopenharmony_ci H, \ 4340b8021494Sopenharmony_ci kInput16bits##input_d, \ 4341b8021494Sopenharmony_ci kInput16bits##input_n, \ 4342b8021494Sopenharmony_ci kInput16bits##input_m, \ 4343b8021494Sopenharmony_ci kInputHIndices); \ 4344b8021494Sopenharmony_ci } \ 4345b8021494Sopenharmony_ci TEST(mnemonic##_S_S_S) { \ 4346b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_BYELEMENT(mnemonic, \ 4347b8021494Sopenharmony_ci S, \ 4348b8021494Sopenharmony_ci S, \ 4349b8021494Sopenharmony_ci S, \ 4350b8021494Sopenharmony_ci kInput32bits##input_d, \ 4351b8021494Sopenharmony_ci kInput32bits##input_n, \ 4352b8021494Sopenharmony_ci kInput32bits##input_m, \ 4353b8021494Sopenharmony_ci kInputSIndices); \ 4354b8021494Sopenharmony_ci } 4355b8021494Sopenharmony_ci 4356b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_FP_BYELEMENT(mnemonic, input_d, input_n, input_m) \ 4357b8021494Sopenharmony_ci TEST(mnemonic##_4H_4H_H) { \ 4358b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_BYELEMENT(mnemonic, \ 4359b8021494Sopenharmony_ci 4H, \ 4360b8021494Sopenharmony_ci 4H, \ 4361b8021494Sopenharmony_ci H, \ 4362b8021494Sopenharmony_ci kInputFloat16##input_d, \ 4363b8021494Sopenharmony_ci kInputFloat16##input_n, \ 4364b8021494Sopenharmony_ci kInputFloat16##input_m, \ 4365b8021494Sopenharmony_ci kInputHIndices); \ 4366b8021494Sopenharmony_ci } \ 4367b8021494Sopenharmony_ci TEST(mnemonic##_8H_8H_H) { \ 4368b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_BYELEMENT(mnemonic, \ 4369b8021494Sopenharmony_ci 8H, \ 4370b8021494Sopenharmony_ci 8H, \ 4371b8021494Sopenharmony_ci H, \ 4372b8021494Sopenharmony_ci kInputFloat16##input_d, \ 4373b8021494Sopenharmony_ci kInputFloat16##input_n, \ 4374b8021494Sopenharmony_ci kInputFloat16##input_m, \ 4375b8021494Sopenharmony_ci kInputHIndices); \ 4376b8021494Sopenharmony_ci } \ 4377b8021494Sopenharmony_ci TEST(mnemonic##_2S_2S_S) { \ 4378b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_BYELEMENT(mnemonic, \ 4379b8021494Sopenharmony_ci 2S, \ 4380b8021494Sopenharmony_ci 2S, \ 4381b8021494Sopenharmony_ci S, \ 4382b8021494Sopenharmony_ci kInputFloat##input_d, \ 4383b8021494Sopenharmony_ci kInputFloat##input_n, \ 4384b8021494Sopenharmony_ci kInputFloat##input_m, \ 4385b8021494Sopenharmony_ci kInputSIndices); \ 4386b8021494Sopenharmony_ci } \ 4387b8021494Sopenharmony_ci TEST(mnemonic##_4S_4S_S) { \ 4388b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_BYELEMENT(mnemonic, \ 4389b8021494Sopenharmony_ci 4S, \ 4390b8021494Sopenharmony_ci 4S, \ 4391b8021494Sopenharmony_ci S, \ 4392b8021494Sopenharmony_ci kInputFloat##input_d, \ 4393b8021494Sopenharmony_ci kInputFloat##input_n, \ 4394b8021494Sopenharmony_ci kInputFloat##input_m, \ 4395b8021494Sopenharmony_ci kInputSIndices); \ 4396b8021494Sopenharmony_ci } \ 4397b8021494Sopenharmony_ci TEST(mnemonic##_2D_2D_D) { \ 4398b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_BYELEMENT(mnemonic, \ 4399b8021494Sopenharmony_ci 2D, \ 4400b8021494Sopenharmony_ci 2D, \ 4401b8021494Sopenharmony_ci D, \ 4402b8021494Sopenharmony_ci kInputDouble##input_d, \ 4403b8021494Sopenharmony_ci kInputDouble##input_n, \ 4404b8021494Sopenharmony_ci kInputDouble##input_m, \ 4405b8021494Sopenharmony_ci kInputDIndices); \ 4406b8021494Sopenharmony_ci } 4407b8021494Sopenharmony_ci 4408b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_FHM_BYELEMENT(mnemonic, input_d, input_n, input_m) \ 4409b8021494Sopenharmony_ci TEST(mnemonic##_2S_2H_H) { \ 4410b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_BYELEMENT(mnemonic, \ 4411b8021494Sopenharmony_ci 2S, \ 4412b8021494Sopenharmony_ci 2H, \ 4413b8021494Sopenharmony_ci H, \ 4414b8021494Sopenharmony_ci kInputFloatAccDestination, \ 4415b8021494Sopenharmony_ci kInputFloat16##input_n, \ 4416b8021494Sopenharmony_ci kInputFloat16##input_m, \ 4417b8021494Sopenharmony_ci kInputHIndices); \ 4418b8021494Sopenharmony_ci } \ 4419b8021494Sopenharmony_ci TEST(mnemonic##_4S_4H_H) { \ 4420b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_BYELEMENT(mnemonic, \ 4421b8021494Sopenharmony_ci 4S, \ 4422b8021494Sopenharmony_ci 4H, \ 4423b8021494Sopenharmony_ci H, \ 4424b8021494Sopenharmony_ci kInputFloatAccDestination, \ 4425b8021494Sopenharmony_ci kInputFloat16##input_n, \ 4426b8021494Sopenharmony_ci kInputFloat16##input_m, \ 4427b8021494Sopenharmony_ci kInputHIndices); \ 4428b8021494Sopenharmony_ci } 4429b8021494Sopenharmony_ci 4430b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_FP_BYELEMENT_SCALAR(mnemonic, inp_d, inp_n, inp_m) \ 4431b8021494Sopenharmony_ci TEST(mnemonic##_H_H_H) { \ 4432b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_BYELEMENT(mnemonic, \ 4433b8021494Sopenharmony_ci H, \ 4434b8021494Sopenharmony_ci H, \ 4435b8021494Sopenharmony_ci H, \ 4436b8021494Sopenharmony_ci kInputFloat16##inp_d, \ 4437b8021494Sopenharmony_ci kInputFloat16##inp_n, \ 4438b8021494Sopenharmony_ci kInputFloat16##inp_m, \ 4439b8021494Sopenharmony_ci kInputHIndices); \ 4440b8021494Sopenharmony_ci } \ 4441b8021494Sopenharmony_ci TEST(mnemonic##_S_S_S) { \ 4442b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_BYELEMENT(mnemonic, \ 4443b8021494Sopenharmony_ci S, \ 4444b8021494Sopenharmony_ci S, \ 4445b8021494Sopenharmony_ci S, \ 4446b8021494Sopenharmony_ci kInputFloat##inp_d, \ 4447b8021494Sopenharmony_ci kInputFloat##inp_n, \ 4448b8021494Sopenharmony_ci kInputFloat##inp_m, \ 4449b8021494Sopenharmony_ci kInputSIndices); \ 4450b8021494Sopenharmony_ci } \ 4451b8021494Sopenharmony_ci TEST(mnemonic##_D_D_D) { \ 4452b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_BYELEMENT(mnemonic, \ 4453b8021494Sopenharmony_ci D, \ 4454b8021494Sopenharmony_ci D, \ 4455b8021494Sopenharmony_ci D, \ 4456b8021494Sopenharmony_ci kInputDouble##inp_d, \ 4457b8021494Sopenharmony_ci kInputDouble##inp_n, \ 4458b8021494Sopenharmony_ci kInputDouble##inp_m, \ 4459b8021494Sopenharmony_ci kInputDIndices); \ 4460b8021494Sopenharmony_ci } 4461b8021494Sopenharmony_ci 4462b8021494Sopenharmony_ci 4463b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_BYELEMENT_DIFF(mnemonic, input_d, input_n, input_m) \ 4464b8021494Sopenharmony_ci TEST(mnemonic##_4S_4H_H) { \ 4465b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_BYELEMENT(mnemonic, \ 4466b8021494Sopenharmony_ci 4S, \ 4467b8021494Sopenharmony_ci 4H, \ 4468b8021494Sopenharmony_ci H, \ 4469b8021494Sopenharmony_ci kInput32bits##input_d, \ 4470b8021494Sopenharmony_ci kInput16bits##input_n, \ 4471b8021494Sopenharmony_ci kInput16bits##input_m, \ 4472b8021494Sopenharmony_ci kInputHIndices); \ 4473b8021494Sopenharmony_ci } \ 4474b8021494Sopenharmony_ci TEST(mnemonic##2_4S_8H_H) { \ 4475b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_BYELEMENT(mnemonic##2, \ 4476b8021494Sopenharmony_ci 4S, \ 4477b8021494Sopenharmony_ci 8H, \ 4478b8021494Sopenharmony_ci H, \ 4479b8021494Sopenharmony_ci kInput32bits##input_d, \ 4480b8021494Sopenharmony_ci kInput16bits##input_n, \ 4481b8021494Sopenharmony_ci kInput16bits##input_m, \ 4482b8021494Sopenharmony_ci kInputHIndices); \ 4483b8021494Sopenharmony_ci } \ 4484b8021494Sopenharmony_ci TEST(mnemonic##_2D_2S_S) { \ 4485b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_BYELEMENT(mnemonic, \ 4486b8021494Sopenharmony_ci 2D, \ 4487b8021494Sopenharmony_ci 2S, \ 4488b8021494Sopenharmony_ci S, \ 4489b8021494Sopenharmony_ci kInput64bits##input_d, \ 4490b8021494Sopenharmony_ci kInput32bits##input_n, \ 4491b8021494Sopenharmony_ci kInput32bits##input_m, \ 4492b8021494Sopenharmony_ci kInputSIndices); \ 4493b8021494Sopenharmony_ci } \ 4494b8021494Sopenharmony_ci TEST(mnemonic##2_2D_4S_S) { \ 4495b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_BYELEMENT(mnemonic##2, \ 4496b8021494Sopenharmony_ci 2D, \ 4497b8021494Sopenharmony_ci 4S, \ 4498b8021494Sopenharmony_ci S, \ 4499b8021494Sopenharmony_ci kInput64bits##input_d, \ 4500b8021494Sopenharmony_ci kInput32bits##input_n, \ 4501b8021494Sopenharmony_ci kInput32bits##input_m, \ 4502b8021494Sopenharmony_ci kInputSIndices); \ 4503b8021494Sopenharmony_ci } 4504b8021494Sopenharmony_ci 4505b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_BYELEMENT_DIFF_SCALAR(mnemonic, \ 4506b8021494Sopenharmony_ci input_d, \ 4507b8021494Sopenharmony_ci input_n, \ 4508b8021494Sopenharmony_ci input_m) \ 4509b8021494Sopenharmony_ci TEST(mnemonic##_S_H_H) { \ 4510b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_BYELEMENT(mnemonic, \ 4511b8021494Sopenharmony_ci S, \ 4512b8021494Sopenharmony_ci H, \ 4513b8021494Sopenharmony_ci H, \ 4514b8021494Sopenharmony_ci kInput32bits##input_d, \ 4515b8021494Sopenharmony_ci kInput16bits##input_n, \ 4516b8021494Sopenharmony_ci kInput16bits##input_m, \ 4517b8021494Sopenharmony_ci kInputHIndices); \ 4518b8021494Sopenharmony_ci } \ 4519b8021494Sopenharmony_ci TEST(mnemonic##_D_S_S) { \ 4520b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_BYELEMENT(mnemonic, \ 4521b8021494Sopenharmony_ci D, \ 4522b8021494Sopenharmony_ci S, \ 4523b8021494Sopenharmony_ci S, \ 4524b8021494Sopenharmony_ci kInput64bits##input_d, \ 4525b8021494Sopenharmony_ci kInput32bits##input_n, \ 4526b8021494Sopenharmony_ci kInput32bits##input_m, \ 4527b8021494Sopenharmony_ci kInputSIndices); \ 4528b8021494Sopenharmony_ci } 4529b8021494Sopenharmony_ci 4530b8021494Sopenharmony_ci 4531b8021494Sopenharmony_ci#define CALL_TEST_NEON_HELPER_2OP2IMM(mnemonic, \ 4532b8021494Sopenharmony_ci variant, \ 4533b8021494Sopenharmony_ci input_d, \ 4534b8021494Sopenharmony_ci input_imm1, \ 4535b8021494Sopenharmony_ci input_n, \ 4536b8021494Sopenharmony_ci input_imm2) \ 4537b8021494Sopenharmony_ci { \ 4538b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_OpImmOpImm(&MacroAssembler::mnemonic, \ 4539b8021494Sopenharmony_ci mnemonic, \ 4540b8021494Sopenharmony_ci variant, \ 4541b8021494Sopenharmony_ci variant, \ 4542b8021494Sopenharmony_ci input_d, \ 4543b8021494Sopenharmony_ci input_imm1, \ 4544b8021494Sopenharmony_ci input_n, \ 4545b8021494Sopenharmony_ci input_imm2); \ 4546b8021494Sopenharmony_ci } 4547b8021494Sopenharmony_ci 4548b8021494Sopenharmony_ci#define DEFINE_TEST_NEON_2OP2IMM(mnemonic, \ 4549b8021494Sopenharmony_ci input_d, \ 4550b8021494Sopenharmony_ci input_imm1, \ 4551b8021494Sopenharmony_ci input_n, \ 4552b8021494Sopenharmony_ci input_imm2) \ 4553b8021494Sopenharmony_ci TEST(mnemonic##_B) { \ 4554b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OP2IMM(mnemonic, \ 4555b8021494Sopenharmony_ci 16B, \ 4556b8021494Sopenharmony_ci kInput8bits##input_d, \ 4557b8021494Sopenharmony_ci kInput8bitsImm##input_imm1, \ 4558b8021494Sopenharmony_ci kInput8bits##input_n, \ 4559b8021494Sopenharmony_ci kInput8bitsImm##input_imm2); \ 4560b8021494Sopenharmony_ci } \ 4561b8021494Sopenharmony_ci TEST(mnemonic##_H) { \ 4562b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OP2IMM(mnemonic, \ 4563b8021494Sopenharmony_ci 8H, \ 4564b8021494Sopenharmony_ci kInput16bits##input_d, \ 4565b8021494Sopenharmony_ci kInput16bitsImm##input_imm1, \ 4566b8021494Sopenharmony_ci kInput16bits##input_n, \ 4567b8021494Sopenharmony_ci kInput16bitsImm##input_imm2); \ 4568b8021494Sopenharmony_ci } \ 4569b8021494Sopenharmony_ci TEST(mnemonic##_S) { \ 4570b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OP2IMM(mnemonic, \ 4571b8021494Sopenharmony_ci 4S, \ 4572b8021494Sopenharmony_ci kInput32bits##input_d, \ 4573b8021494Sopenharmony_ci kInput32bitsImm##input_imm1, \ 4574b8021494Sopenharmony_ci kInput32bits##input_n, \ 4575b8021494Sopenharmony_ci kInput32bitsImm##input_imm2); \ 4576b8021494Sopenharmony_ci } \ 4577b8021494Sopenharmony_ci TEST(mnemonic##_D) { \ 4578b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2OP2IMM(mnemonic, \ 4579b8021494Sopenharmony_ci 2D, \ 4580b8021494Sopenharmony_ci kInput64bits##input_d, \ 4581b8021494Sopenharmony_ci kInput64bitsImm##input_imm1, \ 4582b8021494Sopenharmony_ci kInput64bits##input_n, \ 4583b8021494Sopenharmony_ci kInput64bitsImm##input_imm2); \ 4584b8021494Sopenharmony_ci } 4585b8021494Sopenharmony_ci 4586b8021494Sopenharmony_ci 4587b8021494Sopenharmony_ci// Advanced SIMD copy. 4588b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OP2IMM( 4589b8021494Sopenharmony_ci ins, Basic, LaneCountFromZero, Basic, LaneCountFromZero) 4590b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_COPY(dup, Basic, LaneCountFromZero) 4591b8021494Sopenharmony_ci 4592b8021494Sopenharmony_ci 4593b8021494Sopenharmony_ci// Advanced SIMD scalar copy. 4594b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_SCALAR(dup, Basic, LaneCountFromZero) 4595b8021494Sopenharmony_ci 4596b8021494Sopenharmony_ci 4597b8021494Sopenharmony_ci// Advanced SIMD three same. 4598b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_NO2D(shadd, Basic) 4599b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME(sqadd, Basic) 4600b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_NO2D(srhadd, Basic) 4601b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_NO2D(shsub, Basic) 4602b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME(sqsub, Basic) 4603b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME(cmgt, Basic) 4604b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME(cmge, Basic) 4605b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME(sshl, Basic) 4606b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME(sqshl, Basic) 4607b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME(srshl, Basic) 4608b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME(sqrshl, Basic) 4609b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_NO2D(smax, Basic) 4610b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_NO2D(smin, Basic) 4611b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_NO2D(sabd, Basic) 4612b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_NO2D(saba, Basic) 4613b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME(add, Basic) 4614b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME(cmtst, Basic) 4615b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_NO2D(mla, Basic) 4616b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_NO2D(mul, Basic) 4617b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_NO2D(smaxp, Basic) 4618b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_NO2D(sminp, Basic) 4619b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_HS(sqdmulh, Basic) 4620b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME(addp, Basic) 4621b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_FP(fmaxnm, Basic) 4622b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_FP(fmla, Basic) 4623b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_FP(fadd, Basic) 4624b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_FP(fmulx, Basic) 4625b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_FP(fcmeq, Basic) 4626b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_FP(fmax, Basic) 4627b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_FP(frecps, Basic) 4628b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_8B_16B(and_, Basic) 4629b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_8B_16B(bic, Basic) 4630b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_FP(fminnm, Basic) 4631b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_FP(fmls, Basic) 4632b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_FP(fsub, Basic) 4633b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_FP(fmin, Basic) 4634b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_FP(frsqrts, Basic) 4635b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_8B_16B(orr, Basic) 4636b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_8B_16B(orn, Basic) 4637b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_NO2D(uhadd, Basic) 4638b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME(uqadd, Basic) 4639b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_NO2D(urhadd, Basic) 4640b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_NO2D(uhsub, Basic) 4641b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME(uqsub, Basic) 4642b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME(cmhi, Basic) 4643b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME(cmhs, Basic) 4644b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME(ushl, Basic) 4645b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME(uqshl, Basic) 4646b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME(urshl, Basic) 4647b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME(uqrshl, Basic) 4648b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_NO2D(umax, Basic) 4649b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_NO2D(umin, Basic) 4650b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_NO2D(uabd, Basic) 4651b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_NO2D(uaba, Basic) 4652b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME(sub, Basic) 4653b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME(cmeq, Basic) 4654b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_NO2D(mls, Basic) 4655b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_8B_16B(pmul, Basic) 4656b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_NO2D(uminp, Basic) 4657b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_NO2D(umaxp, Basic) 4658b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_HS(sqrdmulh, Basic) 4659b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_HS(sqrdmlah, Basic) 4660b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_HS(sqrdmlsh, Basic) 4661b8021494Sopenharmony_ciDEFINE_TEST_NEON_3DIFF_DOUBLE_WIDE(udot, Basic) 4662b8021494Sopenharmony_ciDEFINE_TEST_NEON_3DIFF_DOUBLE_WIDE(sdot, Basic) 4663b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_FP(fmaxnmp, Basic) 4664b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_FP(faddp, Basic) 4665b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_FP(fmul, Basic) 4666b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_FP(fcmge, Basic) 4667b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_FP(facge, Basic) 4668b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_FP(fmaxp, Basic) 4669b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_FP(fdiv, Basic) 4670b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_8B_16B(eor, Basic) 4671b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_8B_16B(bsl, Basic) 4672b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_FP(fminnmp, Basic) 4673b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_FP(fabd, Basic) 4674b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_FP(fcmgt, Basic) 4675b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_FP(facgt, Basic) 4676b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_FP(fminp, Basic) 4677b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_8B_16B(bit, Basic) 4678b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_8B_16B(bif, Basic) 4679b8021494Sopenharmony_ci 4680b8021494Sopenharmony_ci 4681b8021494Sopenharmony_ci// Advanced SIMD scalar three same. 4682b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_SCALAR(sqadd, Basic) 4683b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_SCALAR(sqsub, Basic) 4684b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_SCALAR_D(cmgt, Basic) 4685b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_SCALAR_D(cmge, Basic) 4686b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_SCALAR_D(sshl, Basic) 4687b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_SCALAR(sqshl, Basic) 4688b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_SCALAR_D(srshl, Basic) 4689b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_SCALAR(sqrshl, Basic) 4690b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_SCALAR_D(add, Basic) 4691b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_SCALAR_D(cmtst, Basic) 4692b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_SCALAR_HS(sqdmulh, Basic) 4693b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_FP_SCALAR(fmulx, Basic) 4694b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_FP_SCALAR(fcmeq, Basic) 4695b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_FP_SCALAR(frecps, Basic) 4696b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_FP_SCALAR(frsqrts, Basic) 4697b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_SCALAR_D(uqadd, Basic) 4698b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_SCALAR_D(uqsub, Basic) 4699b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_SCALAR_D(cmhi, Basic) 4700b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_SCALAR_D(cmhs, Basic) 4701b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_SCALAR_D(ushl, Basic) 4702b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_SCALAR(uqshl, Basic) 4703b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_SCALAR_D(urshl, Basic) 4704b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_SCALAR(uqrshl, Basic) 4705b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_SCALAR_D(sub, Basic) 4706b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_SCALAR_D(cmeq, Basic) 4707b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_SCALAR_HS(sqrdmulh, Basic) 4708b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_SCALAR_HS(sqrdmlah, Basic) 4709b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_SCALAR_HS(sqrdmlsh, Basic) 4710b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_FP_SCALAR(fcmge, Basic) 4711b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_FP_SCALAR(facge, Basic) 4712b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_FP_SCALAR(fabd, Basic) 4713b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_FP_SCALAR(fcmgt, Basic) 4714b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME_FP_SCALAR(facgt, Basic) 4715b8021494Sopenharmony_ci 4716b8021494Sopenharmony_ci 4717b8021494Sopenharmony_ci// Advanced SIMD FHM instructions (FMLAL, FMLSL). 4718b8021494Sopenharmony_ci// These are oddballs: they are encoded under the 3SAME group but behave 4719b8021494Sopenharmony_ci// quite differently. 4720b8021494Sopenharmony_ciDEFINE_TEST_NEON_FHM(fmlal, Basic, Basic, Basic) 4721b8021494Sopenharmony_ciDEFINE_TEST_NEON_FHM(fmlal2, Basic, Basic, Basic) 4722b8021494Sopenharmony_ciDEFINE_TEST_NEON_FHM(fmlsl, Basic, Basic, Basic) 4723b8021494Sopenharmony_ciDEFINE_TEST_NEON_FHM(fmlsl2, Basic, Basic, Basic) 4724b8021494Sopenharmony_ci 4725b8021494Sopenharmony_ci 4726b8021494Sopenharmony_ci// Advanced SIMD three different. 4727b8021494Sopenharmony_ciDEFINE_TEST_NEON_3DIFF_LONG(saddl, Basic) 4728b8021494Sopenharmony_ciDEFINE_TEST_NEON_3DIFF_WIDE(saddw, Basic) 4729b8021494Sopenharmony_ciDEFINE_TEST_NEON_3DIFF_LONG(ssubl, Basic) 4730b8021494Sopenharmony_ciDEFINE_TEST_NEON_3DIFF_WIDE(ssubw, Basic) 4731b8021494Sopenharmony_ciDEFINE_TEST_NEON_3DIFF_NARROW(addhn, Basic) 4732b8021494Sopenharmony_ciDEFINE_TEST_NEON_3DIFF_LONG(sabal, Basic) 4733b8021494Sopenharmony_ciDEFINE_TEST_NEON_3DIFF_NARROW(subhn, Basic) 4734b8021494Sopenharmony_ciDEFINE_TEST_NEON_3DIFF_LONG(sabdl, Basic) 4735b8021494Sopenharmony_ciDEFINE_TEST_NEON_3DIFF_LONG(smlal, Basic) 4736b8021494Sopenharmony_ciDEFINE_TEST_NEON_3DIFF_LONG_SD(sqdmlal, Basic) 4737b8021494Sopenharmony_ciDEFINE_TEST_NEON_3DIFF_LONG(smlsl, Basic) 4738b8021494Sopenharmony_ciDEFINE_TEST_NEON_3DIFF_LONG_SD(sqdmlsl, Basic) 4739b8021494Sopenharmony_ciDEFINE_TEST_NEON_3DIFF_LONG(smull, Basic) 4740b8021494Sopenharmony_ciDEFINE_TEST_NEON_3DIFF_LONG_SD(sqdmull, Basic) 4741b8021494Sopenharmony_ciDEFINE_TEST_NEON_3DIFF_LONG_8H(pmull, Basic) 4742b8021494Sopenharmony_ciDEFINE_TEST_NEON_3DIFF_LONG(uaddl, Basic) 4743b8021494Sopenharmony_ciDEFINE_TEST_NEON_3DIFF_WIDE(uaddw, Basic) 4744b8021494Sopenharmony_ciDEFINE_TEST_NEON_3DIFF_LONG(usubl, Basic) 4745b8021494Sopenharmony_ciDEFINE_TEST_NEON_3DIFF_WIDE(usubw, Basic) 4746b8021494Sopenharmony_ciDEFINE_TEST_NEON_3DIFF_NARROW(raddhn, Basic) 4747b8021494Sopenharmony_ciDEFINE_TEST_NEON_3DIFF_LONG(uabal, Basic) 4748b8021494Sopenharmony_ciDEFINE_TEST_NEON_3DIFF_NARROW(rsubhn, Basic) 4749b8021494Sopenharmony_ciDEFINE_TEST_NEON_3DIFF_LONG(uabdl, Basic) 4750b8021494Sopenharmony_ciDEFINE_TEST_NEON_3DIFF_LONG(umlal, Basic) 4751b8021494Sopenharmony_ciDEFINE_TEST_NEON_3DIFF_LONG(umlsl, Basic) 4752b8021494Sopenharmony_ciDEFINE_TEST_NEON_3DIFF_LONG(umull, Basic) 4753b8021494Sopenharmony_ci 4754b8021494Sopenharmony_ci 4755b8021494Sopenharmony_ci// Advanced SIMD scalar three different. 4756b8021494Sopenharmony_ciDEFINE_TEST_NEON_3DIFF_SCALAR_LONG_SD(sqdmlal, Basic) 4757b8021494Sopenharmony_ciDEFINE_TEST_NEON_3DIFF_SCALAR_LONG_SD(sqdmlsl, Basic) 4758b8021494Sopenharmony_ciDEFINE_TEST_NEON_3DIFF_SCALAR_LONG_SD(sqdmull, Basic) 4759b8021494Sopenharmony_ci 4760b8021494Sopenharmony_ci 4761b8021494Sopenharmony_ci// Advanced SIMD scalar pairwise. 4762b8021494Sopenharmony_ciTEST(addp_SCALAR) { 4763b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2DIFF(addp, D, 2D, kInput64bitsBasic); 4764b8021494Sopenharmony_ci} 4765b8021494Sopenharmony_ciDEFINE_TEST_NEON_2DIFF_FP_SCALAR_SD(fmaxnmp, Basic) 4766b8021494Sopenharmony_ciDEFINE_TEST_NEON_2DIFF_FP_SCALAR_SD(faddp, Basic) 4767b8021494Sopenharmony_ciDEFINE_TEST_NEON_2DIFF_FP_SCALAR_SD(fmaxp, Basic) 4768b8021494Sopenharmony_ciDEFINE_TEST_NEON_2DIFF_FP_SCALAR_SD(fminnmp, Basic) 4769b8021494Sopenharmony_ciDEFINE_TEST_NEON_2DIFF_FP_SCALAR_SD(fminp, Basic) 4770b8021494Sopenharmony_ci 4771b8021494Sopenharmony_ci 4772b8021494Sopenharmony_ci// Advanced SIMD shift by immediate. 4773b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM(sshr, Basic, TypeWidth) 4774b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM(ssra, Basic, TypeWidth) 4775b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM(srshr, Basic, TypeWidth) 4776b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM(srsra, Basic, TypeWidth) 4777b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM(shl, Basic, TypeWidthFromZero) 4778b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM(sqshl, Basic, TypeWidthFromZero) 4779b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_NARROW(shrn, Basic, TypeWidth) 4780b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_NARROW(rshrn, Basic, TypeWidth) 4781b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_NARROW(sqshrn, Basic, TypeWidth) 4782b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_NARROW(sqrshrn, Basic, TypeWidth) 4783b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_LONG(sshll, Basic, TypeWidthFromZero) 4784b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_HSD(scvtf, 4785b8021494Sopenharmony_ci FixedPointConversions, 4786b8021494Sopenharmony_ci TypeWidthFromZeroToWidth) 4787b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_FP(fcvtzs, Conversions, TypeWidthFromZeroToWidth) 4788b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM(ushr, Basic, TypeWidth) 4789b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM(usra, Basic, TypeWidth) 4790b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM(urshr, Basic, TypeWidth) 4791b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM(ursra, Basic, TypeWidth) 4792b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM(sri, Basic, TypeWidth) 4793b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM(sli, Basic, TypeWidthFromZero) 4794b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM(sqshlu, Basic, TypeWidthFromZero) 4795b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM(uqshl, Basic, TypeWidthFromZero) 4796b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_NARROW(sqshrun, Basic, TypeWidth) 4797b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_NARROW(sqrshrun, Basic, TypeWidth) 4798b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_NARROW(uqshrn, Basic, TypeWidth) 4799b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_NARROW(uqrshrn, Basic, TypeWidth) 4800b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_LONG(ushll, Basic, TypeWidthFromZero) 4801b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_HSD(ucvtf, 4802b8021494Sopenharmony_ci FixedPointConversions, 4803b8021494Sopenharmony_ci TypeWidthFromZeroToWidth) 4804b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_FP(fcvtzu, Conversions, TypeWidthFromZeroToWidth) 4805b8021494Sopenharmony_ci 4806b8021494Sopenharmony_ci 4807b8021494Sopenharmony_ci// Advanced SIMD scalar shift by immediate.. 4808b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_SCALAR_D(sshr, Basic, TypeWidth) 4809b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_SCALAR_D(ssra, Basic, TypeWidth) 4810b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_SCALAR_D(srshr, Basic, TypeWidth) 4811b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_SCALAR_D(srsra, Basic, TypeWidth) 4812b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_SCALAR_D(shl, Basic, TypeWidthFromZero) 4813b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_SCALAR(sqshl, Basic, TypeWidthFromZero) 4814b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_SCALAR_NARROW(sqshrn, Basic, TypeWidth) 4815b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_SCALAR_NARROW(sqrshrn, Basic, TypeWidth) 4816b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_SCALAR_HSD(scvtf, 4817b8021494Sopenharmony_ci FixedPointConversions, 4818b8021494Sopenharmony_ci TypeWidthFromZeroToWidth) 4819b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_FP_SCALAR(fcvtzs, Conversions, TypeWidthFromZeroToWidth) 4820b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_SCALAR_D(ushr, Basic, TypeWidth) 4821b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_SCALAR_D(usra, Basic, TypeWidth) 4822b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_SCALAR_D(urshr, Basic, TypeWidth) 4823b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_SCALAR_D(ursra, Basic, TypeWidth) 4824b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_SCALAR_D(sri, Basic, TypeWidth) 4825b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_SCALAR_D(sli, Basic, TypeWidthFromZero) 4826b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_SCALAR(sqshlu, Basic, TypeWidthFromZero) 4827b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_SCALAR(uqshl, Basic, TypeWidthFromZero) 4828b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_SCALAR_NARROW(sqshrun, Basic, TypeWidth) 4829b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_SCALAR_NARROW(sqrshrun, Basic, TypeWidth) 4830b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_SCALAR_NARROW(uqshrn, Basic, TypeWidth) 4831b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_SCALAR_NARROW(uqrshrn, Basic, TypeWidth) 4832b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_SCALAR_HSD(ucvtf, 4833b8021494Sopenharmony_ci FixedPointConversions, 4834b8021494Sopenharmony_ci TypeWidthFromZeroToWidth) 4835b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_FP_SCALAR(fcvtzu, Conversions, TypeWidthFromZeroToWidth) 4836b8021494Sopenharmony_ci 4837b8021494Sopenharmony_ci 4838b8021494Sopenharmony_ci// Advanced SIMD two-register miscellaneous. 4839b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_NO2D(rev64, Basic) 4840b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_8B_16B(rev16, Basic) 4841b8021494Sopenharmony_ciDEFINE_TEST_NEON_2DIFF_LONG(saddlp, Basic) 4842b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME(suqadd, Basic) 4843b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_NO2D(cls, Basic) 4844b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_8B_16B(cnt, Basic) 4845b8021494Sopenharmony_ciDEFINE_TEST_NEON_2DIFF_LONG(sadalp, Basic) 4846b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME(sqabs, Basic) 4847b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM(cmgt, Basic, Zero) 4848b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM(cmeq, Basic, Zero) 4849b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM(cmlt, Basic, Zero) 4850b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME(abs, Basic) 4851b8021494Sopenharmony_ciDEFINE_TEST_NEON_2DIFF_NARROW(xtn, Basic) 4852b8021494Sopenharmony_ciDEFINE_TEST_NEON_2DIFF_NARROW(sqxtn, Basic) 4853b8021494Sopenharmony_ciDEFINE_TEST_NEON_2DIFF_FP_NARROW(fcvtn, Conversions) 4854b8021494Sopenharmony_ciDEFINE_TEST_NEON_2DIFF_FP_LONG(fcvtl, Conversions) 4855b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_FP_FP16(frintn, Conversions) 4856b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_FP_FP16(frintm, Conversions) 4857b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_FP_FP16(fcvtns, Conversions) 4858b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_FP_FP16(fcvtms, Conversions) 4859b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_FP_FP16(fcvtas, Conversions) 4860b8021494Sopenharmony_ci// SCVTF (vector, integer) covered by SCVTF(vector, fixed point) with fbits 0. 4861b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_FCMP_ZERO(fcmgt, Basic, Zero) 4862b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_FCMP_ZERO(fcmeq, Basic, Zero) 4863b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_FCMP_ZERO(fcmlt, Basic, Zero) 4864b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_FP_FP16(fabs, Basic) 4865b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_FP_FP16(frintp, Conversions) 4866b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_FP_FP16(frintz, Conversions) 4867b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_FP_FP16(fcvtps, Conversions) 4868b8021494Sopenharmony_ci// FCVTZS(vector, integer) covered by FCVTZS(vector, fixed point) with fbits 0. 4869b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_2S_4S(urecpe, Basic) 4870b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_FP_FP16(frecpe, Basic) 4871b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_BH(rev32, Basic) 4872b8021494Sopenharmony_ciDEFINE_TEST_NEON_2DIFF_LONG(uaddlp, Basic) 4873b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME(usqadd, Basic) 4874b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_NO2D(clz, Basic) 4875b8021494Sopenharmony_ciDEFINE_TEST_NEON_2DIFF_LONG(uadalp, Basic) 4876b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME(sqneg, Basic) 4877b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM(cmge, Basic, Zero) 4878b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM(cmle, Basic, Zero) 4879b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME(neg, Basic) 4880b8021494Sopenharmony_ciDEFINE_TEST_NEON_2DIFF_NARROW(sqxtun, Basic) 4881b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_LONG(shll, Basic, SHLL) 4882b8021494Sopenharmony_ciDEFINE_TEST_NEON_2DIFF_NARROW(uqxtn, Basic) 4883b8021494Sopenharmony_ciDEFINE_TEST_NEON_2DIFF_FP_NARROW_2S(fcvtxn, Conversions) 4884b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_FP(frint32x, Conversions) 4885b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_FP(frint64x, Conversions) 4886b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_FP(frint32z, Conversions) 4887b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_FP(frint64z, Conversions) 4888b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_FP_FP16(frinta, Conversions) 4889b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_FP_FP16(frintx, Conversions) 4890b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_FP_FP16(fcvtnu, Conversions) 4891b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_FP_FP16(fcvtmu, Conversions) 4892b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_FP_FP16(fcvtau, Conversions) 4893b8021494Sopenharmony_ci// UCVTF (vector, integer) covered by UCVTF(vector, fixed point) with fbits 0. 4894b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_8B_16B(not_, Basic) 4895b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_8B_16B(rbit, Basic) 4896b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_FCMP_ZERO(fcmge, Basic, Zero) 4897b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_FCMP_ZERO(fcmle, Basic, Zero) 4898b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_FP_FP16(fneg, Basic) 4899b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_FP_FP16(frinti, Conversions) 4900b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_FP_FP16(fcvtpu, Conversions) 4901b8021494Sopenharmony_ci// FCVTZU(vector, integer) covered by FCVTZU(vector, fixed point) with fbits 0. 4902b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_2S_4S(ursqrte, Basic) 4903b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_FP_FP16(frsqrte, Basic) 4904b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_FP_FP16(fsqrt, Basic) 4905b8021494Sopenharmony_ci 4906b8021494Sopenharmony_ci 4907b8021494Sopenharmony_ci// Advanced SIMD scalar two-register miscellaneous. 4908b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_SCALAR(suqadd, Basic) 4909b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_SCALAR(sqabs, Basic) 4910b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_SCALAR_D(cmgt, Basic, Zero) 4911b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_SCALAR_D(cmeq, Basic, Zero) 4912b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_SCALAR_D(cmlt, Basic, Zero) 4913b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_SCALAR_D(abs, Basic) 4914b8021494Sopenharmony_ciDEFINE_TEST_NEON_2DIFF_SCALAR_NARROW(sqxtn, Basic) 4915b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_FP_FP16_SCALAR(fcvtns, Conversions) 4916b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_FP_FP16_SCALAR(fcvtms, Conversions) 4917b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_FP_FP16_SCALAR(fcvtas, Conversions) 4918b8021494Sopenharmony_ci// SCVTF (vector, integer) covered by SCVTF(vector, fixed point) with fbits 0. 4919b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_FP_SCALAR_HSD(fcmgt, Basic, Zero) 4920b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_FP_SCALAR_HSD(fcmeq, Basic, Zero) 4921b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_FP_SCALAR_HSD(fcmlt, Basic, Zero) 4922b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_FP_FP16_SCALAR(fcvtps, Conversions) 4923b8021494Sopenharmony_ci// FCVTZS(vector, integer) covered by FCVTZS(vector, fixed point) with fbits 0. 4924b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_FP_FP16_SCALAR(frecpe, Basic) 4925b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_FP_FP16_SCALAR(frecpx, Basic) 4926b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_SCALAR(usqadd, Basic) 4927b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_SCALAR(sqneg, Basic) 4928b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_SCALAR_D(cmge, Basic, Zero) 4929b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_SCALAR_D(cmle, Basic, Zero) 4930b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_SCALAR_D(neg, Basic) 4931b8021494Sopenharmony_ciDEFINE_TEST_NEON_2DIFF_SCALAR_NARROW(sqxtun, Basic) 4932b8021494Sopenharmony_ciDEFINE_TEST_NEON_2DIFF_SCALAR_NARROW(uqxtn, Basic) 4933b8021494Sopenharmony_ciTEST(fcvtxn_SCALAR) { 4934b8021494Sopenharmony_ci CALL_TEST_NEON_HELPER_2DIFF(fcvtxn, S, D, kInputDoubleConversions); 4935b8021494Sopenharmony_ci} 4936b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_FP_FP16_SCALAR(fcvtnu, Conversions) 4937b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_FP_FP16_SCALAR(fcvtmu, Conversions) 4938b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_FP_FP16_SCALAR(fcvtau, Conversions) 4939b8021494Sopenharmony_ci// UCVTF (vector, integer) covered by UCVTF(vector, fixed point) with fbits 0. 4940b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_FP_SCALAR_HSD(fcmge, Basic, Zero) 4941b8021494Sopenharmony_ciDEFINE_TEST_NEON_2OPIMM_FP_SCALAR_HSD(fcmle, Basic, Zero) 4942b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_FP_FP16_SCALAR(fcvtpu, Conversions) 4943b8021494Sopenharmony_ci// FCVTZU(vector, integer) covered by FCVTZU(vector, fixed point) with fbits 0. 4944b8021494Sopenharmony_ciDEFINE_TEST_NEON_2SAME_FP_FP16_SCALAR(frsqrte, Basic) 4945b8021494Sopenharmony_ci 4946b8021494Sopenharmony_ci 4947b8021494Sopenharmony_ci// Advanced SIMD across lanes. 4948b8021494Sopenharmony_ciDEFINE_TEST_NEON_ACROSS_LONG(saddlv, Basic) 4949b8021494Sopenharmony_ciDEFINE_TEST_NEON_ACROSS(smaxv, Basic) 4950b8021494Sopenharmony_ciDEFINE_TEST_NEON_ACROSS(sminv, Basic) 4951b8021494Sopenharmony_ciDEFINE_TEST_NEON_ACROSS(addv, Basic) 4952b8021494Sopenharmony_ciDEFINE_TEST_NEON_ACROSS_LONG(uaddlv, Basic) 4953b8021494Sopenharmony_ciDEFINE_TEST_NEON_ACROSS(umaxv, Basic) 4954b8021494Sopenharmony_ciDEFINE_TEST_NEON_ACROSS(uminv, Basic) 4955b8021494Sopenharmony_ciDEFINE_TEST_NEON_ACROSS_FP(fmaxnmv, Basic) 4956b8021494Sopenharmony_ciDEFINE_TEST_NEON_ACROSS_FP(fmaxv, Basic) 4957b8021494Sopenharmony_ciDEFINE_TEST_NEON_ACROSS_FP(fminnmv, Basic) 4958b8021494Sopenharmony_ciDEFINE_TEST_NEON_ACROSS_FP(fminv, Basic) 4959b8021494Sopenharmony_ci 4960b8021494Sopenharmony_ci 4961b8021494Sopenharmony_ci// Advanced SIMD permute. 4962b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME(uzp1, Basic) 4963b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME(trn1, Basic) 4964b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME(zip1, Basic) 4965b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME(uzp2, Basic) 4966b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME(trn2, Basic) 4967b8021494Sopenharmony_ciDEFINE_TEST_NEON_3SAME(zip2, Basic) 4968b8021494Sopenharmony_ci 4969b8021494Sopenharmony_ci 4970b8021494Sopenharmony_ci// Advanced SIMD vector x indexed element. 4971b8021494Sopenharmony_ciDEFINE_TEST_NEON_BYELEMENT_DIFF(smlal, Basic, Basic, Basic) 4972b8021494Sopenharmony_ciDEFINE_TEST_NEON_BYELEMENT_DIFF(sqdmlal, Basic, Basic, Basic) 4973b8021494Sopenharmony_ciDEFINE_TEST_NEON_BYELEMENT_DIFF(smlsl, Basic, Basic, Basic) 4974b8021494Sopenharmony_ciDEFINE_TEST_NEON_BYELEMENT_DIFF(sqdmlsl, Basic, Basic, Basic) 4975b8021494Sopenharmony_ciDEFINE_TEST_NEON_BYELEMENT(mul, Basic, Basic, Basic) 4976b8021494Sopenharmony_ciDEFINE_TEST_NEON_BYELEMENT_DIFF(smull, Basic, Basic, Basic) 4977b8021494Sopenharmony_ciDEFINE_TEST_NEON_BYELEMENT_DIFF(sqdmull, Basic, Basic, Basic) 4978b8021494Sopenharmony_ciDEFINE_TEST_NEON_BYELEMENT(sqdmulh, Basic, Basic, Basic) 4979b8021494Sopenharmony_ciDEFINE_TEST_NEON_BYELEMENT(sqrdmulh, Basic, Basic, Basic) 4980b8021494Sopenharmony_ciDEFINE_TEST_NEON_BYELEMENT(sqrdmlah, Basic, Basic, Basic) 4981b8021494Sopenharmony_ciDEFINE_TEST_NEON_BYELEMENT(sqrdmlsh, Basic, Basic, Basic) 4982b8021494Sopenharmony_ciDEFINE_TEST_NEON_BYELEMENT_DOT_PRODUCT(udot, Basic, Basic, Basic) 4983b8021494Sopenharmony_ciDEFINE_TEST_NEON_BYELEMENT_DOT_PRODUCT(sdot, Basic, Basic, Basic) 4984b8021494Sopenharmony_ciDEFINE_TEST_NEON_FP_BYELEMENT(fmla, Basic, Basic, Basic) 4985b8021494Sopenharmony_ciDEFINE_TEST_NEON_FP_BYELEMENT(fmls, Basic, Basic, Basic) 4986b8021494Sopenharmony_ciDEFINE_TEST_NEON_FP_BYELEMENT(fmul, Basic, Basic, Basic) 4987b8021494Sopenharmony_ciDEFINE_TEST_NEON_BYELEMENT(mla, Basic, Basic, Basic) 4988b8021494Sopenharmony_ciDEFINE_TEST_NEON_BYELEMENT_DIFF(umlal, Basic, Basic, Basic) 4989b8021494Sopenharmony_ciDEFINE_TEST_NEON_BYELEMENT(mls, Basic, Basic, Basic) 4990b8021494Sopenharmony_ciDEFINE_TEST_NEON_BYELEMENT_DIFF(umlsl, Basic, Basic, Basic) 4991b8021494Sopenharmony_ciDEFINE_TEST_NEON_BYELEMENT_DIFF(umull, Basic, Basic, Basic) 4992b8021494Sopenharmony_ciDEFINE_TEST_NEON_FP_BYELEMENT(fmulx, Basic, Basic, Basic) 4993b8021494Sopenharmony_ci 4994b8021494Sopenharmony_ci 4995b8021494Sopenharmony_ci// Advanced SIMD scalar x indexed element. 4996b8021494Sopenharmony_ciDEFINE_TEST_NEON_BYELEMENT_DIFF_SCALAR(sqdmlal, Basic, Basic, Basic) 4997b8021494Sopenharmony_ciDEFINE_TEST_NEON_BYELEMENT_DIFF_SCALAR(sqdmlsl, Basic, Basic, Basic) 4998b8021494Sopenharmony_ciDEFINE_TEST_NEON_BYELEMENT_DIFF_SCALAR(sqdmull, Basic, Basic, Basic) 4999b8021494Sopenharmony_ciDEFINE_TEST_NEON_BYELEMENT_SCALAR(sqdmulh, Basic, Basic, Basic) 5000b8021494Sopenharmony_ciDEFINE_TEST_NEON_BYELEMENT_SCALAR(sqrdmulh, Basic, Basic, Basic) 5001b8021494Sopenharmony_ciDEFINE_TEST_NEON_BYELEMENT_SCALAR(sqrdmlah, Basic, Basic, Basic) 5002b8021494Sopenharmony_ciDEFINE_TEST_NEON_BYELEMENT_SCALAR(sqrdmlsh, Basic, Basic, Basic) 5003b8021494Sopenharmony_ciDEFINE_TEST_NEON_FP_BYELEMENT_SCALAR(fmla, Basic, Basic, Basic) 5004b8021494Sopenharmony_ciDEFINE_TEST_NEON_FP_BYELEMENT_SCALAR(fmls, Basic, Basic, Basic) 5005b8021494Sopenharmony_ciDEFINE_TEST_NEON_FP_BYELEMENT_SCALAR(fmul, Basic, Basic, Basic) 5006b8021494Sopenharmony_ciDEFINE_TEST_NEON_FP_BYELEMENT_SCALAR(fmulx, Basic, Basic, Basic) 5007b8021494Sopenharmony_ci 5008b8021494Sopenharmony_ci 5009b8021494Sopenharmony_ciDEFINE_TEST_NEON_FHM_BYELEMENT(fmlal, Basic, Basic, Basic) 5010b8021494Sopenharmony_ciDEFINE_TEST_NEON_FHM_BYELEMENT(fmlal2, Basic, Basic, Basic) 5011b8021494Sopenharmony_ciDEFINE_TEST_NEON_FHM_BYELEMENT(fmlsl, Basic, Basic, Basic) 5012b8021494Sopenharmony_ciDEFINE_TEST_NEON_FHM_BYELEMENT(fmlsl2, Basic, Basic, Basic) 5013b8021494Sopenharmony_ci 5014b8021494Sopenharmony_ci 5015b8021494Sopenharmony_ci#undef __ 5016b8021494Sopenharmony_ci#define __ masm-> 5017b8021494Sopenharmony_ci 5018b8021494Sopenharmony_ci#if defined(VIXL_INCLUDE_SIMULATOR_AARCH64) && \ 5019b8021494Sopenharmony_ci defined(VIXL_HAS_ABI_SUPPORT) && __cplusplus >= 201103L && \ 5020b8021494Sopenharmony_ci (defined(__clang__) || GCC_VERSION_OR_NEWER(4, 9, 1)) 5021b8021494Sopenharmony_ci 5022b8021494Sopenharmony_ci// Generate a function that stores zero to a hard-coded address. 5023b8021494Sopenharmony_ciInstruction* GenerateStoreZero(MacroAssembler* masm, int32_t* target) { 5024b8021494Sopenharmony_ci masm->Reset(); 5025b8021494Sopenharmony_ci 5026b8021494Sopenharmony_ci UseScratchRegisterScope temps(masm); 5027b8021494Sopenharmony_ci Register temp = temps.AcquireX(); 5028b8021494Sopenharmony_ci __ Mov(temp, reinterpret_cast<intptr_t>(target)); 5029b8021494Sopenharmony_ci __ Str(wzr, MemOperand(temp)); 5030b8021494Sopenharmony_ci __ Ret(); 5031b8021494Sopenharmony_ci 5032b8021494Sopenharmony_ci masm->FinalizeCode(); 5033b8021494Sopenharmony_ci return masm->GetBuffer()->GetStartAddress<Instruction*>(); 5034b8021494Sopenharmony_ci} 5035b8021494Sopenharmony_ci 5036b8021494Sopenharmony_ci 5037b8021494Sopenharmony_ci// Generate a function that stores the `int32_t` argument to a hard-coded 5038b8021494Sopenharmony_ci// address. 5039b8021494Sopenharmony_ci// In this example and the other below, we use the `abi` object to retrieve 5040b8021494Sopenharmony_ci// argument and return locations even though we could easily hard code them. 5041b8021494Sopenharmony_ci// This mirrors how more generic code (e.g. templated) user would use these 5042b8021494Sopenharmony_ci// mechanisms. 5043b8021494Sopenharmony_ciInstruction* GenerateStoreInput(MacroAssembler* masm, int32_t* target) { 5044b8021494Sopenharmony_ci masm->Reset(); 5045b8021494Sopenharmony_ci 5046b8021494Sopenharmony_ci ABI abi; 5047b8021494Sopenharmony_ci Register input = 5048b8021494Sopenharmony_ci Register(abi.GetNextParameterGenericOperand<int32_t>().GetCPURegister()); 5049b8021494Sopenharmony_ci 5050b8021494Sopenharmony_ci UseScratchRegisterScope temps(masm); 5051b8021494Sopenharmony_ci Register temp = temps.AcquireX(); 5052b8021494Sopenharmony_ci __ Mov(temp, reinterpret_cast<intptr_t>(target)); 5053b8021494Sopenharmony_ci __ Str(input, MemOperand(temp)); 5054b8021494Sopenharmony_ci __ Ret(); 5055b8021494Sopenharmony_ci 5056b8021494Sopenharmony_ci masm->FinalizeCode(); 5057b8021494Sopenharmony_ci return masm->GetBuffer()->GetStartAddress<Instruction*>(); 5058b8021494Sopenharmony_ci} 5059b8021494Sopenharmony_ci 5060b8021494Sopenharmony_ci 5061b8021494Sopenharmony_ci// A minimal implementation of a `pow` function. 5062b8021494Sopenharmony_ciInstruction* GeneratePow(MacroAssembler* masm, unsigned pow) { 5063b8021494Sopenharmony_ci masm->Reset(); 5064b8021494Sopenharmony_ci 5065b8021494Sopenharmony_ci ABI abi; 5066b8021494Sopenharmony_ci Register input = 5067b8021494Sopenharmony_ci Register(abi.GetNextParameterGenericOperand<int64_t>().GetCPURegister()); 5068b8021494Sopenharmony_ci Register result = 5069b8021494Sopenharmony_ci Register(abi.GetReturnGenericOperand<int64_t>().GetCPURegister()); 5070b8021494Sopenharmony_ci UseScratchRegisterScope temps(masm); 5071b8021494Sopenharmony_ci Register temp = temps.AcquireX(); 5072b8021494Sopenharmony_ci 5073b8021494Sopenharmony_ci __ Mov(temp, 1); 5074b8021494Sopenharmony_ci for (unsigned i = 0; i < pow; i++) { 5075b8021494Sopenharmony_ci __ Mul(temp, temp, input); 5076b8021494Sopenharmony_ci } 5077b8021494Sopenharmony_ci __ Mov(result, temp); 5078b8021494Sopenharmony_ci __ Ret(); 5079b8021494Sopenharmony_ci 5080b8021494Sopenharmony_ci masm->FinalizeCode(); 5081b8021494Sopenharmony_ci return masm->GetBuffer()->GetStartAddress<Instruction*>(); 5082b8021494Sopenharmony_ci} 5083b8021494Sopenharmony_ci 5084b8021494Sopenharmony_ci 5085b8021494Sopenharmony_ciInstruction* GenerateSum(MacroAssembler* masm) { 5086b8021494Sopenharmony_ci masm->Reset(); 5087b8021494Sopenharmony_ci 5088b8021494Sopenharmony_ci ABI abi; 5089b8021494Sopenharmony_ci VRegister input_1 = 5090b8021494Sopenharmony_ci VRegister(abi.GetNextParameterGenericOperand<float>().GetCPURegister()); 5091b8021494Sopenharmony_ci Register input_2 = 5092b8021494Sopenharmony_ci Register(abi.GetNextParameterGenericOperand<int64_t>().GetCPURegister()); 5093b8021494Sopenharmony_ci VRegister input_3 = 5094b8021494Sopenharmony_ci VRegister(abi.GetNextParameterGenericOperand<double>().GetCPURegister()); 5095b8021494Sopenharmony_ci VRegister result = 5096b8021494Sopenharmony_ci VRegister(abi.GetReturnGenericOperand<double>().GetCPURegister()); 5097b8021494Sopenharmony_ci 5098b8021494Sopenharmony_ci UseScratchRegisterScope temps(masm); 5099b8021494Sopenharmony_ci VRegister temp = temps.AcquireD(); 5100b8021494Sopenharmony_ci 5101b8021494Sopenharmony_ci __ Fcvt(input_1.D(), input_1); 5102b8021494Sopenharmony_ci __ Scvtf(temp, input_2); 5103b8021494Sopenharmony_ci __ Fadd(temp, temp, input_1.D()); 5104b8021494Sopenharmony_ci __ Fadd(result, temp, input_3); 5105b8021494Sopenharmony_ci __ Ret(); 5106b8021494Sopenharmony_ci 5107b8021494Sopenharmony_ci masm->FinalizeCode(); 5108b8021494Sopenharmony_ci return masm->GetBuffer()->GetStartAddress<Instruction*>(); 5109b8021494Sopenharmony_ci} 5110b8021494Sopenharmony_ci 5111b8021494Sopenharmony_ci 5112b8021494Sopenharmony_ciTEST(RunFrom) { 5113b8021494Sopenharmony_ci SETUP_WITH_FEATURES(CPUFeatures::kFP); 5114b8021494Sopenharmony_ci 5115b8021494Sopenharmony_ci // Run a function returning `void` and taking no argument. 5116b8021494Sopenharmony_ci int32_t value = 0xbad; 5117b8021494Sopenharmony_ci simulator.RunFrom(GenerateStoreZero(&masm, &value)); 5118b8021494Sopenharmony_ci VIXL_CHECK(value == 0); 5119b8021494Sopenharmony_ci 5120b8021494Sopenharmony_ci // Run a function returning `void` and taking one argument. 5121b8021494Sopenharmony_ci int32_t argument = 0xf00d; 5122b8021494Sopenharmony_ci simulator.RunFrom<void, int32_t>(GenerateStoreInput(&masm, &value), argument); 5123b8021494Sopenharmony_ci VIXL_CHECK(value == 0xf00d); 5124b8021494Sopenharmony_ci 5125b8021494Sopenharmony_ci // Run a function taking one argument and returning a value. 5126b8021494Sopenharmony_ci int64_t res_int64_t; 5127b8021494Sopenharmony_ci res_int64_t = 5128b8021494Sopenharmony_ci simulator.RunFrom<int64_t, int64_t>(GeneratePow(&masm, 0), 0xbad); 5129b8021494Sopenharmony_ci VIXL_CHECK(res_int64_t == 1); 5130b8021494Sopenharmony_ci res_int64_t = simulator.RunFrom<int64_t, int64_t>(GeneratePow(&masm, 1), 123); 5131b8021494Sopenharmony_ci VIXL_CHECK(res_int64_t == 123); 5132b8021494Sopenharmony_ci res_int64_t = simulator.RunFrom<int64_t, int64_t>(GeneratePow(&masm, 10), 2); 5133b8021494Sopenharmony_ci VIXL_CHECK(res_int64_t == 1024); 5134b8021494Sopenharmony_ci 5135b8021494Sopenharmony_ci // Run a function taking multiple arguments in registers. 5136b8021494Sopenharmony_ci double res_double = 5137b8021494Sopenharmony_ci simulator.RunFrom<double, float, int64_t, double>(GenerateSum(&masm), 5138b8021494Sopenharmony_ci 1.0, 5139b8021494Sopenharmony_ci 2, 5140b8021494Sopenharmony_ci 3.0); 5141b8021494Sopenharmony_ci VIXL_CHECK(res_double == 6.0); 5142b8021494Sopenharmony_ci} 5143b8021494Sopenharmony_ci#endif 5144b8021494Sopenharmony_ci 5145b8021494Sopenharmony_ci 5146b8021494Sopenharmony_ci} // namespace aarch64 5147b8021494Sopenharmony_ci} // namespace vixl 5148