| // Copyright 2017, VIXL authors |
| // All rights reserved. |
| // |
| // Redistribution and use in source and binary forms, with or without |
| // modification, are permitted provided that the following conditions are met: |
| // |
| // * Redistributions of source code must retain the above copyright notice, |
| // this list of conditions and the following disclaimer. |
| // * Redistributions in binary form must reproduce the above copyright notice, |
| // this list of conditions and the following disclaimer in the documentation |
| // and/or other materials provided with the distribution. |
| // * Neither the name of ARM Limited nor the names of its contributors may be |
| // used to endorse or promote products derived from this software without |
| // specific prior written permission. |
| // |
| // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND |
| // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE |
| // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
| // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| |
| /// This file is a template read by tools/generate_tests.py, it isn't valid C++ |
| /// as it is. Variables written as ${substitute_me} are replaced by the script. |
| /// Comments starting with three forward slashes such as this one are also |
| /// removed. |
| |
| ${do_not_edit_comment} |
| |
| #include <map> |
| |
| #include "test-runner.h" |
| |
| #include "test-utils.h" |
| |
| #include "aarch32/macro-assembler-aarch32.h" |
| |
| #define BUF_SIZE (4096) |
| |
| namespace vixl { |
| namespace aarch32 { |
| |
| // List of instruction mnemonics. |
| #define FOREACH_INSTRUCTION(M) \ |
| ${instruction_list_declaration} |
| |
| // The following definitions are defined again in each generated test, therefore |
| // we need to place them in an anonymous namespace. It expresses that they are |
| // local to this file only, and the compiler is not allowed to share these types |
| // across test files during template instantiation. Specifically, `Operands` has |
| // various layouts across generated tests so it absolutely cannot be shared. |
| |
| #ifdef ${isa_guard} |
| namespace { |
| |
| // Values to be passed to the assembler to produce the instruction under test. |
| struct Operands { |
| ${operand_list_declaration} |
| }; |
| |
| // This structure contains all data needed to test one specific |
| // instruction. |
| struct TestData { |
| // The `operands` field represents what to pass to the assembler to |
| // produce the instruction. |
| Operands operands; |
| // Description of the operands, used for error reporting. |
| const char* operands_description; |
| // Unique identifier, used for generating traces. |
| const char* identifier; |
| }; |
| |
| #ifdef VIXL_NEGATIVE_TESTING |
| // Each element of this array produce one instruction encoding. |
| const TestData kTests[] = {${test_case_definitions}}; |
| #endif |
| |
| typedef void (MacroAssembler::*Fn)(${macroassembler_method_args}); |
| |
| #ifdef VIXL_NEGATIVE_TESTING |
| void TestHelper(Fn instruction, const char* mnemonic) { |
| for (unsigned i = 0; i < ARRAY_SIZE(kTests); i++) { |
| MacroAssembler masm(BUF_SIZE); |
| ${macroassembler_set_isa} |
| |
| // Values to pass to the assembler. |
| ${code_instantiate_operands} |
| |
| try { |
| { |
| ExactAssemblyScope scope(&masm, 4, ExactAssemblyScope::kMaximumSize); |
| (masm.*instruction)(${code_parameter_list}); |
| } |
| printf("\nNegative test for: %s\n", mnemonic); |
| printf("%s:%d:%s\nNo exception raised.\n", |
| __FILE__, |
| __LINE__, |
| masm.IsUsingT32() ? "T32" : "A32"); |
| abort(); |
| } catch (const std::runtime_error&) { |
| // Nothing to do, test passed. |
| // TODO: Consider checking the error message here, if possible. |
| } |
| } |
| } |
| #else |
| void TestHelper(Fn, const char*) { |
| printf("Skipping negative tests. To enable them, build with" |
| " 'negative_testing=on'.\n"); |
| } |
| #endif |
| |
| // Instantiate tests for each instruction in the list. |
| #define TEST(mnemonic) \ |
| void Test_##mnemonic() { \ |
| TestHelper(&MacroAssembler::mnemonic, #mnemonic); \ |
| } \ |
| Test test_##mnemonic("AARCH32_${test_name}_" #mnemonic "_${test_isa}", \ |
| &Test_##mnemonic); |
| FOREACH_INSTRUCTION(TEST) |
| #undef TEST |
| |
| } // namespace |
| #endif |
| |
| } // namespace aarch32 |
| } // namespace vixl |