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