1*f5c631daSSadaf Ebrahimi// Copyright 2016, 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 27*f5c631daSSadaf Ebrahimi/// This file is a template read by tools/generate_tests.py, it isn't valid C++ 28*f5c631daSSadaf Ebrahimi/// as it is. Variables written as ${substitute_me} are replaced by the script. 29*f5c631daSSadaf Ebrahimi/// Comments starting with three forward slashes such as this one are also 30*f5c631daSSadaf Ebrahimi/// removed. 31*f5c631daSSadaf Ebrahimi 32*f5c631daSSadaf Ebrahimi${do_not_edit_comment} 33*f5c631daSSadaf Ebrahimi 34*f5c631daSSadaf Ebrahimi#include <iostream> 35*f5c631daSSadaf Ebrahimi#include <map> 36*f5c631daSSadaf Ebrahimi 37*f5c631daSSadaf Ebrahimi#include "test-runner.h" 38*f5c631daSSadaf Ebrahimi 39*f5c631daSSadaf Ebrahimi#include "test-utils.h" 40*f5c631daSSadaf Ebrahimi#include "test-utils-aarch32.h" 41*f5c631daSSadaf Ebrahimi 42*f5c631daSSadaf Ebrahimi#include "aarch32/assembler-aarch32.h" 43*f5c631daSSadaf Ebrahimi#include "aarch32/disasm-aarch32.h" 44*f5c631daSSadaf Ebrahimi#include "aarch32/macro-assembler-aarch32.h" 45*f5c631daSSadaf Ebrahimi 46*f5c631daSSadaf Ebrahimi#define BUF_SIZE (4096) 47*f5c631daSSadaf Ebrahimi 48*f5c631daSSadaf Ebrahiminamespace vixl { 49*f5c631daSSadaf Ebrahiminamespace aarch32 { 50*f5c631daSSadaf Ebrahimi 51*f5c631daSSadaf Ebrahimi// List of instruction mnemonics. 52*f5c631daSSadaf Ebrahimi#define FOREACH_INSTRUCTION(M) \ 53*f5c631daSSadaf Ebrahimi ${instruction_list_declaration} 54*f5c631daSSadaf Ebrahimi 55*f5c631daSSadaf Ebrahimi// The following definitions are defined again in each generated test, therefore 56*f5c631daSSadaf Ebrahimi// we need to place them in an anomymous namespace. It expresses that they are 57*f5c631daSSadaf Ebrahimi// local to this file only, and the compiler is not allowed to share these types 58*f5c631daSSadaf Ebrahimi// across test files during template instantiation. Specifically, `Operands` has 59*f5c631daSSadaf Ebrahimi// various layouts across generated tests so it absolutely cannot be shared. 60*f5c631daSSadaf Ebrahimi 61*f5c631daSSadaf Ebrahimi#ifdef ${isa_guard} 62*f5c631daSSadaf Ebrahiminamespace { 63*f5c631daSSadaf Ebrahimi 64*f5c631daSSadaf Ebrahimi// Values to be passed to the assembler to produce the instruction under test. 65*f5c631daSSadaf Ebrahimistruct Operands { 66*f5c631daSSadaf Ebrahimi ${operand_list_declaration} 67*f5c631daSSadaf Ebrahimi}; 68*f5c631daSSadaf Ebrahimi 69*f5c631daSSadaf Ebrahimi// This structure contains all data needed to test one specific 70*f5c631daSSadaf Ebrahimi// instruction. 71*f5c631daSSadaf Ebrahimistruct TestData { 72*f5c631daSSadaf Ebrahimi // The `operands` field represents what to pass to the assembler to 73*f5c631daSSadaf Ebrahimi // produce the instruction. 74*f5c631daSSadaf Ebrahimi Operands operands; 75*f5c631daSSadaf Ebrahimi // Description of the operands, used for error reporting. 76*f5c631daSSadaf Ebrahimi const char* operands_description; 77*f5c631daSSadaf Ebrahimi // Unique identifier, used for generating traces. 78*f5c631daSSadaf Ebrahimi const char* identifier; 79*f5c631daSSadaf Ebrahimi}; 80*f5c631daSSadaf Ebrahimi 81*f5c631daSSadaf Ebrahimi// Each element of this array produce one instruction encoding. 82*f5c631daSSadaf Ebrahimiconst TestData kTests[] = {${test_case_definitions}}; 83*f5c631daSSadaf Ebrahimi 84*f5c631daSSadaf Ebrahimitypedef void (MacroAssembler::*Fn)(${macroassembler_method_args}); 85*f5c631daSSadaf Ebrahimi 86*f5c631daSSadaf Ebrahimi// Use a customised disassembler to label test cases. 87*f5c631daSSadaf Ebrahimitypedef std::map<uint32_t, int> TestCaseSymbolMap; 88*f5c631daSSadaf Ebrahimi 89*f5c631daSSadaf Ebrahimiclass TestDisassembler : public PrintDisassembler { 90*f5c631daSSadaf Ebrahimi public: 91*f5c631daSSadaf Ebrahimi TestDisassembler(std::ostream& os, // NOLINT(runtime/references) 92*f5c631daSSadaf Ebrahimi const TestCaseSymbolMap& symbols, 93*f5c631daSSadaf Ebrahimi const char* mnemonic) 94*f5c631daSSadaf Ebrahimi : PrintDisassembler(os), symbols_(symbols), mnemonic_(mnemonic) {} 95*f5c631daSSadaf Ebrahimi 96*f5c631daSSadaf Ebrahimi virtual void PrintCodeAddress(uint32_t pc) VIXL_OVERRIDE { 97*f5c631daSSadaf Ebrahimi // Label test cases. 98*f5c631daSSadaf Ebrahimi TestCaseSymbolMap::const_iterator symbol = symbols_.find(pc); 99*f5c631daSSadaf Ebrahimi if (symbol != symbols_.end()) { 100*f5c631daSSadaf Ebrahimi int n = symbol->second; 101*f5c631daSSadaf Ebrahimi os().os() << "// " << mnemonic_ << "(" << 102*f5c631daSSadaf Ebrahimi kTests[n].operands_description << ")" << std::endl; 103*f5c631daSSadaf Ebrahimi } 104*f5c631daSSadaf Ebrahimi // Print the code address as normal. 105*f5c631daSSadaf Ebrahimi PrintDisassembler::PrintCodeAddress(pc); 106*f5c631daSSadaf Ebrahimi } 107*f5c631daSSadaf Ebrahimi 108*f5c631daSSadaf Ebrahimi private: 109*f5c631daSSadaf Ebrahimi const TestCaseSymbolMap& symbols_; 110*f5c631daSSadaf Ebrahimi const char* mnemonic_; 111*f5c631daSSadaf Ebrahimi}; 112*f5c631daSSadaf Ebrahimi 113*f5c631daSSadaf Ebrahimivoid TestHelper(Fn instruction, const char* mnemonic) { 114*f5c631daSSadaf Ebrahimi MacroAssembler masm(BUF_SIZE); 115*f5c631daSSadaf Ebrahimi 116*f5c631daSSadaf Ebrahimi ${macroassembler_set_isa} 117*f5c631daSSadaf Ebrahimi 118*f5c631daSSadaf Ebrahimi TestCaseSymbolMap symbols; 119*f5c631daSSadaf Ebrahimi 120*f5c631daSSadaf Ebrahimi for (unsigned i = 0; i < ARRAY_SIZE(kTests); i++) { 121*f5c631daSSadaf Ebrahimi if (Test::disassemble()) { 122*f5c631daSSadaf Ebrahimi // TODO: This will fail if the MacroAssembler generates no code. We can 123*f5c631daSSadaf Ebrahimi // fix this with multimap but then we must take care to print the labels 124*f5c631daSSadaf Ebrahimi // in the correct order. (Insertion order is only preserved for C++11.) 125*f5c631daSSadaf Ebrahimi symbols.insert(std::pair<uint32_t, int>(masm.GetCursorOffset(), i)); 126*f5c631daSSadaf Ebrahimi } 127*f5c631daSSadaf Ebrahimi 128*f5c631daSSadaf Ebrahimi // Values to pass to the macro-assembler. 129*f5c631daSSadaf Ebrahimi UseScratchRegisterScope scratch_registers(&masm); 130*f5c631daSSadaf Ebrahimi ${code_instantiate_operands} 131*f5c631daSSadaf Ebrahimi 132*f5c631daSSadaf Ebrahimi (masm.*instruction)(${code_parameter_list}); 133*f5c631daSSadaf Ebrahimi 134*f5c631daSSadaf Ebrahimi // For now, these test don't currently produce (or check) any trace; we just 135*f5c631daSSadaf Ebrahimi // check that the MacroAssembler didn't crash. 136*f5c631daSSadaf Ebrahimi // TODO: We could generate disassembly as a trace here, to check for sane 137*f5c631daSSadaf Ebrahimi // output, though the trace would need to be manually checked. 138*f5c631daSSadaf Ebrahimi } 139*f5c631daSSadaf Ebrahimi 140*f5c631daSSadaf Ebrahimi masm.FinalizeCode(); 141*f5c631daSSadaf Ebrahimi 142*f5c631daSSadaf Ebrahimi if (Test::disassemble()) { 143*f5c631daSSadaf Ebrahimi // Disassemble to stdout if given --disassemble on the command line. 144*f5c631daSSadaf Ebrahimi TestDisassembler dis(std::cout, symbols, mnemonic); 145*f5c631daSSadaf Ebrahimi if (masm.IsUsingT32()) { 146*f5c631daSSadaf Ebrahimi dis.DisassembleT32Buffer(masm.GetBuffer()->GetStartAddress<uint16_t*>(), 147*f5c631daSSadaf Ebrahimi masm.GetCursorOffset()); 148*f5c631daSSadaf Ebrahimi } else { 149*f5c631daSSadaf Ebrahimi dis.DisassembleA32Buffer(masm.GetBuffer()->GetStartAddress<uint32_t*>(), 150*f5c631daSSadaf Ebrahimi masm.GetCursorOffset()); 151*f5c631daSSadaf Ebrahimi } 152*f5c631daSSadaf Ebrahimi } 153*f5c631daSSadaf Ebrahimi} 154*f5c631daSSadaf Ebrahimi 155*f5c631daSSadaf Ebrahimi// Instantiate tests for each instruction in the list. 156*f5c631daSSadaf Ebrahimi#define TEST(mnemonic) \ 157*f5c631daSSadaf Ebrahimi void Test_##mnemonic() { \ 158*f5c631daSSadaf Ebrahimi TestHelper(&MacroAssembler::mnemonic, #mnemonic); \ 159*f5c631daSSadaf Ebrahimi } \ 160*f5c631daSSadaf Ebrahimi Test test_##mnemonic("AARCH32_${test_name}_" #mnemonic, \ 161*f5c631daSSadaf Ebrahimi &Test_##mnemonic); 162*f5c631daSSadaf EbrahimiFOREACH_INSTRUCTION(TEST) 163*f5c631daSSadaf Ebrahimi#undef TEST 164*f5c631daSSadaf Ebrahimi 165*f5c631daSSadaf Ebrahimi} // namespace 166*f5c631daSSadaf Ebrahimi#endif 167*f5c631daSSadaf Ebrahimi 168*f5c631daSSadaf Ebrahimi} // namespace aarch32 169*f5c631daSSadaf Ebrahimi} // namespace vixl 170