[llvm] [JITLink][AArch32] Add TableGen Backend for Instr Encodings (PR #76996)
Eymen Ünay via llvm-commits
llvm-commits at lists.llvm.org
Fri Jan 26 10:12:40 PST 2024
https://github.com/eymay updated https://github.com/llvm/llvm-project/pull/76996
>From 6d96b3f0a3fe80f7134f2076491a0784e49d8867 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eymen=20=C3=9Cnay?= <eymenunay at outlook.com>
Date: Fri, 22 Dec 2023 17:56:07 +0300
Subject: [PATCH 1/5] [JITLink][AArch32] Add TableGen Backend for Instr
Encodings
This TableGen backend uses the Target info in lib/Target/ARM to
produce instruction encodings necessary for JITLink AArch32 backend.
Currently opcode, opcode mask, register mask and immediate mask are
generated. These were used to replace the `mov` related instruction
information in aarch32.h.
---
.../llvm/ExecutionEngine/JITLink/aarch32.h | 35 ----
.../ExecutionEngine/JITLink/CMakeLists.txt | 5 +
llvm/lib/ExecutionEngine/JITLink/aarch32.cpp | 2 +
.../ExecutionEngine/JITLink/AArch32Tests.cpp | 2 +
.../JITLink/JITLinkAArch32.inc | 58 ++++++
llvm/utils/TableGen/CMakeLists.txt | 5 +
.../TableGen/JITLinkAArch32InstrInfo.cpp | 196 ++++++++++++++++++
7 files changed, 268 insertions(+), 35 deletions(-)
create mode 100644 llvm/unittests/ExecutionEngine/JITLink/JITLinkAArch32.inc
create mode 100644 llvm/utils/TableGen/JITLinkAArch32InstrInfo.cpp
diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h b/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h
index eda6feb441e672..f81a071e7d773e 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h
@@ -219,20 +219,6 @@ template <> struct FixupInfo<Arm_Call> : public FixupInfoArmBranch {
static constexpr uint32_t BitBlx = 0x10000000;
};
-struct FixupInfoArmMov : public FixupInfoArm {
- static constexpr uint32_t OpcodeMask = 0x0ff00000;
- static constexpr uint32_t ImmMask = 0x000f0fff;
- static constexpr uint32_t RegMask = 0x0000f000;
-};
-
-template <> struct FixupInfo<Arm_MovtAbs> : public FixupInfoArmMov {
- static constexpr uint32_t Opcode = 0x03400000;
-};
-
-template <> struct FixupInfo<Arm_MovwAbsNC> : public FixupInfoArmMov {
- static constexpr uint32_t Opcode = 0x03000000;
-};
-
template <> struct FixupInfo<Thumb_Jump24> : public FixupInfoThumb {
static constexpr HalfWords Opcode{0xf000, 0x9000};
static constexpr HalfWords OpcodeMask{0xf800, 0x9000};
@@ -247,27 +233,6 @@ template <> struct FixupInfo<Thumb_Call> : public FixupInfoThumb {
static constexpr uint16_t LoBitNoBlx = 0x1000;
};
-struct FixupInfoThumbMov : public FixupInfoThumb {
- static constexpr HalfWords OpcodeMask{0xfbf0, 0x8000};
- static constexpr HalfWords ImmMask{0x040f, 0x70ff};
- static constexpr HalfWords RegMask{0x0000, 0x0f00};
-};
-
-template <> struct FixupInfo<Thumb_MovtAbs> : public FixupInfoThumbMov {
- static constexpr HalfWords Opcode{0xf2c0, 0x0000};
-};
-
-template <> struct FixupInfo<Thumb_MovtPrel> : public FixupInfoThumbMov {
- static constexpr HalfWords Opcode{0xf2c0, 0x0000};
-};
-
-template <> struct FixupInfo<Thumb_MovwAbsNC> : public FixupInfoThumbMov {
- static constexpr HalfWords Opcode{0xf240, 0x0000};
-};
-
-template <> struct FixupInfo<Thumb_MovwPrelNC> : public FixupInfoThumbMov {
- static constexpr HalfWords Opcode{0xf240, 0x0000};
-};
/// Helper function to read the initial addend for Data-class relocations.
Expected<int64_t> readAddendData(LinkGraph &G, Block &B, Edge::OffsetT Offset,
diff --git a/llvm/lib/ExecutionEngine/JITLink/CMakeLists.txt b/llvm/lib/ExecutionEngine/JITLink/CMakeLists.txt
index e5f5a99c39bc00..524bd9fad8e53e 100644
--- a/llvm/lib/ExecutionEngine/JITLink/CMakeLists.txt
+++ b/llvm/lib/ExecutionEngine/JITLink/CMakeLists.txt
@@ -1,5 +1,10 @@
set(LLVM_TARGET_DEFINITIONS COFFOptions.td)
tablegen(LLVM COFFOptions.inc -gen-opt-parser-defs)
+
+include_directories(${PROJECT_SOURCE_DIR}/lib/Target/ARM/)
+set(LLVM_TARGET_DEFINITIONS ${PROJECT_SOURCE_DIR}/lib/Target/ARM/ARM.td)
+tablegen(LLVM JITLinkAArch32.inc -gen-jitlink-aarch32-instr-info)
+
add_public_tablegen_target(JITLinkTableGen)
add_llvm_component_library(LLVMJITLink
diff --git a/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp b/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp
index 00be2f57d06640..0a705fcde89479 100644
--- a/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp
@@ -21,6 +21,8 @@
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MathExtras.h"
+#include "JITLinkAArch32.inc"
+
#define DEBUG_TYPE "jitlink"
namespace llvm {
diff --git a/llvm/unittests/ExecutionEngine/JITLink/AArch32Tests.cpp b/llvm/unittests/ExecutionEngine/JITLink/AArch32Tests.cpp
index b1890d884d1735..46307db539b8d3 100644
--- a/llvm/unittests/ExecutionEngine/JITLink/AArch32Tests.cpp
+++ b/llvm/unittests/ExecutionEngine/JITLink/AArch32Tests.cpp
@@ -11,6 +11,8 @@
#include "gtest/gtest.h"
+#include "JITLinkAArch32.inc"
+
using namespace llvm;
using namespace llvm::jitlink;
using namespace llvm::jitlink::aarch32;
diff --git a/llvm/unittests/ExecutionEngine/JITLink/JITLinkAArch32.inc b/llvm/unittests/ExecutionEngine/JITLink/JITLinkAArch32.inc
new file mode 100644
index 00000000000000..42ef9795921e34
--- /dev/null
+++ b/llvm/unittests/ExecutionEngine/JITLink/JITLinkAArch32.inc
@@ -0,0 +1,58 @@
+/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
+|* *|
+|* Skeleton data structures *|
+|* *|
+|* Automatically generated file, do not edit! *|
+|* *|
+\*===----------------------------------------------------------------------===*/
+
+using namespace llvm::jitlink::aarch32;
+
+namespace llvm {
+namespace jitlink {
+namespace aarch32 {
+template <> struct FixupInfo<Arm_MovwAbsNC> : public FixupInfoArm {
+ static constexpr uint32_t Opcode = 0x3000000;
+ static constexpr uint32_t OpcodeMask = 0xff00000;
+ static constexpr uint32_t ImmMask = 0xf0fff;
+ static constexpr uint32_t RegMask = 0xf000;
+};
+
+template <> struct FixupInfo<Arm_MovtAbs> : public FixupInfoArm {
+ static constexpr uint32_t Opcode = 0x3400000;
+ static constexpr uint32_t OpcodeMask = 0xff00000;
+ static constexpr uint32_t ImmMask = 0xf0fff;
+ static constexpr uint32_t RegMask = 0xf000;
+};
+
+template <> struct FixupInfo<Thumb_MovwAbsNC> : public FixupInfoThumb {
+ static constexpr HalfWords Opcode {0xf240, 0x0};
+ static constexpr HalfWords OpcodeMask {0xfbf0, 0x8000};
+ static constexpr HalfWords ImmMask {0x40f, 0x70ff};
+ static constexpr HalfWords RegMask {0x0, 0xf00};
+};
+
+template <> struct FixupInfo<Thumb_MovtAbs> : public FixupInfoThumb {
+ static constexpr HalfWords Opcode {0xf2c0, 0x0};
+ static constexpr HalfWords OpcodeMask {0xfbf0, 0x8000};
+ static constexpr HalfWords ImmMask {0x40f, 0x70ff};
+ static constexpr HalfWords RegMask {0x0, 0xf00};
+};
+
+template <> struct FixupInfo<Thumb_MovwPrelNC> : public FixupInfoThumb {
+ static constexpr HalfWords Opcode {0xf240, 0x0};
+ static constexpr HalfWords OpcodeMask {0xfbf0, 0x8000};
+ static constexpr HalfWords ImmMask {0x40f, 0x70ff};
+ static constexpr HalfWords RegMask {0x0, 0xf00};
+};
+
+template <> struct FixupInfo<Thumb_MovtPrel> : public FixupInfoThumb {
+ static constexpr HalfWords Opcode {0xf2c0, 0x0};
+ static constexpr HalfWords OpcodeMask {0xfbf0, 0x8000};
+ static constexpr HalfWords ImmMask {0x40f, 0x70ff};
+ static constexpr HalfWords RegMask {0x0, 0xf00};
+};
+
+} //aarch32
+} //jitlink
+} //llvm
diff --git a/llvm/utils/TableGen/CMakeLists.txt b/llvm/utils/TableGen/CMakeLists.txt
index 0100bf345ec29e..0232003a7cd66a 100644
--- a/llvm/utils/TableGen/CMakeLists.txt
+++ b/llvm/utils/TableGen/CMakeLists.txt
@@ -66,6 +66,7 @@ add_tablegen(llvm-tblgen LLVM
InfoByHwMode.cpp
InstrInfoEmitter.cpp
InstrDocsEmitter.cpp
+ JITLinkAArch32InstrInfo.cpp
OptEmitter.cpp
OptParserEmitter.cpp
OptRSTEmitter.cpp
@@ -90,6 +91,10 @@ add_tablegen(llvm-tblgen LLVM
WebAssemblyDisassemblerEmitter.cpp
$<TARGET_OBJECTS:obj.LLVMTableGenCommon>
+ ADDITIONAL_HEADER_DIRS
+ ${LLVM_MAIN_INCLUDE_DIR}/llvm/ExecutionEngine/JITLink
+
+
DEPENDS
intrinsics_gen # via llvm-min-tablegen
)
diff --git a/llvm/utils/TableGen/JITLinkAArch32InstrInfo.cpp b/llvm/utils/TableGen/JITLinkAArch32InstrInfo.cpp
new file mode 100644
index 00000000000000..6144764d482295
--- /dev/null
+++ b/llvm/utils/TableGen/JITLinkAArch32InstrInfo.cpp
@@ -0,0 +1,196 @@
+//===- JITLinkAArch32InstrInfo.cpp - JITLink AArch32 TableGen backend -----===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This Tablegen backend emits instruction encodings of AArch32 for JITLink.
+//
+//===----------------------------------------------------------------------===//
+#include "CodeGenDAGPatterns.h"
+#include "CodeGenInstruction.h"
+#include "CodeGenSchedule.h"
+#include "CodeGenTarget.h"
+#include "PredicateExpander.h"
+#include "SequenceToOffsetTable.h"
+#include "SubtargetFeatureInfo.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ExecutionEngine/JITLink/aarch32.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/TableGen/Error.h"
+#include "llvm/TableGen/TableGenBackend.h"
+
+#define DEBUG_TYPE "jitlink-aarch32-tblgen"
+
+namespace llvm {
+class RecordKeeper;
+class raw_ostream;
+} // namespace llvm
+
+using namespace llvm;
+using namespace llvm::jitlink;
+using namespace llvm::jitlink::aarch32;
+
+namespace {
+
+// Any helper data structures can be defined here. Some backends use
+// structs to collect information from the records.
+
+Twine getEdgeKindName(Edge::Kind K) {
+#define KIND_NAME_CASE(K) \
+ case K: \
+ return #K;
+
+ switch (K) {
+ KIND_NAME_CASE(Data_Delta32)
+ KIND_NAME_CASE(Data_Pointer32)
+ KIND_NAME_CASE(Arm_Call)
+ KIND_NAME_CASE(Arm_Jump24)
+ KIND_NAME_CASE(Arm_MovwAbsNC)
+ KIND_NAME_CASE(Arm_MovtAbs)
+ KIND_NAME_CASE(Thumb_Call)
+ KIND_NAME_CASE(Thumb_Jump24)
+ KIND_NAME_CASE(Thumb_MovwAbsNC)
+ KIND_NAME_CASE(Thumb_MovtAbs)
+ KIND_NAME_CASE(Thumb_MovwPrelNC)
+ KIND_NAME_CASE(Thumb_MovtPrel)
+ default:
+ return "";
+ }
+#undef KIND_NAME_CASE
+}
+
+static StringRef getInstrFromJITLinkEdgeKind(Edge::Kind Kind) {
+ /// Translate from JITLink-internal edge kind to TableGen instruction names.
+ switch (Kind) {
+ case Arm_Call:
+ return "";
+ case aarch32::Arm_Jump24:
+ return "";
+ case aarch32::Arm_MovwAbsNC:
+ return "MOVi16";
+ case aarch32::Arm_MovtAbs:
+ return "MOVTi16";
+ case aarch32::Thumb_Call:
+ return "";
+ case aarch32::Thumb_Jump24:
+ return "";
+ case aarch32::Thumb_MovwAbsNC:
+ case aarch32::Thumb_MovwPrelNC:
+ return "t2MOVi16";
+ case aarch32::Thumb_MovtAbs:
+ case aarch32::Thumb_MovtPrel:
+ return "t2MOVTi16";
+ default:
+ return "";
+ }
+}
+
+struct InstrInfo {
+ uint32_t Opcode = 0;
+ uint32_t OpcodeMask = 0;
+ uint32_t ImmMask = 0;
+ uint32_t RegMask = 0;
+};
+
+static void extractBits(BitsInit &InstBits, InstrInfo &II) {
+ for (unsigned i = 0; i < InstBits.getNumBits(); ++i) {
+ Init *Bit = InstBits.getBit(i);
+
+ if (auto *VarBit = dyn_cast<VarBitInit>(Bit)) {
+ // Check if the VarBit is for 'imm' or 'Rd'
+ std::string VarName = VarBit->getBitVar()->getAsUnquotedString();
+ if (VarName == "imm") {
+ II.ImmMask |= 1 << i;
+ } else if (VarName == "Rd") {
+ II.RegMask |= 1 << i;
+ }
+ } else if (auto *TheBit = dyn_cast<BitInit>(Bit)) {
+ II.OpcodeMask |= 1 << i;
+ if (TheBit->getValue()) {
+ II.Opcode |= 1 << i;
+ }
+ }
+ }
+
+ assert((II.OpcodeMask & II.ImmMask & II.RegMask) == 0 &&
+ "Masks have intersecting bits");
+}
+
+static void writeArmElement(raw_ostream &OS, Twine InfoName, uint32_t Value,
+ int Indentation = 4) {
+ OS.indent(Indentation) << "static constexpr uint32_t " + InfoName + " = 0x";
+ OS.write_hex(Value) << ";\n";
+}
+
+static void writeArmInfo(raw_ostream &OS, InstrInfo &II, Edge::Kind Kind) {
+ OS << "template <> struct FixupInfo<" + getEdgeKindName(Kind) +
+ "> : public FixupInfoArm {\n";
+ writeArmElement(OS, "Opcode", II.Opcode);
+ writeArmElement(OS, "OpcodeMask", II.OpcodeMask);
+ writeArmElement(OS, "ImmMask", II.ImmMask);
+ writeArmElement(OS, "RegMask", II.RegMask);
+ OS << "};\n\n";
+}
+
+static void writeThumbElement(raw_ostream &OS, Twine InfoName, uint32_t Value,
+ int Indentation = 4) {
+ OS.indent(Indentation) << "static constexpr HalfWords " + InfoName + " {0x";
+ OS.write_hex(Value >> 16) << ", 0x";
+ OS.write_hex(Value & 0x0000FFFF) << "};\n";
+}
+
+static void writeThumbInfo(raw_ostream &OS, InstrInfo &II, Edge::Kind Kind) {
+ OS << "template <> struct FixupInfo<" + getEdgeKindName(Kind) +
+ "> : public FixupInfoThumb {\n";
+ writeThumbElement(OS, "Opcode", II.Opcode);
+ writeThumbElement(OS, "OpcodeMask", II.OpcodeMask);
+ writeThumbElement(OS, "ImmMask", II.ImmMask);
+ writeThumbElement(OS, "RegMask", II.RegMask);
+ OS << "};\n\n";
+}
+
+class JITLinkAArch32Emitter {
+private:
+ RecordKeeper &Records;
+
+public:
+ JITLinkAArch32Emitter(RecordKeeper &RK) : Records(RK) {}
+
+ void run(raw_ostream &OS);
+}; // emitter class
+
+} // anonymous namespace
+
+void JITLinkAArch32Emitter::run(raw_ostream &OS) {
+ emitSourceFileHeader("Skeleton data structures", OS);
+ OS << "using namespace llvm::jitlink::aarch32;\n\n";
+ OS << "namespace llvm {\n";
+ OS << "namespace jitlink {\n";
+ OS << "namespace aarch32 {\n";
+ // const auto &Instructions = Records.getAllDerivedDefinitions("Instruction");
+ for (Edge::Kind JITLinkEdgeKind = aarch32::FirstArmRelocation;
+ JITLinkEdgeKind <= aarch32::LastThumbRelocation; JITLinkEdgeKind += 1) {
+ auto InstName = getInstrFromJITLinkEdgeKind(JITLinkEdgeKind);
+ if (InstName.empty())
+ continue;
+ auto *InstRecord = Records.getDef(InstName);
+ auto *InstBits = InstRecord->getValueAsBitsInit("Inst");
+ InstrInfo II;
+ extractBits(*InstBits, II);
+ if (JITLinkEdgeKind > LastArmRelocation)
+ writeThumbInfo(OS, II, JITLinkEdgeKind);
+ else
+ writeArmInfo(OS, II, JITLinkEdgeKind);
+ }
+
+ OS << "} //aarch32\n";
+ OS << "} //jitlink\n";
+ OS << "} //llvm\n";
+}
+
+static TableGen::Emitter::OptClass<JITLinkAArch32Emitter>
+ X("gen-jitlink-aarch32-instr-info",
+ "Generate JITLink AArch32 Instruction Information");
>From 63e28a2987806a1259d412e1c65af17a9b4935aa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eymen=20=C3=9Cnay?= <eymenunay at outlook.com>
Date: Thu, 4 Jan 2024 23:17:47 +0300
Subject: [PATCH 2/5] Reformat and indent by 2
---
.../llvm/ExecutionEngine/JITLink/aarch32.h | 1 -
.../JITLink/JITLinkAArch32.inc | 54 +++++++++----------
.../TableGen/JITLinkAArch32InstrInfo.cpp | 4 +-
3 files changed, 29 insertions(+), 30 deletions(-)
diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h b/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h
index f81a071e7d773e..2bd2d6023bea8f 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h
@@ -233,7 +233,6 @@ template <> struct FixupInfo<Thumb_Call> : public FixupInfoThumb {
static constexpr uint16_t LoBitNoBlx = 0x1000;
};
-
/// Helper function to read the initial addend for Data-class relocations.
Expected<int64_t> readAddendData(LinkGraph &G, Block &B, Edge::OffsetT Offset,
Edge::Kind Kind);
diff --git a/llvm/unittests/ExecutionEngine/JITLink/JITLinkAArch32.inc b/llvm/unittests/ExecutionEngine/JITLink/JITLinkAArch32.inc
index 42ef9795921e34..aaff38b8c5ad85 100644
--- a/llvm/unittests/ExecutionEngine/JITLink/JITLinkAArch32.inc
+++ b/llvm/unittests/ExecutionEngine/JITLink/JITLinkAArch32.inc
@@ -12,47 +12,47 @@ namespace llvm {
namespace jitlink {
namespace aarch32 {
template <> struct FixupInfo<Arm_MovwAbsNC> : public FixupInfoArm {
- static constexpr uint32_t Opcode = 0x3000000;
- static constexpr uint32_t OpcodeMask = 0xff00000;
- static constexpr uint32_t ImmMask = 0xf0fff;
- static constexpr uint32_t RegMask = 0xf000;
+ static constexpr uint32_t Opcode = 0x3000000;
+ static constexpr uint32_t OpcodeMask = 0xff00000;
+ static constexpr uint32_t ImmMask = 0xf0fff;
+ static constexpr uint32_t RegMask = 0xf000;
};
template <> struct FixupInfo<Arm_MovtAbs> : public FixupInfoArm {
- static constexpr uint32_t Opcode = 0x3400000;
- static constexpr uint32_t OpcodeMask = 0xff00000;
- static constexpr uint32_t ImmMask = 0xf0fff;
- static constexpr uint32_t RegMask = 0xf000;
+ static constexpr uint32_t Opcode = 0x3400000;
+ static constexpr uint32_t OpcodeMask = 0xff00000;
+ static constexpr uint32_t ImmMask = 0xf0fff;
+ static constexpr uint32_t RegMask = 0xf000;
};
template <> struct FixupInfo<Thumb_MovwAbsNC> : public FixupInfoThumb {
- static constexpr HalfWords Opcode {0xf240, 0x0};
- static constexpr HalfWords OpcodeMask {0xfbf0, 0x8000};
- static constexpr HalfWords ImmMask {0x40f, 0x70ff};
- static constexpr HalfWords RegMask {0x0, 0xf00};
+ static constexpr HalfWords Opcode{0xf240, 0x0};
+ static constexpr HalfWords OpcodeMask{0xfbf0, 0x8000};
+ static constexpr HalfWords ImmMask{0x40f, 0x70ff};
+ static constexpr HalfWords RegMask{0x0, 0xf00};
};
template <> struct FixupInfo<Thumb_MovtAbs> : public FixupInfoThumb {
- static constexpr HalfWords Opcode {0xf2c0, 0x0};
- static constexpr HalfWords OpcodeMask {0xfbf0, 0x8000};
- static constexpr HalfWords ImmMask {0x40f, 0x70ff};
- static constexpr HalfWords RegMask {0x0, 0xf00};
+ static constexpr HalfWords Opcode{0xf2c0, 0x0};
+ static constexpr HalfWords OpcodeMask{0xfbf0, 0x8000};
+ static constexpr HalfWords ImmMask{0x40f, 0x70ff};
+ static constexpr HalfWords RegMask{0x0, 0xf00};
};
template <> struct FixupInfo<Thumb_MovwPrelNC> : public FixupInfoThumb {
- static constexpr HalfWords Opcode {0xf240, 0x0};
- static constexpr HalfWords OpcodeMask {0xfbf0, 0x8000};
- static constexpr HalfWords ImmMask {0x40f, 0x70ff};
- static constexpr HalfWords RegMask {0x0, 0xf00};
+ static constexpr HalfWords Opcode{0xf240, 0x0};
+ static constexpr HalfWords OpcodeMask{0xfbf0, 0x8000};
+ static constexpr HalfWords ImmMask{0x40f, 0x70ff};
+ static constexpr HalfWords RegMask{0x0, 0xf00};
};
template <> struct FixupInfo<Thumb_MovtPrel> : public FixupInfoThumb {
- static constexpr HalfWords Opcode {0xf2c0, 0x0};
- static constexpr HalfWords OpcodeMask {0xfbf0, 0x8000};
- static constexpr HalfWords ImmMask {0x40f, 0x70ff};
- static constexpr HalfWords RegMask {0x0, 0xf00};
+ static constexpr HalfWords Opcode{0xf2c0, 0x0};
+ static constexpr HalfWords OpcodeMask{0xfbf0, 0x8000};
+ static constexpr HalfWords ImmMask{0x40f, 0x70ff};
+ static constexpr HalfWords RegMask{0x0, 0xf00};
};
-} //aarch32
-} //jitlink
-} //llvm
+} // namespace aarch32
+} // namespace jitlink
+} // namespace llvm
diff --git a/llvm/utils/TableGen/JITLinkAArch32InstrInfo.cpp b/llvm/utils/TableGen/JITLinkAArch32InstrInfo.cpp
index 6144764d482295..62468ed057d431 100644
--- a/llvm/utils/TableGen/JITLinkAArch32InstrInfo.cpp
+++ b/llvm/utils/TableGen/JITLinkAArch32InstrInfo.cpp
@@ -120,7 +120,7 @@ static void extractBits(BitsInit &InstBits, InstrInfo &II) {
}
static void writeArmElement(raw_ostream &OS, Twine InfoName, uint32_t Value,
- int Indentation = 4) {
+ int Indentation = 2) {
OS.indent(Indentation) << "static constexpr uint32_t " + InfoName + " = 0x";
OS.write_hex(Value) << ";\n";
}
@@ -136,7 +136,7 @@ static void writeArmInfo(raw_ostream &OS, InstrInfo &II, Edge::Kind Kind) {
}
static void writeThumbElement(raw_ostream &OS, Twine InfoName, uint32_t Value,
- int Indentation = 4) {
+ int Indentation = 2) {
OS.indent(Indentation) << "static constexpr HalfWords " + InfoName + " {0x";
OS.write_hex(Value >> 16) << ", 0x";
OS.write_hex(Value & 0x0000FFFF) << "};\n";
>From 7e63dd2cf2ccf49586a75bfe6c45acb360b5a082 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eymen=20=C3=9Cnay?= <eymenunay at outlook.com>
Date: Sat, 6 Jan 2024 14:09:35 +0300
Subject: [PATCH 3/5] Include the generated file in header
Generating an includable file in header requires the TableGen backend
to be independent of the headers, if not a cyclic dependency occurs.
A macro based generation is prioritised and its manipulation is done
in the header file by constexpr lookups.
---
llvm/include/llvm/CMakeLists.txt | 1 +
.../llvm/ExecutionEngine/CMakeLists.txt | 1 +
.../ExecutionEngine/JITLink/CMakeLists.txt | 3 +
.../llvm/ExecutionEngine/JITLink/aarch32.h | 103 +++++++++++-
.../ExecutionEngine/JITLink/CMakeLists.txt | 9 +-
llvm/lib/ExecutionEngine/JITLink/aarch32.cpp | 4 +-
.../ExecutionEngine/JITLink/AArch32Tests.cpp | 4 +-
.../JITLink/JITLinkAArch32.inc | 58 -------
llvm/utils/TableGen/CMakeLists.txt | 6 +-
.../TableGen/JITLinkAArch32InstrInfo.cpp | 149 +++---------------
10 files changed, 135 insertions(+), 203 deletions(-)
create mode 100644 llvm/include/llvm/ExecutionEngine/CMakeLists.txt
create mode 100644 llvm/include/llvm/ExecutionEngine/JITLink/CMakeLists.txt
delete mode 100644 llvm/unittests/ExecutionEngine/JITLink/JITLinkAArch32.inc
diff --git a/llvm/include/llvm/CMakeLists.txt b/llvm/include/llvm/CMakeLists.txt
index ac6b96a68ab92d..22b06c598280e0 100644
--- a/llvm/include/llvm/CMakeLists.txt
+++ b/llvm/include/llvm/CMakeLists.txt
@@ -3,6 +3,7 @@
set(LLVM_TABLEGEN_PROJECT LLVM_HEADERS)
add_subdirectory(CodeGen)
+add_subdirectory(ExecutionEngine)
add_subdirectory(IR)
add_subdirectory(Support)
add_subdirectory(Frontend)
diff --git a/llvm/include/llvm/ExecutionEngine/CMakeLists.txt b/llvm/include/llvm/ExecutionEngine/CMakeLists.txt
new file mode 100644
index 00000000000000..4dff4573dae892
--- /dev/null
+++ b/llvm/include/llvm/ExecutionEngine/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory(JITLink)
diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/CMakeLists.txt b/llvm/include/llvm/ExecutionEngine/JITLink/CMakeLists.txt
new file mode 100644
index 00000000000000..b1eb84feac1256
--- /dev/null
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/CMakeLists.txt
@@ -0,0 +1,3 @@
+set(LLVM_TARGET_DEFINITIONS ${PROJECT_SOURCE_DIR}/lib/Target/ARM/ARM.td)
+tablegen(LLVM JITLinkAArch32.inc -gen-jitlink-aarch32-instr-info -I ${PROJECT_SOURCE_DIR}/lib/Target/ARM/)
+add_public_tablegen_target(JITLinkAArch32TableGen)
diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h b/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h
index 2bd2d6023bea8f..8ca1467635047b 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h
@@ -171,17 +171,77 @@ struct HalfWords {
const uint16_t Lo; // Second halfword
};
+enum InstrName {
+
+#define GET_INSTR(name, opcode, opcode_mask, imm_mask, reg_mask) name,
+
+#include "llvm/ExecutionEngine/JITLink/JITLinkAArch32.inc"
+#undef GET_INSTR
+ INSTR_COUNT,
+ NONE = INSTR_COUNT,
+};
+
+constexpr InstrName getInstrFromJITLinkEdgeKind(Edge::Kind Kind) {
+ switch (Kind) {
+ case Arm_Call:
+ return InstrName::NONE;
+ case aarch32::Arm_Jump24:
+ return InstrName::NONE;
+ case aarch32::Arm_MovwAbsNC:
+ return InstrName::MOVi16;
+ case aarch32::Arm_MovtAbs:
+ return InstrName::MOVTi16;
+ case aarch32::Thumb_Call:
+ return InstrName::NONE;
+ case aarch32::Thumb_Jump24:
+ return InstrName::NONE;
+ case aarch32::Thumb_MovwAbsNC:
+ case aarch32::Thumb_MovwPrelNC:
+ return InstrName::t2MOVi16;
+ case aarch32::Thumb_MovtAbs:
+ case aarch32::Thumb_MovtPrel:
+ return InstrName::t2MOVTi16;
+ default:
+ return InstrName::NONE;
+ }
+}
+
+struct InstrInfo {
+ uint32_t Opcode;
+ uint32_t OpcodeMask;
+ uint32_t ImmMask;
+ uint32_t RegMask;
+};
+
+static constexpr InstrInfo InstrTable[INSTR_COUNT] = {
+#define GET_INSTR(name, opcode, opcode_mask, imm_mask, reg_mask) \
+ {opcode, opcode_mask, imm_mask, reg_mask},
+#include "llvm/ExecutionEngine/JITLink/JITLinkAArch32.inc"
+#undef GET_INSTR
+};
+
/// FixupInfo base class is required for dynamic lookups.
struct FixupInfoBase {
static const FixupInfoBase *getDynFixupInfo(Edge::Kind K);
virtual ~FixupInfoBase() {}
};
-/// FixupInfo checks for Arm edge kinds work on 32-bit words
-struct FixupInfoArm : public FixupInfoBase {
+struct FixupInfoArmBase : public FixupInfoBase {
bool (*checkOpcode)(uint32_t Wd) = nullptr;
};
+/// FixupInfo checks for Arm edge kinds work on 32-bit words
+template <EdgeKind_aarch32 Kind> struct FixupInfoArm : public FixupInfoArmBase {
+ static constexpr uint32_t Opcode =
+ InstrTable[getInstrFromJITLinkEdgeKind(Kind)].Opcode;
+ static constexpr uint32_t OpcodeMask =
+ InstrTable[getInstrFromJITLinkEdgeKind(Kind)].OpcodeMask;
+ static constexpr uint32_t ImmMask =
+ InstrTable[getInstrFromJITLinkEdgeKind(Kind)].ImmMask;
+ static constexpr uint32_t RegMask =
+ InstrTable[getInstrFromJITLinkEdgeKind(Kind)].RegMask;
+};
+
/// FixupInfo check for Thumb32 edge kinds work on a pair of 16-bit halfwords
struct FixupInfoThumb : public FixupInfoBase {
bool (*checkOpcode)(uint16_t Hi, uint16_t Lo) = nullptr;
@@ -199,10 +259,10 @@ struct FixupInfoThumb : public FixupInfoBase {
/// RegMask - Mask with all bits set that encode the register
///
/// Specializations can add further custom fields without restrictions.
-///
+
template <EdgeKind_aarch32 Kind> struct FixupInfo {};
-struct FixupInfoArmBranch : public FixupInfoArm {
+struct FixupInfoArmBranch : public FixupInfoArmBase {
static constexpr uint32_t Opcode = 0x0a000000;
static constexpr uint32_t ImmMask = 0x00ffffff;
};
@@ -219,6 +279,19 @@ template <> struct FixupInfo<Arm_Call> : public FixupInfoArmBranch {
static constexpr uint32_t BitBlx = 0x10000000;
};
+template <EdgeKind_aarch32 Kind>
+struct FixupInfoArmMov : public FixupInfoArm<Kind> {
+ static constexpr uint32_t OpcodeMask = 0x0ff00000;
+ static constexpr uint32_t ImmMask = 0x000f0fff;
+ static constexpr uint32_t RegMask = 0x0000f000;
+};
+
+template <>
+struct FixupInfo<Arm_MovtAbs> : public FixupInfoArmMov<Arm_MovtAbs> {};
+
+template <>
+struct FixupInfo<Arm_MovwAbsNC> : public FixupInfoArmMov<Arm_MovwAbsNC> {};
+
template <> struct FixupInfo<Thumb_Jump24> : public FixupInfoThumb {
static constexpr HalfWords Opcode{0xf000, 0x9000};
static constexpr HalfWords OpcodeMask{0xf800, 0x9000};
@@ -233,6 +306,28 @@ template <> struct FixupInfo<Thumb_Call> : public FixupInfoThumb {
static constexpr uint16_t LoBitNoBlx = 0x1000;
};
+struct FixupInfoThumbMov : public FixupInfoThumb {
+ static constexpr HalfWords OpcodeMask{0xfbf0, 0x8000};
+ static constexpr HalfWords ImmMask{0x040f, 0x70ff};
+ static constexpr HalfWords RegMask{0x0000, 0x0f00};
+};
+
+template <> struct FixupInfo<Thumb_MovtAbs> : public FixupInfoThumbMov {
+ static constexpr HalfWords Opcode{0xf2c0, 0x0000};
+};
+
+template <> struct FixupInfo<Thumb_MovtPrel> : public FixupInfoThumbMov {
+ static constexpr HalfWords Opcode{0xf2c0, 0x0000};
+};
+
+template <> struct FixupInfo<Thumb_MovwAbsNC> : public FixupInfoThumbMov {
+ static constexpr HalfWords Opcode{0xf240, 0x0000};
+};
+
+template <> struct FixupInfo<Thumb_MovwPrelNC> : public FixupInfoThumbMov {
+ static constexpr HalfWords Opcode{0xf240, 0x0000};
+};
+
/// Helper function to read the initial addend for Data-class relocations.
Expected<int64_t> readAddendData(LinkGraph &G, Block &B, Edge::OffsetT Offset,
Edge::Kind Kind);
diff --git a/llvm/lib/ExecutionEngine/JITLink/CMakeLists.txt b/llvm/lib/ExecutionEngine/JITLink/CMakeLists.txt
index 524bd9fad8e53e..c5482bb2ec69b7 100644
--- a/llvm/lib/ExecutionEngine/JITLink/CMakeLists.txt
+++ b/llvm/lib/ExecutionEngine/JITLink/CMakeLists.txt
@@ -1,11 +1,7 @@
set(LLVM_TARGET_DEFINITIONS COFFOptions.td)
tablegen(LLVM COFFOptions.inc -gen-opt-parser-defs)
+add_public_tablegen_target(JITLinkCOFFTableGen)
-include_directories(${PROJECT_SOURCE_DIR}/lib/Target/ARM/)
-set(LLVM_TARGET_DEFINITIONS ${PROJECT_SOURCE_DIR}/lib/Target/ARM/ARM.td)
-tablegen(LLVM JITLinkAArch32.inc -gen-jitlink-aarch32-instr-info)
-
-add_public_tablegen_target(JITLinkTableGen)
add_llvm_component_library(LLVMJITLink
DWARFRecordSectionSplitter.cpp
@@ -53,7 +49,8 @@ add_llvm_component_library(LLVMJITLink
DEPENDS
intrinsics_gen
- JITLinkTableGen
+ JITLinkCOFFTableGen
+ JITLinkAArch32TableGen
LINK_COMPONENTS
BinaryFormat
diff --git a/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp b/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp
index 0a705fcde89479..d0aa20be19f90b 100644
--- a/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp
@@ -21,8 +21,6 @@
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MathExtras.h"
-#include "JITLinkAArch32.inc"
-
#define DEBUG_TYPE "jitlink"
namespace llvm {
@@ -319,7 +317,7 @@ static Error checkOpcode(LinkGraph &G, const ArmRelocation &R,
assert(Kind >= FirstArmRelocation && Kind <= LastArmRelocation &&
"Edge kind must be Arm relocation");
const FixupInfoBase *Entry = DynFixupInfos->getEntry(Kind);
- const FixupInfoArm &Info = *static_cast<const FixupInfoArm *>(Entry);
+ const FixupInfoArmBase &Info = *static_cast<const FixupInfoArmBase *>(Entry);
assert(Info.checkOpcode && "Opcode check is mandatory for Arm edges");
if (!Info.checkOpcode(R.Wd))
return makeUnexpectedOpcodeError(G, R, Kind);
diff --git a/llvm/unittests/ExecutionEngine/JITLink/AArch32Tests.cpp b/llvm/unittests/ExecutionEngine/JITLink/AArch32Tests.cpp
index 46307db539b8d3..28045bfedb51e3 100644
--- a/llvm/unittests/ExecutionEngine/JITLink/AArch32Tests.cpp
+++ b/llvm/unittests/ExecutionEngine/JITLink/AArch32Tests.cpp
@@ -11,8 +11,6 @@
#include "gtest/gtest.h"
-#include "JITLinkAArch32.inc"
-
using namespace llvm;
using namespace llvm::jitlink;
using namespace llvm::jitlink::aarch32;
@@ -76,7 +74,7 @@ TEST(AArch32_ELF, DynFixupInfos) {
for (Edge::Kind K = FirstArmRelocation; K < LastArmRelocation; K += 1) {
const auto *Info = FixupInfoBase::getDynFixupInfo(K);
EXPECT_NE(Info, nullptr);
- const auto *InfoArm = static_cast<const FixupInfoArm *>(Info);
+ const auto *InfoArm = static_cast<const FixupInfoArmBase *>(Info);
EXPECT_NE(InfoArm->checkOpcode, nullptr);
EXPECT_FALSE(InfoArm->checkOpcode(0x00000000));
}
diff --git a/llvm/unittests/ExecutionEngine/JITLink/JITLinkAArch32.inc b/llvm/unittests/ExecutionEngine/JITLink/JITLinkAArch32.inc
deleted file mode 100644
index aaff38b8c5ad85..00000000000000
--- a/llvm/unittests/ExecutionEngine/JITLink/JITLinkAArch32.inc
+++ /dev/null
@@ -1,58 +0,0 @@
-/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
-|* *|
-|* Skeleton data structures *|
-|* *|
-|* Automatically generated file, do not edit! *|
-|* *|
-\*===----------------------------------------------------------------------===*/
-
-using namespace llvm::jitlink::aarch32;
-
-namespace llvm {
-namespace jitlink {
-namespace aarch32 {
-template <> struct FixupInfo<Arm_MovwAbsNC> : public FixupInfoArm {
- static constexpr uint32_t Opcode = 0x3000000;
- static constexpr uint32_t OpcodeMask = 0xff00000;
- static constexpr uint32_t ImmMask = 0xf0fff;
- static constexpr uint32_t RegMask = 0xf000;
-};
-
-template <> struct FixupInfo<Arm_MovtAbs> : public FixupInfoArm {
- static constexpr uint32_t Opcode = 0x3400000;
- static constexpr uint32_t OpcodeMask = 0xff00000;
- static constexpr uint32_t ImmMask = 0xf0fff;
- static constexpr uint32_t RegMask = 0xf000;
-};
-
-template <> struct FixupInfo<Thumb_MovwAbsNC> : public FixupInfoThumb {
- static constexpr HalfWords Opcode{0xf240, 0x0};
- static constexpr HalfWords OpcodeMask{0xfbf0, 0x8000};
- static constexpr HalfWords ImmMask{0x40f, 0x70ff};
- static constexpr HalfWords RegMask{0x0, 0xf00};
-};
-
-template <> struct FixupInfo<Thumb_MovtAbs> : public FixupInfoThumb {
- static constexpr HalfWords Opcode{0xf2c0, 0x0};
- static constexpr HalfWords OpcodeMask{0xfbf0, 0x8000};
- static constexpr HalfWords ImmMask{0x40f, 0x70ff};
- static constexpr HalfWords RegMask{0x0, 0xf00};
-};
-
-template <> struct FixupInfo<Thumb_MovwPrelNC> : public FixupInfoThumb {
- static constexpr HalfWords Opcode{0xf240, 0x0};
- static constexpr HalfWords OpcodeMask{0xfbf0, 0x8000};
- static constexpr HalfWords ImmMask{0x40f, 0x70ff};
- static constexpr HalfWords RegMask{0x0, 0xf00};
-};
-
-template <> struct FixupInfo<Thumb_MovtPrel> : public FixupInfoThumb {
- static constexpr HalfWords Opcode{0xf2c0, 0x0};
- static constexpr HalfWords OpcodeMask{0xfbf0, 0x8000};
- static constexpr HalfWords ImmMask{0x40f, 0x70ff};
- static constexpr HalfWords RegMask{0x0, 0xf00};
-};
-
-} // namespace aarch32
-} // namespace jitlink
-} // namespace llvm
diff --git a/llvm/utils/TableGen/CMakeLists.txt b/llvm/utils/TableGen/CMakeLists.txt
index 0232003a7cd66a..13e102485a3b9f 100644
--- a/llvm/utils/TableGen/CMakeLists.txt
+++ b/llvm/utils/TableGen/CMakeLists.txt
@@ -5,6 +5,7 @@ add_llvm_library(LLVMTableGenCommon STATIC OBJECT EXCLUDE_FROM_ALL
CodeGenIntrinsics.cpp
DirectiveEmitter.cpp
IntrinsicEmitter.cpp
+ JITLinkAArch32InstrInfo.cpp
RISCVTargetDefEmitter.cpp
SDNodeProperties.cpp
VTEmitter.cpp
@@ -66,7 +67,6 @@ add_tablegen(llvm-tblgen LLVM
InfoByHwMode.cpp
InstrInfoEmitter.cpp
InstrDocsEmitter.cpp
- JITLinkAArch32InstrInfo.cpp
OptEmitter.cpp
OptParserEmitter.cpp
OptRSTEmitter.cpp
@@ -91,10 +91,6 @@ add_tablegen(llvm-tblgen LLVM
WebAssemblyDisassemblerEmitter.cpp
$<TARGET_OBJECTS:obj.LLVMTableGenCommon>
- ADDITIONAL_HEADER_DIRS
- ${LLVM_MAIN_INCLUDE_DIR}/llvm/ExecutionEngine/JITLink
-
-
DEPENDS
intrinsics_gen # via llvm-min-tablegen
)
diff --git a/llvm/utils/TableGen/JITLinkAArch32InstrInfo.cpp b/llvm/utils/TableGen/JITLinkAArch32InstrInfo.cpp
index 62468ed057d431..54d149187eb8a6 100644
--- a/llvm/utils/TableGen/JITLinkAArch32InstrInfo.cpp
+++ b/llvm/utils/TableGen/JITLinkAArch32InstrInfo.cpp
@@ -9,20 +9,11 @@
// This Tablegen backend emits instruction encodings of AArch32 for JITLink.
//
//===----------------------------------------------------------------------===//
-#include "CodeGenDAGPatterns.h"
-#include "CodeGenInstruction.h"
-#include "CodeGenSchedule.h"
-#include "CodeGenTarget.h"
-#include "PredicateExpander.h"
-#include "SequenceToOffsetTable.h"
-#include "SubtargetFeatureInfo.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ExecutionEngine/JITLink/aarch32.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/TableGen/Error.h"
+#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/TableGenBackend.h"
-#define DEBUG_TYPE "jitlink-aarch32-tblgen"
+#define DEBUG_TYPE "jitlink-instr-info"
namespace llvm {
class RecordKeeper;
@@ -30,64 +21,9 @@ class raw_ostream;
} // namespace llvm
using namespace llvm;
-using namespace llvm::jitlink;
-using namespace llvm::jitlink::aarch32;
namespace {
-// Any helper data structures can be defined here. Some backends use
-// structs to collect information from the records.
-
-Twine getEdgeKindName(Edge::Kind K) {
-#define KIND_NAME_CASE(K) \
- case K: \
- return #K;
-
- switch (K) {
- KIND_NAME_CASE(Data_Delta32)
- KIND_NAME_CASE(Data_Pointer32)
- KIND_NAME_CASE(Arm_Call)
- KIND_NAME_CASE(Arm_Jump24)
- KIND_NAME_CASE(Arm_MovwAbsNC)
- KIND_NAME_CASE(Arm_MovtAbs)
- KIND_NAME_CASE(Thumb_Call)
- KIND_NAME_CASE(Thumb_Jump24)
- KIND_NAME_CASE(Thumb_MovwAbsNC)
- KIND_NAME_CASE(Thumb_MovtAbs)
- KIND_NAME_CASE(Thumb_MovwPrelNC)
- KIND_NAME_CASE(Thumb_MovtPrel)
- default:
- return "";
- }
-#undef KIND_NAME_CASE
-}
-
-static StringRef getInstrFromJITLinkEdgeKind(Edge::Kind Kind) {
- /// Translate from JITLink-internal edge kind to TableGen instruction names.
- switch (Kind) {
- case Arm_Call:
- return "";
- case aarch32::Arm_Jump24:
- return "";
- case aarch32::Arm_MovwAbsNC:
- return "MOVi16";
- case aarch32::Arm_MovtAbs:
- return "MOVTi16";
- case aarch32::Thumb_Call:
- return "";
- case aarch32::Thumb_Jump24:
- return "";
- case aarch32::Thumb_MovwAbsNC:
- case aarch32::Thumb_MovwPrelNC:
- return "t2MOVi16";
- case aarch32::Thumb_MovtAbs:
- case aarch32::Thumb_MovtPrel:
- return "t2MOVTi16";
- default:
- return "";
- }
-}
-
struct InstrInfo {
uint32_t Opcode = 0;
uint32_t OpcodeMask = 0;
@@ -119,78 +55,43 @@ static void extractBits(BitsInit &InstBits, InstrInfo &II) {
"Masks have intersecting bits");
}
-static void writeArmElement(raw_ostream &OS, Twine InfoName, uint32_t Value,
- int Indentation = 2) {
- OS.indent(Indentation) << "static constexpr uint32_t " + InfoName + " = 0x";
- OS.write_hex(Value) << ";\n";
-}
-
-static void writeArmInfo(raw_ostream &OS, InstrInfo &II, Edge::Kind Kind) {
- OS << "template <> struct FixupInfo<" + getEdgeKindName(Kind) +
- "> : public FixupInfoArm {\n";
- writeArmElement(OS, "Opcode", II.Opcode);
- writeArmElement(OS, "OpcodeMask", II.OpcodeMask);
- writeArmElement(OS, "ImmMask", II.ImmMask);
- writeArmElement(OS, "RegMask", II.RegMask);
- OS << "};\n\n";
+static void writeInstrInfo(raw_ostream &OS, const InstrInfo &II,
+ const std::string &InstName) {
+ OS << "GET_INSTR(" << InstName << ", 0x";
+ OS.write_hex(II.Opcode) << ", 0x";
+ OS.write_hex(II.OpcodeMask) << ", 0x";
+ OS.write_hex(II.ImmMask) << ", 0x";
+ OS.write_hex(II.RegMask) << ")\n";
}
-static void writeThumbElement(raw_ostream &OS, Twine InfoName, uint32_t Value,
- int Indentation = 2) {
- OS.indent(Indentation) << "static constexpr HalfWords " + InfoName + " {0x";
- OS.write_hex(Value >> 16) << ", 0x";
- OS.write_hex(Value & 0x0000FFFF) << "};\n";
-}
-
-static void writeThumbInfo(raw_ostream &OS, InstrInfo &II, Edge::Kind Kind) {
- OS << "template <> struct FixupInfo<" + getEdgeKindName(Kind) +
- "> : public FixupInfoThumb {\n";
- writeThumbElement(OS, "Opcode", II.Opcode);
- writeThumbElement(OS, "OpcodeMask", II.OpcodeMask);
- writeThumbElement(OS, "ImmMask", II.ImmMask);
- writeThumbElement(OS, "RegMask", II.RegMask);
- OS << "};\n\n";
-}
-
-class JITLinkAArch32Emitter {
+class JITLinkEmitter {
private:
RecordKeeper &Records;
public:
- JITLinkAArch32Emitter(RecordKeeper &RK) : Records(RK) {}
+ JITLinkEmitter(RecordKeeper &RK) : Records(RK) {}
void run(raw_ostream &OS);
-}; // emitter class
-
-} // anonymous namespace
-
-void JITLinkAArch32Emitter::run(raw_ostream &OS) {
- emitSourceFileHeader("Skeleton data structures", OS);
- OS << "using namespace llvm::jitlink::aarch32;\n\n";
- OS << "namespace llvm {\n";
- OS << "namespace jitlink {\n";
- OS << "namespace aarch32 {\n";
- // const auto &Instructions = Records.getAllDerivedDefinitions("Instruction");
- for (Edge::Kind JITLinkEdgeKind = aarch32::FirstArmRelocation;
- JITLinkEdgeKind <= aarch32::LastThumbRelocation; JITLinkEdgeKind += 1) {
- auto InstName = getInstrFromJITLinkEdgeKind(JITLinkEdgeKind);
- if (InstName.empty())
+};
+
+void JITLinkEmitter::run(raw_ostream &OS) {
+ emitSourceFileHeader("Instruction Encoding Information", OS);
+
+ OS << "#ifdef GET_INSTR // (Opc, Opc_Mask, Imm_Mask, Reg_Mask)\n";
+ auto RecordsList = Records.getAllDerivedDefinitions("Instruction");
+ for (auto *InstRecord : RecordsList) {
+ if (InstRecord->getValueAsBit("isPseudo"))
continue;
- auto *InstRecord = Records.getDef(InstName);
auto *InstBits = InstRecord->getValueAsBitsInit("Inst");
InstrInfo II;
extractBits(*InstBits, II);
- if (JITLinkEdgeKind > LastArmRelocation)
- writeThumbInfo(OS, II, JITLinkEdgeKind);
- else
- writeArmInfo(OS, II, JITLinkEdgeKind);
+ writeInstrInfo(OS, II, InstRecord->getNameInitAsString());
}
- OS << "} //aarch32\n";
- OS << "} //jitlink\n";
- OS << "} //llvm\n";
+ OS << "#endif\n";
}
-static TableGen::Emitter::OptClass<JITLinkAArch32Emitter>
+static TableGen::Emitter::OptClass<JITLinkEmitter>
X("gen-jitlink-aarch32-instr-info",
- "Generate JITLink AArch32 Instruction Information");
+ "Generate JITLink Instruction Information");
+} // namespace
>From f6b812d78ed98239986c37eac63b9406b92c6e1a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eymen=20=C3=9Cnay?= <eymenunay at outlook.com>
Date: Sun, 7 Jan 2024 16:18:08 +0300
Subject: [PATCH 4/5] Remove unused header
---
llvm/utils/TableGen/JITLinkAArch32InstrInfo.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/llvm/utils/TableGen/JITLinkAArch32InstrInfo.cpp b/llvm/utils/TableGen/JITLinkAArch32InstrInfo.cpp
index 54d149187eb8a6..151b5aaafa15b4 100644
--- a/llvm/utils/TableGen/JITLinkAArch32InstrInfo.cpp
+++ b/llvm/utils/TableGen/JITLinkAArch32InstrInfo.cpp
@@ -9,7 +9,6 @@
// This Tablegen backend emits instruction encodings of AArch32 for JITLink.
//
//===----------------------------------------------------------------------===//
-#include "llvm/ADT/StringRef.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/TableGenBackend.h"
>From ce1db9d8b03a52d872d0afeb66c81d5142079c3e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eymen=20=C3=9Cnay?= <eymenunay at outlook.com>
Date: Fri, 26 Jan 2024 21:09:53 +0300
Subject: [PATCH 5/5] Reduce generated instructions by selecting mov and branch
only
---
.../JITLink/JITLinkAArch32.inc.example | 33 +++++++++++++++++++
.../TableGen/JITLinkAArch32InstrInfo.cpp | 25 +++++++++++---
2 files changed, 53 insertions(+), 5 deletions(-)
create mode 100644 llvm/include/llvm/ExecutionEngine/JITLink/JITLinkAArch32.inc.example
diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/JITLinkAArch32.inc.example b/llvm/include/llvm/ExecutionEngine/JITLink/JITLinkAArch32.inc.example
new file mode 100644
index 00000000000000..7541fbdc82ed02
--- /dev/null
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/JITLinkAArch32.inc.example
@@ -0,0 +1,33 @@
+/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
+|* *|
+|* Instruction Encoding Information *|
+|* *|
+|* Automatically generated file, do not edit! *|
+|* *|
+\*===----------------------------------------------------------------------===*/
+
+#ifdef GET_INSTR // (Opc, Opc_Mask, Imm_Mask, Reg_Mask)
+GET_INSTR(BL, 0xeb000000, 0xff000000, 0xffffff, 0x0)
+GET_INSTR(BLX, 0xe12fff30, 0xfffffff0, 0xf, 0x0)
+GET_INSTR(BLX_pred, 0x12fff30, 0xffffff0, 0xf, 0x0)
+GET_INSTR(BLXi, 0xfa000000, 0xfe000000, 0x0, 0x0)
+GET_INSTR(BL_pred, 0xb000000, 0xf000000, 0xffffff, 0x0)
+GET_INSTR(HVC, 0xe1400070, 0xfff000f0, 0xfff0f, 0x0)
+GET_INSTR(MOVTi16, 0x3400000, 0xff00000, 0xf0fff, 0xf000)
+GET_INSTR(MOVi, 0x3a00000, 0xfef0000, 0xfff, 0xf000)
+GET_INSTR(MOVi16, 0x3000000, 0xff00000, 0xf0fff, 0xf000)
+GET_INSTR(MVNi, 0x3e00000, 0xfef0000, 0xfff, 0xf000)
+GET_INSTR(SVC, 0xf000000, 0xf000000, 0x0, 0x0)
+GET_INSTR(t2HVC, 0xf7e08000, 0xfff0f000, 0x0, 0x0)
+GET_INSTR(t2MOVTi16, 0xf2c00000, 0xfbf08000, 0x40f70ff, 0xf00)
+GET_INSTR(t2MOVi, 0xf04f0000, 0xfbef8000, 0x40070ff, 0xf00)
+GET_INSTR(t2MOVi16, 0xf2400000, 0xfbf08000, 0x40f70ff, 0xf00)
+GET_INSTR(t2MVNi, 0xf06f0000, 0xfbef8000, 0x40070ff, 0xf00)
+GET_INSTR(t2SMC, 0xf7f08000, 0xfff0f000, 0x0, 0x0)
+GET_INSTR(tBL, 0xf000d000, 0xf800d000, 0x7ff2fff, 0x0)
+GET_INSTR(tBLXNSr, 0x4784, 0xffffff87, 0x78, 0x0)
+GET_INSTR(tBLXi, 0xf000c000, 0xf800d001, 0x7ff2ffe, 0x0)
+GET_INSTR(tBLXr, 0x4780, 0xffffff87, 0x78, 0x0)
+GET_INSTR(tMOVi8, 0x2000, 0xfffff800, 0x0, 0x700)
+GET_INSTR(tSVC, 0xdf00, 0xffffff00, 0xff, 0x0)
+#endif
diff --git a/llvm/utils/TableGen/JITLinkAArch32InstrInfo.cpp b/llvm/utils/TableGen/JITLinkAArch32InstrInfo.cpp
index 151b5aaafa15b4..5d283ac71386ac 100644
--- a/llvm/utils/TableGen/JITLinkAArch32InstrInfo.cpp
+++ b/llvm/utils/TableGen/JITLinkAArch32InstrInfo.cpp
@@ -9,6 +9,7 @@
// This Tablegen backend emits instruction encodings of AArch32 for JITLink.
//
//===----------------------------------------------------------------------===//
+#include "llvm/Support/Debug.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/TableGenBackend.h"
@@ -37,7 +38,7 @@ static void extractBits(BitsInit &InstBits, InstrInfo &II) {
if (auto *VarBit = dyn_cast<VarBitInit>(Bit)) {
// Check if the VarBit is for 'imm' or 'Rd'
std::string VarName = VarBit->getBitVar()->getAsUnquotedString();
- if (VarName == "imm") {
+ if (VarName == "imm" || VarName == "func") {
II.ImmMask |= 1 << i;
} else if (VarName == "Rd") {
II.RegMask |= 1 << i;
@@ -81,10 +82,24 @@ void JITLinkEmitter::run(raw_ostream &OS) {
for (auto *InstRecord : RecordsList) {
if (InstRecord->getValueAsBit("isPseudo"))
continue;
- auto *InstBits = InstRecord->getValueAsBitsInit("Inst");
- InstrInfo II;
- extractBits(*InstBits, II);
- writeInstrInfo(OS, II, InstRecord->getNameInitAsString());
+ LLVM_DEBUG(dbgs() << "Processing " << InstRecord->getNameInitAsString()
+ << "\n");
+ if (InstRecord->getValueAsBit("isMoveImm") ||
+ InstRecord->getValueAsBit("isCall") ||
+ // FIXME movt for ARM and Thumb2 do not have their isMovImm flags set
+ // so we add these conditionals
+ InstRecord->getNameInitAsString() == "MOVTi16" ||
+ InstRecord->getNameInitAsString() == "t2MOVTi16") {
+ LLVM_DEBUG(for (const auto &Val
+ : InstRecord->getValues()) {
+ dbgs() << "Field: " << Val.getNameInitAsString() << " = "
+ << Val.getValue()->getAsUnquotedString() << "\n";
+ });
+ auto *InstBits = InstRecord->getValueAsBitsInit("Inst");
+ InstrInfo II;
+ extractBits(*InstBits, II);
+ writeInstrInfo(OS, II, InstRecord->getNameInitAsString());
+ }
}
OS << "#endif\n";
More information about the llvm-commits
mailing list