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