//===- llvm/unittest/MC/DwarfLineTables.cpp ------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCTargetOptions.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
#include "gtest/gtest.h"

using namespace llvm;

namespace {
struct Context {
  const char *TripleName = "x86_64-pc-linux";
  std::unique_ptr<MCRegisterInfo> MRI;
  std::unique_ptr<MCAsmInfo> MAI;
  std::unique_ptr<MCContext> Ctx;

  Context() {
    llvm::InitializeAllTargetInfos();
    llvm::InitializeAllTargetMCs();
    llvm::InitializeAllDisassemblers();

    // If we didn't build x86, do not run the test.
    std::string Error;
    const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, Error);
    if (!TheTarget)
      return;

    MRI.reset(TheTarget->createMCRegInfo(TripleName));
    MCTargetOptions MCOptions;
    MAI.reset(TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions));
    Ctx = std::make_unique<MCContext>(Triple(TripleName), MAI.get(), MRI.get(),
                                      /*MSTI=*/nullptr);
  }

  operator bool() { return Ctx.get(); }
  operator MCContext &() { return *Ctx; };
};

Context &getContext() {
  static Context Ctxt;
  return Ctxt;
}
}

void verifyEncoding(MCDwarfLineTableParams Params, int LineDelta, int AddrDelta,
                    ArrayRef<uint8_t> ExpectedEncoding) {
  SmallString<16> Buffer;
  MCDwarfLineAddr::encode(getContext(), Params, LineDelta, AddrDelta,
                          Buffer);
  EXPECT_EQ(ExpectedEncoding, arrayRefFromStringRef(Buffer));
}

TEST(DwarfLineTables, TestDefaultParams) {
  if (!getContext())
    GTEST_SKIP();

  MCDwarfLineTableParams Params;

  // Minimal line offset expressible through extended opcode, 0 addr delta
  const uint8_t Encoding0[] = {13}; // Special opcode Addr += 0, Line += -5
  verifyEncoding(Params, -5, 0, Encoding0);

  // Maximal line offset expressible through extended opcode,
  const uint8_t Encoding1[] = {26}; // Special opcode Addr += 0, Line += +8
  verifyEncoding(Params, 8, 0, Encoding1);

  // Random value in the middle of the special ocode range
  const uint8_t Encoding2[] = {146}; // Special opcode Addr += 9, Line += 2
  verifyEncoding(Params, 2, 9, Encoding2);

  // Minimal line offset expressible through extended opcode, max addr delta
  const uint8_t Encoding3[] = {251}; // Special opcode Addr += 17, Line += -5
  verifyEncoding(Params, -5, 17, Encoding3);

  // Biggest special opcode
  const uint8_t Encoding4[] = {255}; // Special opcode Addr += 17, Line += -1
  verifyEncoding(Params, -1, 17, Encoding4);

  // Line delta outside of the special opcode range, address delta in range
  const uint8_t Encoding5[] = {dwarf::DW_LNS_advance_line, 9,
                               158}; // Special opcode Addr += 10, Line += 0
  verifyEncoding(Params, 9, 10, Encoding5);

  // Address delta outside of the special opcode range, but small
  // enough to do DW_LNS_const_add_pc + special opcode.
  const uint8_t Encoding6[] = {dwarf::DW_LNS_const_add_pc, // pc += 17
                               62}; // Special opcode Addr += 3, Line += 2
  verifyEncoding(Params, 2, 20, Encoding6);

  // Address delta big enough to require the use of DW_LNS_advance_pc
  // Line delta in special opcode range
  const uint8_t Encoding7[] = {dwarf::DW_LNS_advance_pc, 100,
                               20}; // Special opcode Addr += 0, Line += 2
  verifyEncoding(Params, 2, 100, Encoding7);

  // No special opcode possible.
  const uint8_t Encoding8[] = {dwarf::DW_LNS_advance_line, 20,
                               dwarf::DW_LNS_advance_pc, 100,
                               dwarf::DW_LNS_copy};
  verifyEncoding(Params, 20, 100, Encoding8);
}

TEST(DwarfLineTables, TestCustomParams) {
  if (!getContext())
    GTEST_SKIP();

  // Some tests against the example values given in the standard.
  MCDwarfLineTableParams Params;
  Params.DWARF2LineOpcodeBase = 13;
  Params.DWARF2LineBase = -3;
  Params.DWARF2LineRange = 12;

  // Minimal line offset expressible through extended opcode, 0 addr delta
  const uint8_t Encoding0[] = {13}; // Special opcode Addr += 0, Line += -5
  verifyEncoding(Params, -3, 0, Encoding0);

  // Maximal line offset expressible through extended opcode,
  const uint8_t Encoding1[] = {24}; // Special opcode Addr += 0, Line += +8
  verifyEncoding(Params, 8, 0, Encoding1);

  // Random value in the middle of the special ocode range
  const uint8_t Encoding2[] = {126}; // Special opcode Addr += 9, Line += 2
  verifyEncoding(Params, 2, 9, Encoding2);

  // Minimal line offset expressible through extended opcode, max addr delta
  const uint8_t Encoding3[] = {253}; // Special opcode Addr += 20, Line += -3
  verifyEncoding(Params, -3, 20, Encoding3);

  // Biggest special opcode
  const uint8_t Encoding4[] = {255}; // Special opcode Addr += 17, Line += -1
  verifyEncoding(Params, -1, 20, Encoding4);

  // Line delta outside of the special opcode range, address delta in range
  const uint8_t Encoding5[] = {dwarf::DW_LNS_advance_line, 9,
                               136}; // Special opcode Addr += 10, Line += 0
  verifyEncoding(Params, 9, 10, Encoding5);

  // Address delta outside of the special opcode range, but small
  // enough to do DW_LNS_const_add_pc + special opcode.
  const uint8_t Encoding6[] = {dwarf::DW_LNS_const_add_pc, // pc += 20
                               138}; // Special opcode Addr += 10, Line += 2
  verifyEncoding(Params, 2, 30, Encoding6);

  // Address delta big enough to require the use of DW_LNS_advance_pc
  // Line delta in special opcode range
  const uint8_t Encoding7[] = {dwarf::DW_LNS_advance_pc, 100,
                               18}; // Special opcode Addr += 0, Line += 2
  verifyEncoding(Params, 2, 100, Encoding7);

  // No special opcode possible.
  const uint8_t Encoding8[] = {dwarf::DW_LNS_advance_line, 20,
                               dwarf::DW_LNS_advance_pc, 100,
                               dwarf::DW_LNS_copy};
  verifyEncoding(Params, 20, 100, Encoding8);
}

TEST(DwarfLineTables, TestCustomParams2) {
  if (!getContext())
    GTEST_SKIP();

  // Corner case param values.
  MCDwarfLineTableParams Params;
  Params.DWARF2LineOpcodeBase = 13;
  Params.DWARF2LineBase = 1;
  Params.DWARF2LineRange = 255;

  const uint8_t Encoding0[] = {dwarf::DW_LNS_advance_line, 248, 1,
                               dwarf::DW_LNS_copy};
  verifyEncoding(Params, 248, 0, Encoding0);
}
