// 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
