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