/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <vector>
#include <memory>

#include "arch/instruction_set.h"
#include "arch/instruction_set_features.h"
#include "cfi_test.h"
#include "dex/compiler_ir.h"
#include "dex/mir_graph.h"
#include "dex/pass_manager.h"
#include "dex/quick/dex_file_to_method_inliner_map.h"
#include "dex/quick/quick_compiler.h"
#include "dex/quick/mir_to_lir.h"
#include "dex/verification_results.h"
#include "driver/compiler_driver.h"
#include "driver/compiler_options.h"
#include "gtest/gtest.h"

#include "dex/quick/quick_cfi_test_expected.inc"

namespace art {

// Run the tests only on host.
#ifndef HAVE_ANDROID_OS

class QuickCFITest : public CFITest {
 public:
  // Enable this flag to generate the expected outputs.
  static constexpr bool kGenerateExpected = false;

  void TestImpl(InstructionSet isa, const char* isa_str,
                const std::vector<uint8_t>& expected_asm,
                const std::vector<uint8_t>& expected_cfi) {
    // Setup simple compiler context.
    ArenaPool pool;
    ArenaAllocator arena(&pool);
    CompilerOptions compiler_options(
      CompilerOptions::kDefaultCompilerFilter,
      CompilerOptions::kDefaultHugeMethodThreshold,
      CompilerOptions::kDefaultLargeMethodThreshold,
      CompilerOptions::kDefaultSmallMethodThreshold,
      CompilerOptions::kDefaultTinyMethodThreshold,
      CompilerOptions::kDefaultNumDexMethodsThreshold,
      false,
      CompilerOptions::kDefaultTopKProfileThreshold,
      false,
      true,  // include_debug_symbols.
      true,  // include_cfi
      false,
      false,
      false,
      false,
      nullptr,
      new PassManagerOptions(),
      nullptr,
      false);
    VerificationResults verification_results(&compiler_options);
    DexFileToMethodInlinerMap method_inliner_map;
    std::unique_ptr<const InstructionSetFeatures> isa_features;
    std::string error;
    isa_features.reset(InstructionSetFeatures::FromVariant(isa, "default", &error));
    CompilerDriver driver(&compiler_options, &verification_results, &method_inliner_map,
                          Compiler::kQuick, isa, isa_features.get(),
                          false, nullptr, nullptr, nullptr, 0, false, false, "", 0, -1, "");
    ClassLinker* linker = nullptr;
    CompilationUnit cu(&pool, isa, &driver, linker);
    DexFile::CodeItem code_item { 0, 0, 0, 0, 0, 0, { 0 } };  // NOLINT
    cu.mir_graph.reset(new MIRGraph(&cu, &arena));
    cu.mir_graph->current_code_item_ = &code_item;

    // Generate empty method with some spills.
    std::unique_ptr<Mir2Lir> m2l(QuickCompiler::GetCodeGenerator(&cu, nullptr));
    m2l->frame_size_ = 64u;
    m2l->CompilerInitializeRegAlloc();
    for (const auto& info : m2l->reg_pool_->core_regs_) {
      if (m2l->num_core_spills_ < 2 && !info->IsTemp() && !info->InUse()) {
        m2l->core_spill_mask_ |= 1 << info->GetReg().GetRegNum();
        m2l->num_core_spills_++;
      }
    }
    for (const auto& info : m2l->reg_pool_->sp_regs_) {
      if (m2l->num_fp_spills_ < 2 && !info->IsTemp() && !info->InUse()) {
        m2l->fp_spill_mask_ |= 1 << info->GetReg().GetRegNum();
        m2l->num_fp_spills_++;
      }
    }
    m2l->AdjustSpillMask();
    m2l->GenEntrySequence(nullptr, m2l->LocCReturnRef());
    m2l->GenExitSequence();
    m2l->HandleSlowPaths();
    m2l->AssembleLIR();
    std::vector<uint8_t> actual_asm(m2l->code_buffer_.begin(), m2l->code_buffer_.end());
    auto const& cfi_data = m2l->cfi().Patch(actual_asm.size());
    std::vector<uint8_t> actual_cfi(cfi_data->begin(), cfi_data->end());
    EXPECT_EQ(m2l->cfi().GetCurrentPC(), static_cast<int>(actual_asm.size()));

    if (kGenerateExpected) {
      GenerateExpected(stdout, isa, isa_str, actual_asm, actual_cfi);
    } else {
      EXPECT_EQ(expected_asm, actual_asm);
      EXPECT_EQ(expected_cfi, actual_cfi);
    }
  }
};

#define TEST_ISA(isa) \
  TEST_F(QuickCFITest, isa) { \
    std::vector<uint8_t> expected_asm(expected_asm_##isa, \
        expected_asm_##isa + arraysize(expected_asm_##isa)); \
    std::vector<uint8_t> expected_cfi(expected_cfi_##isa, \
        expected_cfi_##isa + arraysize(expected_cfi_##isa)); \
    TestImpl(isa, #isa, expected_asm, expected_cfi); \
  }

TEST_ISA(kThumb2)
TEST_ISA(kArm64)
TEST_ISA(kX86)
TEST_ISA(kX86_64)
TEST_ISA(kMips)
TEST_ISA(kMips64)

#endif  // HAVE_ANDROID_OS

}  // namespace art
