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