aboutsummaryrefslogtreecommitdiff
path: root/llvm/unittests/MC/SystemZ/SystemZMCDisassemblerTest.cpp
blob: df59fcb402e219fe31529590d3d0bade917d5fc0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
//===- SystemZMCDisassemblerTest.cpp - Tests for SystemZ MCDisassembler ---===//
//
// 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/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
#include "llvm/MC/MCDisassembler/MCSymbolizer.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.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 = "systemz-unknown";
  std::unique_ptr<MCRegisterInfo> MRI;
  std::unique_ptr<MCAsmInfo> MAI;
  std::unique_ptr<MCContext> Ctx;
  std::unique_ptr<MCSubtargetInfo> STI;
  std::unique_ptr<MCDisassembler> DisAsm;

  Context() {
    LLVMInitializeSystemZTargetInfo();
    LLVMInitializeSystemZTargetMC();
    LLVMInitializeSystemZDisassembler();

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

    MRI.reset(TheTarget->createMCRegInfo(TripleName));
    MAI.reset(TheTarget->createMCAsmInfo(*MRI, TripleName, MCTargetOptions()));
    STI.reset(TheTarget->createMCSubtargetInfo(TripleName, "", ""));
    Ctx = std::make_unique<MCContext>(Triple(TripleName), MAI.get(), MRI.get(),
                                      STI.get());

    DisAsm.reset(TheTarget->createMCDisassembler(*STI, *Ctx));
  }

  operator MCContext &() { return *Ctx; };
};

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

class SystemZMCSymbolizerTest : public MCSymbolizer {
public:
  SystemZMCSymbolizerTest(MCContext &MC) : MCSymbolizer(MC, nullptr) {}
  ~SystemZMCSymbolizerTest() {}

  bool tryAddingSymbolicOperand([[maybe_unused]] MCInst &Inst,
                                [[maybe_unused]] raw_ostream &CStream,
                                [[maybe_unused]] int64_t Value,
                                [[maybe_unused]] uint64_t Address,
                                [[maybe_unused]] bool IsBranch,
                                [[maybe_unused]] uint64_t Offset,
                                [[maybe_unused]] uint64_t OpSize,
                                [[maybe_unused]] uint64_t InstSize) override {
    return true;
  }

  void
  tryAddingPcLoadReferenceComment([[maybe_unused]] raw_ostream &cStream,
                                  [[maybe_unused]] int64_t Value,
                                  [[maybe_unused]] uint64_t Address) override {}
};

} // namespace

TEST(SystemZDisassembler, SystemZMCSymbolizerTest) {
  SystemZMCSymbolizerTest *TestSymbolizer =
      new SystemZMCSymbolizerTest(getContext());
  getContext().DisAsm->setSymbolizer(
      std::unique_ptr<MCSymbolizer>(TestSymbolizer));

  MCInst Inst;
  uint64_t InstSize;

  // Check that the SystemZ disassembler sets the comment stream before calling
  // MCDisassembler::tryAddingSymbolicOperand. This will fail an assert if it
  // does not do that.
  MCDisassembler::DecodeStatus Status = getContext().DisAsm->getInstruction(
      Inst, InstSize,
      // lgrl   %r1, 0x1234
      {0xc4, 0x18, 0x00, 0x00, 0x9a, 0x1a}, 0, nulls());
  ASSERT_TRUE(Status == MCDisassembler::Success);
  EXPECT_EQ(InstSize, uint64_t{6});
}