1b8021494Sopenharmony_ci// Copyright 2019, 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// Test infrastructure.
27b8021494Sopenharmony_ci//
28b8021494Sopenharmony_ci// Tests are functions which accept no parameters and have no return values.
29b8021494Sopenharmony_ci// The testing code should not perform an explicit return once completed. For
30b8021494Sopenharmony_ci// example to test the mov immediate instruction a very simple test would be:
31b8021494Sopenharmony_ci//
32b8021494Sopenharmony_ci//   TEST(mov_x0_one) {
33b8021494Sopenharmony_ci//     SETUP();
34b8021494Sopenharmony_ci//
35b8021494Sopenharmony_ci//     START();
36b8021494Sopenharmony_ci//     __ mov(x0, 1);
37b8021494Sopenharmony_ci//     END();
38b8021494Sopenharmony_ci//
39b8021494Sopenharmony_ci//     if (CAN_RUN()) {
40b8021494Sopenharmony_ci//       RUN();
41b8021494Sopenharmony_ci//
42b8021494Sopenharmony_ci//       ASSERT_EQUAL_64(1, x0);
43b8021494Sopenharmony_ci//     }
44b8021494Sopenharmony_ci//   }
45b8021494Sopenharmony_ci//
46b8021494Sopenharmony_ci// Within a START ... END block all registers but sp can be modified. sp has to
47b8021494Sopenharmony_ci// be explicitly saved/restored. The END() macro replaces the function return
48b8021494Sopenharmony_ci// so it may appear multiple times in a test if the test has multiple exit
49b8021494Sopenharmony_ci// points.
50b8021494Sopenharmony_ci//
51b8021494Sopenharmony_ci// Tests requiring specific CPU features should specify exactly what they
52b8021494Sopenharmony_ci// require using SETUP_WITH_FEATURES(...) instead of SETUP().
53b8021494Sopenharmony_ci//
54b8021494Sopenharmony_ci// Once the test has been run all integer and floating point registers as well
55b8021494Sopenharmony_ci// as flags are accessible through a RegisterDump instance, see
56b8021494Sopenharmony_ci// utils-aarch64.cc for more info on RegisterDump.
57b8021494Sopenharmony_ci//
58b8021494Sopenharmony_ci// We provide some helper assert to handle common cases:
59b8021494Sopenharmony_ci//
60b8021494Sopenharmony_ci//   ASSERT_EQUAL_32(int32_t, int_32t)
61b8021494Sopenharmony_ci//   ASSERT_EQUAL_FP32(float, float)
62b8021494Sopenharmony_ci//   ASSERT_EQUAL_32(int32_t, W register)
63b8021494Sopenharmony_ci//   ASSERT_EQUAL_FP32(float, S register)
64b8021494Sopenharmony_ci//   ASSERT_EQUAL_64(int64_t, int_64t)
65b8021494Sopenharmony_ci//   ASSERT_EQUAL_FP64(double, double)
66b8021494Sopenharmony_ci//   ASSERT_EQUAL_64(int64_t, X register)
67b8021494Sopenharmony_ci//   ASSERT_EQUAL_64(X register, X register)
68b8021494Sopenharmony_ci//   ASSERT_EQUAL_FP64(double, D register)
69b8021494Sopenharmony_ci//
70b8021494Sopenharmony_ci// e.g. ASSERT_EQUAL_64(0.5, d30);
71b8021494Sopenharmony_ci//
72b8021494Sopenharmony_ci// If more advanced computation is required before the assert then access the
73b8021494Sopenharmony_ci// RegisterDump named core directly:
74b8021494Sopenharmony_ci//
75b8021494Sopenharmony_ci//   ASSERT_EQUAL_64(0x1234, core->reg_x0() & 0xffff);
76b8021494Sopenharmony_ci
77b8021494Sopenharmony_cinamespace vixl {
78b8021494Sopenharmony_cinamespace aarch64 {
79b8021494Sopenharmony_ci
80b8021494Sopenharmony_ci#define __ masm.
81b8021494Sopenharmony_ci#define TEST(name) TEST_(AARCH64_ASM_##name)
82b8021494Sopenharmony_ci
83b8021494Sopenharmony_ci#ifdef VIXL_INCLUDE_SIMULATOR_AARCH64
84b8021494Sopenharmony_ci// Run tests with the simulator.
85b8021494Sopenharmony_ci
86b8021494Sopenharmony_ci#define SETUP()        \
87b8021494Sopenharmony_ci  MacroAssembler masm; \
88b8021494Sopenharmony_ci  SETUP_COMMON();      \
89b8021494Sopenharmony_ci  SETUP_COMMON_SIM()
90b8021494Sopenharmony_ci
91b8021494Sopenharmony_ci#define SETUP_WITH_FEATURES(...)                 \
92b8021494Sopenharmony_ci  MacroAssembler masm;                           \
93b8021494Sopenharmony_ci  SETUP_COMMON();                                \
94b8021494Sopenharmony_ci  SETUP_COMMON_SIM();                            \
95b8021494Sopenharmony_ci  masm.SetCPUFeatures(CPUFeatures(__VA_ARGS__)); \
96b8021494Sopenharmony_ci  simulator.SetCPUFeatures(CPUFeatures(__VA_ARGS__))
97b8021494Sopenharmony_ci
98b8021494Sopenharmony_ci#define SETUP_CUSTOM(size, pic)                                  \
99b8021494Sopenharmony_ci  MacroAssembler masm(size + CodeBuffer::kDefaultCapacity, pic); \
100b8021494Sopenharmony_ci  SETUP_COMMON();                                                \
101b8021494Sopenharmony_ci  SETUP_COMMON_SIM()
102b8021494Sopenharmony_ci
103b8021494Sopenharmony_ci#define SETUP_CUSTOM_SIM(...)                                   \
104b8021494Sopenharmony_ci  MacroAssembler masm;                                          \
105b8021494Sopenharmony_ci  SETUP_COMMON();                                               \
106b8021494Sopenharmony_ci  Simulator simulator(&simulator_decoder, stdout, __VA_ARGS__); \
107b8021494Sopenharmony_ci  simulator.SetColouredTrace(Test::coloured_trace());           \
108b8021494Sopenharmony_ci  simulator.SetCPUFeatures(CPUFeatures::None())
109b8021494Sopenharmony_ci
110b8021494Sopenharmony_ci#define SETUP_COMMON()                                                   \
111b8021494Sopenharmony_ci  bool queried_can_run = false;                                          \
112b8021494Sopenharmony_ci  bool printed_sve_lane_warning = false;                                 \
113b8021494Sopenharmony_ci  /* Avoid unused-variable warnings in case a test never calls RUN(). */ \
114b8021494Sopenharmony_ci  USE(queried_can_run);                                                  \
115b8021494Sopenharmony_ci  USE(printed_sve_lane_warning);                                         \
116b8021494Sopenharmony_ci  masm.SetCPUFeatures(CPUFeatures::None());                              \
117b8021494Sopenharmony_ci  masm.SetGenerateSimulatorCode(true);                                   \
118b8021494Sopenharmony_ci  Decoder simulator_decoder;                                             \
119b8021494Sopenharmony_ci  RegisterDump core;                                                     \
120b8021494Sopenharmony_ci  ptrdiff_t offset_after_infrastructure_start;                           \
121b8021494Sopenharmony_ci  ptrdiff_t offset_before_infrastructure_end
122b8021494Sopenharmony_ci
123b8021494Sopenharmony_ci#define SETUP_COMMON_SIM()                            \
124b8021494Sopenharmony_ci  Simulator simulator(&simulator_decoder);            \
125b8021494Sopenharmony_ci  simulator.SetColouredTrace(Test::coloured_trace()); \
126b8021494Sopenharmony_ci  simulator.SetCPUFeatures(CPUFeatures::None())
127b8021494Sopenharmony_ci
128b8021494Sopenharmony_ci#define START()                                                               \
129b8021494Sopenharmony_ci  masm.Reset();                                                               \
130b8021494Sopenharmony_ci  simulator.ResetState();                                                     \
131b8021494Sopenharmony_ci  {                                                                           \
132b8021494Sopenharmony_ci    SimulationCPUFeaturesScope cpu(&masm, kInfrastructureCPUFeatures);        \
133b8021494Sopenharmony_ci    __ PushCalleeSavedRegisters();                                            \
134b8021494Sopenharmony_ci  }                                                                           \
135b8021494Sopenharmony_ci  /* The infrastructure code hasn't been covered at the moment, e.g. */       \
136b8021494Sopenharmony_ci  /* prologue/epilogue. Suppress tagging mis-match exception before  */       \
137b8021494Sopenharmony_ci  /* this point. */                                                           \
138b8021494Sopenharmony_ci  if (masm.GetCPUFeatures()->Has(CPUFeatures::kMTE)) {                        \
139b8021494Sopenharmony_ci    __ Hlt(DebugHltOpcode::kMTEActive);                                       \
140b8021494Sopenharmony_ci  }                                                                           \
141b8021494Sopenharmony_ci  {                                                                           \
142b8021494Sopenharmony_ci    int trace_parameters = 0;                                                 \
143b8021494Sopenharmony_ci    if (Test::trace_reg()) trace_parameters |= LOG_STATE;                     \
144b8021494Sopenharmony_ci    if (Test::trace_write()) trace_parameters |= LOG_WRITE;                   \
145b8021494Sopenharmony_ci    if (Test::trace_sim()) trace_parameters |= LOG_DISASM;                    \
146b8021494Sopenharmony_ci    if (Test::trace_branch()) trace_parameters |= LOG_BRANCH;                 \
147b8021494Sopenharmony_ci    if (trace_parameters != 0) {                                              \
148b8021494Sopenharmony_ci      __ Trace(static_cast<TraceParameters>(trace_parameters), TRACE_ENABLE); \
149b8021494Sopenharmony_ci    }                                                                         \
150b8021494Sopenharmony_ci  }                                                                           \
151b8021494Sopenharmony_ci  offset_after_infrastructure_start = masm.GetCursorOffset();                 \
152b8021494Sopenharmony_ci  /* Avoid unused-variable warnings in case a test never calls RUN(). */      \
153b8021494Sopenharmony_ci  USE(offset_after_infrastructure_start)
154b8021494Sopenharmony_ci
155b8021494Sopenharmony_ci#define END()                                                            \
156b8021494Sopenharmony_ci  offset_before_infrastructure_end = masm.GetCursorOffset();             \
157b8021494Sopenharmony_ci  /* Avoid unused-variable warnings in case a test never calls RUN(). */ \
158b8021494Sopenharmony_ci  USE(offset_before_infrastructure_end);                                 \
159b8021494Sopenharmony_ci  __ Trace(LOG_ALL, TRACE_DISABLE);                                      \
160b8021494Sopenharmony_ci  if (masm.GetCPUFeatures()->Has(CPUFeatures::kMTE)) {                   \
161b8021494Sopenharmony_ci    __ Hlt(DebugHltOpcode::kMTEInactive);                                \
162b8021494Sopenharmony_ci  }                                                                      \
163b8021494Sopenharmony_ci  {                                                                      \
164b8021494Sopenharmony_ci    SimulationCPUFeaturesScope cpu(&masm, kInfrastructureCPUFeatures);   \
165b8021494Sopenharmony_ci    core.Dump(&masm);                                                    \
166b8021494Sopenharmony_ci    __ PopCalleeSavedRegisters();                                        \
167b8021494Sopenharmony_ci  }                                                                      \
168b8021494Sopenharmony_ci  __ Ret();                                                              \
169b8021494Sopenharmony_ci  masm.FinalizeCode()
170b8021494Sopenharmony_ci
171b8021494Sopenharmony_ci#define RUN()                                                                  \
172b8021494Sopenharmony_ci  RUN_WITHOUT_SEEN_FEATURE_CHECK();                                            \
173b8021494Sopenharmony_ci  {                                                                            \
174b8021494Sopenharmony_ci    /* We expect the test to use all of the features it requested, plus the */ \
175b8021494Sopenharmony_ci    /* features that the instruction code requires.                         */ \
176b8021494Sopenharmony_ci    CPUFeatures const& expected_features =                                     \
177b8021494Sopenharmony_ci        simulator.GetCPUFeatures()->With(CPUFeatures::kNEON);                  \
178b8021494Sopenharmony_ci    CPUFeatures const& seen = simulator.GetSeenFeatures();                     \
179b8021494Sopenharmony_ci    /* This gives three broad categories of features that we care about:    */ \
180b8021494Sopenharmony_ci    /*  1. Things both expected and seen.                                   */ \
181b8021494Sopenharmony_ci    /*  2. Things seen, but not expected. The simulator catches these.      */ \
182b8021494Sopenharmony_ci    /*  3. Things expected, but not seen. We check these here.              */ \
183b8021494Sopenharmony_ci    /* In a valid, passing test, categories 2 and 3 should be empty.        */ \
184b8021494Sopenharmony_ci    if (seen != expected_features) {                                           \
185b8021494Sopenharmony_ci      /* The Simulator should have caught anything in category 2 already.   */ \
186b8021494Sopenharmony_ci      VIXL_ASSERT(expected_features.Has(seen));                                \
187b8021494Sopenharmony_ci      /* Anything left is category 3: things expected, but not seen. This   */ \
188b8021494Sopenharmony_ci      /* is not necessarily a bug in VIXL itself, but indicates that the    */ \
189b8021494Sopenharmony_ci      /* test is less strict than it could be.                              */ \
190b8021494Sopenharmony_ci      CPUFeatures missing = expected_features.Without(seen);                   \
191b8021494Sopenharmony_ci      VIXL_ASSERT(missing.Count() > 0);                                        \
192b8021494Sopenharmony_ci      std::cout << "Error: expected to see CPUFeatures { " << missing          \
193b8021494Sopenharmony_ci                << " }\n";                                                     \
194b8021494Sopenharmony_ci      VIXL_ABORT();                                                            \
195b8021494Sopenharmony_ci    }                                                                          \
196b8021494Sopenharmony_ci  }
197b8021494Sopenharmony_ci
198b8021494Sopenharmony_ci#define RUN_WITHOUT_SEEN_FEATURE_CHECK() \
199b8021494Sopenharmony_ci  DISASSEMBLE();                         \
200b8021494Sopenharmony_ci  VIXL_ASSERT(QUERIED_CAN_RUN());        \
201b8021494Sopenharmony_ci  VIXL_ASSERT(CAN_RUN());                \
202b8021494Sopenharmony_ci  simulator.RunFrom(masm.GetBuffer()->GetStartAddress<Instruction*>())
203b8021494Sopenharmony_ci
204b8021494Sopenharmony_ci#else  // ifdef VIXL_INCLUDE_SIMULATOR_AARCH64.
205b8021494Sopenharmony_ci#define SETUP()        \
206b8021494Sopenharmony_ci  MacroAssembler masm; \
207b8021494Sopenharmony_ci  SETUP_COMMON()
208b8021494Sopenharmony_ci
209b8021494Sopenharmony_ci#define SETUP_WITH_FEATURES(...) \
210b8021494Sopenharmony_ci  MacroAssembler masm;           \
211b8021494Sopenharmony_ci  SETUP_COMMON();                \
212b8021494Sopenharmony_ci  masm.SetCPUFeatures(CPUFeatures(__VA_ARGS__))
213b8021494Sopenharmony_ci
214b8021494Sopenharmony_ci#define SETUP_CUSTOM(size, pic)                             \
215b8021494Sopenharmony_ci  size_t buffer_size = size + CodeBuffer::kDefaultCapacity; \
216b8021494Sopenharmony_ci  MacroAssembler masm(buffer_size, pic);                    \
217b8021494Sopenharmony_ci  SETUP_COMMON()
218b8021494Sopenharmony_ci
219b8021494Sopenharmony_ci#define SETUP_COMMON()                                                   \
220b8021494Sopenharmony_ci  bool queried_can_run = false;                                          \
221b8021494Sopenharmony_ci  bool printed_sve_lane_warning = false;                                 \
222b8021494Sopenharmony_ci  /* Avoid unused-variable warnings in case a test never calls RUN(). */ \
223b8021494Sopenharmony_ci  USE(queried_can_run);                                                  \
224b8021494Sopenharmony_ci  USE(printed_sve_lane_warning);                                         \
225b8021494Sopenharmony_ci  masm.SetCPUFeatures(CPUFeatures::None());                              \
226b8021494Sopenharmony_ci  masm.SetGenerateSimulatorCode(false);                                  \
227b8021494Sopenharmony_ci  RegisterDump core;                                                     \
228b8021494Sopenharmony_ci  CPU::SetUp();                                                          \
229b8021494Sopenharmony_ci  ptrdiff_t offset_after_infrastructure_start;                           \
230b8021494Sopenharmony_ci  ptrdiff_t offset_before_infrastructure_end
231b8021494Sopenharmony_ci
232b8021494Sopenharmony_ci#define START()                                                          \
233b8021494Sopenharmony_ci  masm.Reset();                                                          \
234b8021494Sopenharmony_ci  {                                                                      \
235b8021494Sopenharmony_ci    CPUFeaturesScope cpu(&masm, kInfrastructureCPUFeatures);             \
236b8021494Sopenharmony_ci    __ PushCalleeSavedRegisters();                                       \
237b8021494Sopenharmony_ci  }                                                                      \
238b8021494Sopenharmony_ci  offset_after_infrastructure_start = masm.GetCursorOffset();            \
239b8021494Sopenharmony_ci  /* Avoid unused-variable warnings in case a test never calls RUN(). */ \
240b8021494Sopenharmony_ci  USE(offset_after_infrastructure_start)
241b8021494Sopenharmony_ci
242b8021494Sopenharmony_ci#define END()                                                            \
243b8021494Sopenharmony_ci  offset_before_infrastructure_end = masm.GetCursorOffset();             \
244b8021494Sopenharmony_ci  /* Avoid unused-variable warnings in case a test never calls RUN(). */ \
245b8021494Sopenharmony_ci  USE(offset_before_infrastructure_end);                                 \
246b8021494Sopenharmony_ci  {                                                                      \
247b8021494Sopenharmony_ci    CPUFeaturesScope cpu(&masm, kInfrastructureCPUFeatures);             \
248b8021494Sopenharmony_ci    core.Dump(&masm);                                                    \
249b8021494Sopenharmony_ci    __ PopCalleeSavedRegisters();                                        \
250b8021494Sopenharmony_ci  }                                                                      \
251b8021494Sopenharmony_ci  __ Ret();                                                              \
252b8021494Sopenharmony_ci  masm.FinalizeCode()
253b8021494Sopenharmony_ci
254b8021494Sopenharmony_ci// Execute the generated code from the memory area.
255b8021494Sopenharmony_ci#define RUN()                                               \
256b8021494Sopenharmony_ci  DISASSEMBLE();                                            \
257b8021494Sopenharmony_ci  VIXL_ASSERT(QUERIED_CAN_RUN());                           \
258b8021494Sopenharmony_ci  VIXL_ASSERT(CAN_RUN());                                   \
259b8021494Sopenharmony_ci  masm.GetBuffer()->SetExecutable();                        \
260b8021494Sopenharmony_ci  ExecuteMemory(masm.GetBuffer()->GetStartAddress<byte*>(), \
261b8021494Sopenharmony_ci                masm.GetSizeOfCodeGenerated());             \
262b8021494Sopenharmony_ci  masm.GetBuffer()->SetWritable()
263b8021494Sopenharmony_ci
264b8021494Sopenharmony_ci// This just provides compatibility with VIXL_INCLUDE_SIMULATOR_AARCH64 builds.
265b8021494Sopenharmony_ci// We cannot run seen-feature checks when running natively.
266b8021494Sopenharmony_ci#define RUN_WITHOUT_SEEN_FEATURE_CHECK() RUN()
267b8021494Sopenharmony_ci
268b8021494Sopenharmony_ci#endif  // ifdef VIXL_INCLUDE_SIMULATOR_AARCH64.
269b8021494Sopenharmony_ci
270b8021494Sopenharmony_ci#define CAN_RUN() CanRun(*masm.GetCPUFeatures(), &queried_can_run)
271b8021494Sopenharmony_ci#define QUERIED_CAN_RUN() (queried_can_run)
272b8021494Sopenharmony_ci
273b8021494Sopenharmony_ci#define DISASSEMBLE()                                                     \
274b8021494Sopenharmony_ci  if (Test::disassemble()) {                                              \
275b8021494Sopenharmony_ci    PrintDisassembler disasm(stdout);                                     \
276b8021494Sopenharmony_ci    CodeBuffer* buffer = masm.GetBuffer();                                \
277b8021494Sopenharmony_ci    Instruction* test_start = buffer->GetOffsetAddress<Instruction*>(     \
278b8021494Sopenharmony_ci        offset_after_infrastructure_start);                               \
279b8021494Sopenharmony_ci    Instruction* test_end = buffer->GetOffsetAddress<Instruction*>(       \
280b8021494Sopenharmony_ci        offset_before_infrastructure_end);                                \
281b8021494Sopenharmony_ci                                                                          \
282b8021494Sopenharmony_ci    if (Test::disassemble_infrastructure()) {                             \
283b8021494Sopenharmony_ci      Instruction* infra_start = buffer->GetStartAddress<Instruction*>(); \
284b8021494Sopenharmony_ci      printf("# Infrastructure code (prologue)\n");                       \
285b8021494Sopenharmony_ci      disasm.DisassembleBuffer(infra_start, test_start);                  \
286b8021494Sopenharmony_ci      printf("# Test code\n");                                            \
287b8021494Sopenharmony_ci    } else {                                                              \
288b8021494Sopenharmony_ci      printf(                                                             \
289b8021494Sopenharmony_ci          "# Warning: Omitting infrastructure code. "                     \
290b8021494Sopenharmony_ci          "Use --disassemble to see it.\n");                              \
291b8021494Sopenharmony_ci    }                                                                     \
292b8021494Sopenharmony_ci                                                                          \
293b8021494Sopenharmony_ci    disasm.DisassembleBuffer(test_start, test_end);                       \
294b8021494Sopenharmony_ci                                                                          \
295b8021494Sopenharmony_ci    if (Test::disassemble_infrastructure()) {                             \
296b8021494Sopenharmony_ci      printf("# Infrastructure code (epilogue)\n");                       \
297b8021494Sopenharmony_ci      Instruction* infra_end = buffer->GetEndAddress<Instruction*>();     \
298b8021494Sopenharmony_ci      disasm.DisassembleBuffer(test_end, infra_end);                      \
299b8021494Sopenharmony_ci    }                                                                     \
300b8021494Sopenharmony_ci  }
301b8021494Sopenharmony_ci
302b8021494Sopenharmony_ci#define ASSERT_EQUAL_NZCV(expected) \
303b8021494Sopenharmony_ci  VIXL_CHECK(EqualNzcv(expected, core.flags_nzcv()))
304b8021494Sopenharmony_ci
305b8021494Sopenharmony_ci#define ASSERT_EQUAL_REGISTERS(expected) \
306b8021494Sopenharmony_ci  VIXL_CHECK(EqualRegisters(&expected, &core))
307b8021494Sopenharmony_ci
308b8021494Sopenharmony_ci#define ASSERT_EQUAL_FP16(expected, result) \
309b8021494Sopenharmony_ci  VIXL_CHECK(EqualFP16(expected, &core, result))
310b8021494Sopenharmony_ci
311b8021494Sopenharmony_ci#define ASSERT_EQUAL_32(expected, result) \
312b8021494Sopenharmony_ci  VIXL_CHECK(Equal32(static_cast<uint32_t>(expected), &core, result))
313b8021494Sopenharmony_ci
314b8021494Sopenharmony_ci#define ASSERT_EQUAL_FP32(expected, result) \
315b8021494Sopenharmony_ci  VIXL_CHECK(EqualFP32(expected, &core, result))
316b8021494Sopenharmony_ci
317b8021494Sopenharmony_ci#define ASSERT_EQUAL_64(expected, result) \
318b8021494Sopenharmony_ci  VIXL_CHECK(Equal64(expected, &core, result))
319b8021494Sopenharmony_ci
320b8021494Sopenharmony_ci#define ASSERT_NOT_EQUAL_64(expected, result) \
321b8021494Sopenharmony_ci  VIXL_CHECK(NotEqual64(expected, &core, result))
322b8021494Sopenharmony_ci
323b8021494Sopenharmony_ci#define ASSERT_EQUAL_FP64(expected, result) \
324b8021494Sopenharmony_ci  VIXL_CHECK(EqualFP64(expected, &core, result))
325b8021494Sopenharmony_ci
326b8021494Sopenharmony_ci#define ASSERT_EQUAL_128(expected_h, expected_l, result) \
327b8021494Sopenharmony_ci  VIXL_CHECK(Equal128(expected_h, expected_l, &core, result))
328b8021494Sopenharmony_ci
329b8021494Sopenharmony_ci#define ASSERT_LITERAL_POOL_SIZE(expected) \
330b8021494Sopenharmony_ci  VIXL_CHECK((expected + kInstructionSize) == (masm.GetLiteralPoolSize()))
331b8021494Sopenharmony_ci
332b8021494Sopenharmony_ci#define ASSERT_EQUAL_SVE_LANE(expected, result, lane) \
333b8021494Sopenharmony_ci  VIXL_CHECK(EqualSVELane(expected, &core, result, lane));
334b8021494Sopenharmony_ci
335b8021494Sopenharmony_ci// If `expected` is scalar, check that every lane of `result` matches it.
336b8021494Sopenharmony_ci// If `expected` is an array of N expected values, check that the first N
337b8021494Sopenharmony_ci// lanes on `result` match. The rightmost (highest-indexed) array element maps
338b8021494Sopenharmony_ci// to the lowest-numbered lane.
339b8021494Sopenharmony_ci#define ASSERT_EQUAL_SVE(expected, result) \
340b8021494Sopenharmony_ci  VIXL_CHECK(EqualSVE(expected, &core, result, &printed_sve_lane_warning))
341b8021494Sopenharmony_ci
342b8021494Sopenharmony_ci#define ASSERT_EQUAL_MEMORY(expected, result, ...)          \
343b8021494Sopenharmony_ci  VIXL_CHECK(EqualMemory(reinterpret_cast<void*>(expected), \
344b8021494Sopenharmony_ci                         reinterpret_cast<void*>(result),   \
345b8021494Sopenharmony_ci                         __VA_ARGS__))
346b8021494Sopenharmony_ci
347b8021494Sopenharmony_ci#define MUST_FAIL_WITH_MESSAGE(code, message)                     \
348b8021494Sopenharmony_ci  {                                                               \
349b8021494Sopenharmony_ci    bool aborted = false;                                         \
350b8021494Sopenharmony_ci    try {                                                         \
351b8021494Sopenharmony_ci      code;                                                       \
352b8021494Sopenharmony_ci    } catch (const std::runtime_error& e) {                       \
353b8021494Sopenharmony_ci      const char* expected_error = message;                       \
354b8021494Sopenharmony_ci      size_t error_length = strlen(expected_error);               \
355b8021494Sopenharmony_ci      if (strncmp(expected_error, e.what(), error_length) == 0) { \
356b8021494Sopenharmony_ci        aborted = true;                                           \
357b8021494Sopenharmony_ci      } else {                                                    \
358b8021494Sopenharmony_ci        printf("Mismatch in error message.\n");                   \
359b8021494Sopenharmony_ci        printf("Expected: %s\n", expected_error);                 \
360b8021494Sopenharmony_ci        printf("Found:    %s\n", e.what());                       \
361b8021494Sopenharmony_ci      }                                                           \
362b8021494Sopenharmony_ci    }                                                             \
363b8021494Sopenharmony_ci    VIXL_CHECK(aborted);                                          \
364b8021494Sopenharmony_ci  }
365b8021494Sopenharmony_ci
366b8021494Sopenharmony_ci}  // namespace aarch64
367b8021494Sopenharmony_ci}  // namespace vixl
368