[llvm] Ws lend (PR #136643)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 21 19:36:17 PDT 2025
https://github.com/GYXgo created https://github.com/llvm/llvm-project/pull/136643
None
>From 001f2be21a310de225c7ef853bbedc3d48f7e2f4 Mon Sep 17 00:00:00 2001
From: gyx <gyx5252 at 163.com>
Date: Wed, 26 Mar 2025 22:23:16 +0800
Subject: [PATCH 1/4] =?UTF-8?q?=E6=B7=BB=E5=8A=A0PE=E7=9B=AE=E6=A0=87?=
=?UTF-8?q?=E6=9E=B6=E6=9E=84=E6=94=AF=E6=8C=81=EF=BC=8C=E5=8C=85=E6=8B=AC?=
=?UTF-8?q?=E7=9B=B8=E5=85=B3=E7=9A=84CMake=E9=85=8D=E7=BD=AE=E5=92=8C?=
=?UTF-8?q?=E6=BA=90=E6=96=87=E4=BB=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
llvm/CPackConfig.cmake | 77 +++++++++++++++++
llvm/CPackSourceConfig.cmake | 85 +++++++++++++++++++
llvm/include/llvm/TargetParser/Triple.h | 3 +-
llvm/lib/Target/PE/AsmParser/CMakeLists.txt | 0
llvm/lib/Target/PE/CMakeLists.txt | 62 ++++++++++++++
.../lib/Target/PE/Disassembler/CMakeLists.txt | 0
.../lib/Target/PE/MCTargetDesc/CMakeLists.txt | 5 ++
.../Target/PE/MCTargetDesc/PEMCTargetDesc.cpp | 3 +
llvm/lib/Target/PE/PE.h | 14 +++
llvm/lib/Target/PE/PE.td | 38 +++++++++
llvm/lib/Target/PE/PEFrameLowering.cpp | 8 ++
llvm/lib/Target/PE/PEISelDAGToDAG.cpp | 8 ++
llvm/lib/Target/PE/PEISelLowering.cpp | 6 ++
llvm/lib/Target/PE/PEInstrInfo.cpp | 8 ++
llvm/lib/Target/PE/PERegisterInfo.cpp | 6 ++
llvm/lib/Target/PE/PESubtarget.cpp | 6 ++
llvm/lib/Target/PE/PETargetMachine.cpp | 5 ++
llvm/lib/Target/PE/TargetInfo/CMakeLists.txt | 7 ++
.../lib/Target/PE/TargetInfo/PETargetInfo.cpp | 22 +++++
llvm/lib/Target/PE/TargetInfo/PETargetInfo.h | 12 +++
llvm/lib/TargetParser/Triple.cpp | 9 ++
21 files changed, 383 insertions(+), 1 deletion(-)
create mode 100644 llvm/CPackConfig.cmake
create mode 100644 llvm/CPackSourceConfig.cmake
create mode 100644 llvm/lib/Target/PE/AsmParser/CMakeLists.txt
create mode 100644 llvm/lib/Target/PE/CMakeLists.txt
create mode 100644 llvm/lib/Target/PE/Disassembler/CMakeLists.txt
create mode 100644 llvm/lib/Target/PE/MCTargetDesc/CMakeLists.txt
create mode 100644 llvm/lib/Target/PE/MCTargetDesc/PEMCTargetDesc.cpp
create mode 100644 llvm/lib/Target/PE/PE.h
create mode 100644 llvm/lib/Target/PE/PE.td
create mode 100644 llvm/lib/Target/PE/PEFrameLowering.cpp
create mode 100644 llvm/lib/Target/PE/PEISelDAGToDAG.cpp
create mode 100644 llvm/lib/Target/PE/PEISelLowering.cpp
create mode 100644 llvm/lib/Target/PE/PEInstrInfo.cpp
create mode 100644 llvm/lib/Target/PE/PERegisterInfo.cpp
create mode 100644 llvm/lib/Target/PE/PESubtarget.cpp
create mode 100644 llvm/lib/Target/PE/PETargetMachine.cpp
create mode 100644 llvm/lib/Target/PE/TargetInfo/CMakeLists.txt
create mode 100644 llvm/lib/Target/PE/TargetInfo/PETargetInfo.cpp
create mode 100644 llvm/lib/Target/PE/TargetInfo/PETargetInfo.h
diff --git a/llvm/CPackConfig.cmake b/llvm/CPackConfig.cmake
new file mode 100644
index 0000000000000..ff201eea83dbf
--- /dev/null
+++ b/llvm/CPackConfig.cmake
@@ -0,0 +1,77 @@
+# This file will be configured to contain variables for CPack. These variables
+# should be set in the CMake list file of the project before CPack module is
+# included. The list of available CPACK_xxx variables and their associated
+# documentation may be obtained using
+# cpack --help-variable-list
+#
+# Some variables are common to all generators (e.g. CPACK_PACKAGE_NAME)
+# and some are specific to a generator
+# (e.g. CPACK_NSIS_EXTRA_INSTALL_COMMANDS). The generator specific variables
+# usually begin with CPACK_<GENNAME>_xxxx.
+
+
+set(CPACK_BINARY_DEB "OFF")
+set(CPACK_BINARY_FREEBSD "OFF")
+set(CPACK_BINARY_IFW "OFF")
+set(CPACK_BINARY_NSIS "OFF")
+set(CPACK_BINARY_RPM "OFF")
+set(CPACK_BINARY_STGZ "ON")
+set(CPACK_BINARY_TBZ2 "OFF")
+set(CPACK_BINARY_TGZ "ON")
+set(CPACK_BINARY_TXZ "OFF")
+set(CPACK_BINARY_TZ "ON")
+set(CPACK_BUILD_SOURCE_DIRS "/home/gyx/work/LLVM-project/llvm;/home/gyx/work/LLVM-project/llvm")
+set(CPACK_CMAKE_GENERATOR "Ninja")
+set(CPACK_COMPONENTS_ALL "")
+set(CPACK_COMPONENT_UNSPECIFIED_HIDDEN "TRUE")
+set(CPACK_COMPONENT_UNSPECIFIED_REQUIRED "TRUE")
+set(CPACK_DEFAULT_PACKAGE_DESCRIPTION_FILE "/usr/local/share/cmake-3.20/Templates/CPack.GenericDescription.txt")
+set(CPACK_DEFAULT_PACKAGE_DESCRIPTION_SUMMARY "LLVM built using CMake")
+set(CPACK_GENERATOR "STGZ;TGZ;TZ")
+set(CPACK_INSTALL_CMAKE_PROJECTS "/home/gyx/work/LLVM-project/llvm;LLVM;ALL;/")
+set(CPACK_INSTALL_PREFIX "/usr/local")
+set(CPACK_MODULE_PATH "/home/gyx/work/LLVM-project/llvm/cmake;/home/gyx/work/LLVM-project/llvm/cmake/modules;/home/gyx/work/LLVM-project/llvm/../cmake/Modules")
+set(CPACK_NSIS_DISPLAY_NAME "LLVM")
+set(CPACK_NSIS_INSTALLER_ICON_CODE "")
+set(CPACK_NSIS_INSTALLER_MUI_ICON_CODE "")
+set(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES")
+set(CPACK_NSIS_PACKAGE_NAME "LLVM")
+set(CPACK_NSIS_UNINSTALL_NAME "Uninstall")
+set(CPACK_OUTPUT_CONFIG_FILE "/home/gyx/work/LLVM-project/llvm/CPackConfig.cmake")
+set(CPACK_PACKAGE_DEFAULT_LOCATION "/")
+set(CPACK_PACKAGE_DESCRIPTION_FILE "/usr/local/share/cmake-3.20/Templates/CPack.GenericDescription.txt")
+set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "LLVM built using CMake")
+set(CPACK_PACKAGE_FILE_NAME "LLVM-20.0.0git-Linux")
+set(CPACK_PACKAGE_INSTALL_DIRECTORY "LLVM")
+set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "LLVM")
+set(CPACK_PACKAGE_NAME "LLVM")
+set(CPACK_PACKAGE_RELOCATABLE "true")
+set(CPACK_PACKAGE_VENDOR "LLVM")
+set(CPACK_PACKAGE_VERSION "20.0.0git")
+set(CPACK_PACKAGE_VERSION_MAJOR "20")
+set(CPACK_PACKAGE_VERSION_MINOR "0")
+set(CPACK_PACKAGE_VERSION_PATCH "0")
+set(CPACK_RESOURCE_FILE_LICENSE "/home/gyx/work/LLVM-project/llvm/LICENSE.TXT")
+set(CPACK_RESOURCE_FILE_README "/usr/local/share/cmake-3.20/Templates/CPack.GenericDescription.txt")
+set(CPACK_RESOURCE_FILE_WELCOME "/usr/local/share/cmake-3.20/Templates/CPack.GenericWelcome.txt")
+set(CPACK_SET_DESTDIR "OFF")
+set(CPACK_SOURCE_GENERATOR "TBZ2;TGZ;TXZ;TZ")
+set(CPACK_SOURCE_OUTPUT_CONFIG_FILE "/home/gyx/work/LLVM-project/llvm/CPackSourceConfig.cmake")
+set(CPACK_SOURCE_RPM "OFF")
+set(CPACK_SOURCE_TBZ2 "ON")
+set(CPACK_SOURCE_TGZ "ON")
+set(CPACK_SOURCE_TXZ "ON")
+set(CPACK_SOURCE_TZ "ON")
+set(CPACK_SOURCE_ZIP "OFF")
+set(CPACK_SYSTEM_NAME "Linux")
+set(CPACK_THREADS "1")
+set(CPACK_TOPLEVEL_TAG "Linux")
+set(CPACK_WIX_SIZEOF_VOID_P "8")
+
+if(NOT CPACK_PROPERTIES_FILE)
+ set(CPACK_PROPERTIES_FILE "/home/gyx/work/LLVM-project/llvm/CPackProperties.cmake")
+endif()
+
+if(EXISTS ${CPACK_PROPERTIES_FILE})
+ include(${CPACK_PROPERTIES_FILE})
+endif()
diff --git a/llvm/CPackSourceConfig.cmake b/llvm/CPackSourceConfig.cmake
new file mode 100644
index 0000000000000..563354e08b3de
--- /dev/null
+++ b/llvm/CPackSourceConfig.cmake
@@ -0,0 +1,85 @@
+# This file will be configured to contain variables for CPack. These variables
+# should be set in the CMake list file of the project before CPack module is
+# included. The list of available CPACK_xxx variables and their associated
+# documentation may be obtained using
+# cpack --help-variable-list
+#
+# Some variables are common to all generators (e.g. CPACK_PACKAGE_NAME)
+# and some are specific to a generator
+# (e.g. CPACK_NSIS_EXTRA_INSTALL_COMMANDS). The generator specific variables
+# usually begin with CPACK_<GENNAME>_xxxx.
+
+
+set(CPACK_BINARY_DEB "OFF")
+set(CPACK_BINARY_FREEBSD "OFF")
+set(CPACK_BINARY_IFW "OFF")
+set(CPACK_BINARY_NSIS "OFF")
+set(CPACK_BINARY_RPM "OFF")
+set(CPACK_BINARY_STGZ "ON")
+set(CPACK_BINARY_TBZ2 "OFF")
+set(CPACK_BINARY_TGZ "ON")
+set(CPACK_BINARY_TXZ "OFF")
+set(CPACK_BINARY_TZ "ON")
+set(CPACK_BUILD_SOURCE_DIRS "/home/gyx/work/LLVM-project/llvm;/home/gyx/work/LLVM-project/llvm")
+set(CPACK_CMAKE_GENERATOR "Ninja")
+set(CPACK_COMPONENTS_ALL "")
+set(CPACK_COMPONENT_UNSPECIFIED_HIDDEN "TRUE")
+set(CPACK_COMPONENT_UNSPECIFIED_REQUIRED "TRUE")
+set(CPACK_DEFAULT_PACKAGE_DESCRIPTION_FILE "/usr/local/share/cmake-3.20/Templates/CPack.GenericDescription.txt")
+set(CPACK_DEFAULT_PACKAGE_DESCRIPTION_SUMMARY "LLVM built using CMake")
+set(CPACK_GENERATOR "TBZ2;TGZ;TXZ;TZ")
+set(CPACK_IGNORE_FILES "/CVS/;/\\.svn/;/\\.bzr/;/\\.hg/;/\\.git/;\\.swp\$;\\.#;/#")
+set(CPACK_INSTALLED_DIRECTORIES "/home/gyx/work/LLVM-project/llvm;/")
+set(CPACK_INSTALL_CMAKE_PROJECTS "")
+set(CPACK_INSTALL_PREFIX "/usr/local")
+set(CPACK_MODULE_PATH "/home/gyx/work/LLVM-project/llvm/cmake;/home/gyx/work/LLVM-project/llvm/cmake/modules;/home/gyx/work/LLVM-project/llvm/../cmake/Modules")
+set(CPACK_NSIS_DISPLAY_NAME "LLVM")
+set(CPACK_NSIS_INSTALLER_ICON_CODE "")
+set(CPACK_NSIS_INSTALLER_MUI_ICON_CODE "")
+set(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES")
+set(CPACK_NSIS_PACKAGE_NAME "LLVM")
+set(CPACK_NSIS_UNINSTALL_NAME "Uninstall")
+set(CPACK_OUTPUT_CONFIG_FILE "/home/gyx/work/LLVM-project/llvm/CPackConfig.cmake")
+set(CPACK_PACKAGE_DEFAULT_LOCATION "/")
+set(CPACK_PACKAGE_DESCRIPTION_FILE "/usr/local/share/cmake-3.20/Templates/CPack.GenericDescription.txt")
+set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "LLVM built using CMake")
+set(CPACK_PACKAGE_FILE_NAME "LLVM-20.0.0git-Source")
+set(CPACK_PACKAGE_INSTALL_DIRECTORY "LLVM")
+set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "LLVM")
+set(CPACK_PACKAGE_NAME "LLVM")
+set(CPACK_PACKAGE_RELOCATABLE "true")
+set(CPACK_PACKAGE_VENDOR "LLVM")
+set(CPACK_PACKAGE_VERSION "20.0.0git")
+set(CPACK_PACKAGE_VERSION_MAJOR "20")
+set(CPACK_PACKAGE_VERSION_MINOR "0")
+set(CPACK_PACKAGE_VERSION_PATCH "0")
+set(CPACK_RESOURCE_FILE_LICENSE "/home/gyx/work/LLVM-project/llvm/LICENSE.TXT")
+set(CPACK_RESOURCE_FILE_README "/usr/local/share/cmake-3.20/Templates/CPack.GenericDescription.txt")
+set(CPACK_RESOURCE_FILE_WELCOME "/usr/local/share/cmake-3.20/Templates/CPack.GenericWelcome.txt")
+set(CPACK_RPM_PACKAGE_SOURCES "ON")
+set(CPACK_SET_DESTDIR "OFF")
+set(CPACK_SOURCE_GENERATOR "TBZ2;TGZ;TXZ;TZ")
+set(CPACK_SOURCE_IGNORE_FILES "/CVS/;/\\.svn/;/\\.bzr/;/\\.hg/;/\\.git/;\\.swp\$;\\.#;/#")
+set(CPACK_SOURCE_INSTALLED_DIRECTORIES "/home/gyx/work/LLVM-project/llvm;/")
+set(CPACK_SOURCE_OUTPUT_CONFIG_FILE "/home/gyx/work/LLVM-project/llvm/CPackSourceConfig.cmake")
+set(CPACK_SOURCE_PACKAGE_FILE_NAME "LLVM-20.0.0git-Source")
+set(CPACK_SOURCE_RPM "OFF")
+set(CPACK_SOURCE_TBZ2 "ON")
+set(CPACK_SOURCE_TGZ "ON")
+set(CPACK_SOURCE_TOPLEVEL_TAG "Linux-Source")
+set(CPACK_SOURCE_TXZ "ON")
+set(CPACK_SOURCE_TZ "ON")
+set(CPACK_SOURCE_ZIP "OFF")
+set(CPACK_STRIP_FILES "")
+set(CPACK_SYSTEM_NAME "Linux")
+set(CPACK_THREADS "1")
+set(CPACK_TOPLEVEL_TAG "Linux-Source")
+set(CPACK_WIX_SIZEOF_VOID_P "8")
+
+if(NOT CPACK_PROPERTIES_FILE)
+ set(CPACK_PROPERTIES_FILE "/home/gyx/work/LLVM-project/llvm/CPackProperties.cmake")
+endif()
+
+if(EXISTS ${CPACK_PROPERTIES_FILE})
+ include(${CPACK_PROPERTIES_FILE})
+endif()
diff --git a/llvm/include/llvm/TargetParser/Triple.h b/llvm/include/llvm/TargetParser/Triple.h
index 8097300c6e630..4cf34088ee1c8 100644
--- a/llvm/include/llvm/TargetParser/Triple.h
+++ b/llvm/include/llvm/TargetParser/Triple.h
@@ -105,7 +105,8 @@ class Triple {
renderscript32, // 32-bit RenderScript
renderscript64, // 64-bit RenderScript
ve, // NEC SX-Aurora Vector Engine
- LastArchType = ve
+ pe,
+ LastArchType = pe
};
enum SubArchType {
NoSubArch,
diff --git a/llvm/lib/Target/PE/AsmParser/CMakeLists.txt b/llvm/lib/Target/PE/AsmParser/CMakeLists.txt
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/llvm/lib/Target/PE/CMakeLists.txt b/llvm/lib/Target/PE/CMakeLists.txt
new file mode 100644
index 0000000000000..8a2ec65fd8098
--- /dev/null
+++ b/llvm/lib/Target/PE/CMakeLists.txt
@@ -0,0 +1,62 @@
+#创建一个PE的LLVM组件,具有JIT即时编译功能
+add_llvm_component_group(PE HAS_JIT)
+
+#指定目标架构的定义文件为PE.td,该文件使用TableGen语言描述目标架构的指令集、寄存器、调度模型等核心元数据
+set(LLVM_TARGET_DEFINITIONS PE.td)
+set(LLVM_EXPERIMENTAL_TARGETS_TO_BUILD "PE")
+
+#通过LLVM的TableGen工具,从PE.td生成C++头文件(.inc),用于后续编译
+#[[tablegen(LLVM PEGenAsmMatcher.inc -gen-asm-matcher)
+tablegen(LLVM PEGenAsmWriter.inc -gen-asm-writer)
+tablegen(LLVM PEGenCallingConv.inc -gen-callingconv)
+tablegen(LLVM PEGenDAGISel.inc -gen-dag-isel)
+tablegen(LLVM PEGenDisassemblerTables.inc -gen-disassembler)
+tablegen(LLVM PEGenFastISel.inc -gen-fast-isel)
+tablegen(LLVM PEGenGlobalISel.inc -gen-global-isel)
+tablegen(LLVM PEGenPostLegalizeGICombiner.inc -gen-global-isel-combiner
+ -combiners="PEPostLegalizerCombiner")
+tablegen(LLVM PEGenInstrInfo.inc -gen-instr-info)
+tablegen(LLVM PEGenMCCodeEmitter.inc -gen-emitter)
+tablegen(LLVM PEGenMCPseudoLowering.inc -gen-pseudo-lowering)
+tablegen(LLVM PEGenRegisterBank.inc -gen-register-bank)
+tablegen(LLVM PEGenRegisterInfo.inc -gen-register-info)
+tablegen(LLVM PEGenSubtargetInfo.inc -gen-subtarget)
+tablegen(LLVM PEGenExegesis.inc -gen-exegesis)]]
+
+#将生成的TableGen文件(如PEGen*.inc)声明为公共构建目标,确保其他LLVM组件(如汇编器、反汇编器)能访问这些文件
+#add_public_tablegen_target(PECommonTableGen)
+
+add_llvm_target(PECodeGen
+ PEFrameLowering.cpp
+ PEInstrInfo.cpp
+ PEISelDAGToDAG.cpp
+ PEISelLowering.cpp
+ PERegisterInfo.cpp
+ PESubtarget.cpp
+ PETargetMachine.cpp
+ PE.h # 添加新的头文件
+
+ LINK_COMPONENTS
+ Analysis
+ AsmPrinter
+ CodeGen
+ CodeGenTypes
+ Core
+ GlobalISel
+ MC
+ PEDesc
+ PEInfo
+ SelectionDAG
+ Support
+ Target
+ TargetParser
+ TransformUtils
+
+ ADD_TO_COMPONENT #添加PE组件
+ PE
+ )
+#递归构建子目录中的模块,通常包括
+add_subdirectory(AsmParser)
+add_subdirectory(Disassembler)
+add_subdirectory(MCTargetDesc)
+add_subdirectory(TargetInfo)
diff --git a/llvm/lib/Target/PE/Disassembler/CMakeLists.txt b/llvm/lib/Target/PE/Disassembler/CMakeLists.txt
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/llvm/lib/Target/PE/MCTargetDesc/CMakeLists.txt b/llvm/lib/Target/PE/MCTargetDesc/CMakeLists.txt
new file mode 100644
index 0000000000000..2f36298dd4a4f
--- /dev/null
+++ b/llvm/lib/Target/PE/MCTargetDesc/CMakeLists.txt
@@ -0,0 +1,5 @@
+add_llvm_component_library(LLVMPEDesc
+ PEMCTargetDesc.cpp
+ ADD_TO_COMPONENT
+ PE
+)
\ No newline at end of file
diff --git a/llvm/lib/Target/PE/MCTargetDesc/PEMCTargetDesc.cpp b/llvm/lib/Target/PE/MCTargetDesc/PEMCTargetDesc.cpp
new file mode 100644
index 0000000000000..4fd00daddea1f
--- /dev/null
+++ b/llvm/lib/Target/PE/MCTargetDesc/PEMCTargetDesc.cpp
@@ -0,0 +1,3 @@
+#include "llvm/Support/Compiler.h"
+
+extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePETargetMC() {}
\ No newline at end of file
diff --git a/llvm/lib/Target/PE/PE.h b/llvm/lib/Target/PE/PE.h
new file mode 100644
index 0000000000000..5e253cd733a63
--- /dev/null
+++ b/llvm/lib/Target/PE/PE.h
@@ -0,0 +1,14 @@
+#ifndef LLVM_LIB_TARGET_PE_PE_H
+#define LLVM_LIB_TARGET_PE_PE_H
+
+#include "llvm/CodeGen/TargetFrameLowering.h"
+#include "llvm/CodeGen/TargetInstrInfo.h"
+#include "llvm/CodeGen/TargetLowering.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
+#include "llvm/CodeGen/TargetSubtargetInfo.h"
+#include "llvm/Target/TargetMachine.h"
+
+// 添加其他需要的头文件引用
+// ...
+
+#endif // LLVM_LIB_TARGET_PE_PE_H
diff --git a/llvm/lib/Target/PE/PE.td b/llvm/lib/Target/PE/PE.td
new file mode 100644
index 0000000000000..e091b2fc8dfcb
--- /dev/null
+++ b/llvm/lib/Target/PE/PE.td
@@ -0,0 +1,38 @@
+// 包含必要的 LLVM 定义文件
+include "llvm/IR/Intrinsics.td"
+include "llvm/Target/Target.td"
+// 定义 PE 指令集信息
+def PEInstrInfo : InstrInfo {
+ let Name = "PE"; // 指令集名称
+ let AllowRegisterRenaming = 0; // 其他可选属性
+}
+
+// 定义PE目标
+def PE : Target {
+ // 指定目标的名称
+ let InstructionSet = PEInstrInfo;
+}
+
+// 定义寄存器类
+class RegisterClass<RegisterType, string Name, list<Register> Regs> {
+ let Name = Name;
+ let Registers = Regs;
+}
+
+// 定义一个简单的寄存器
+def R0 : Register;
+def R1 : Register;
+
+// 定义寄存器类
+def GPR : RegisterClass<"i32", "GPR", [R0, R1]>;
+
+// 定义一个简单的指令
+class Instruction {
+ let Namespace = "PE";
+}
+
+def ADD : Instruction {
+ let Inst = "add";
+ let Operands = (outs GPR:$dst, GPR:$src1, GPR:$src2);
+ let AsmString = "add $dst, $src1, $src2";
+}
\ No newline at end of file
diff --git a/llvm/lib/Target/PE/PEFrameLowering.cpp b/llvm/lib/Target/PE/PEFrameLowering.cpp
new file mode 100644
index 0000000000000..4fd3e171ddbf8
--- /dev/null
+++ b/llvm/lib/Target/PE/PEFrameLowering.cpp
@@ -0,0 +1,8 @@
+#include "PE.h"
+
+using namespace llvm;
+
+PEFrameLowering::PEFrameLowering()
+ : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, Align(16), 0) {}
+
+// ...existing code...
\ No newline at end of file
diff --git a/llvm/lib/Target/PE/PEISelDAGToDAG.cpp b/llvm/lib/Target/PE/PEISelDAGToDAG.cpp
new file mode 100644
index 0000000000000..2be2b86d4f194
--- /dev/null
+++ b/llvm/lib/Target/PE/PEISelDAGToDAG.cpp
@@ -0,0 +1,8 @@
+#include "PE.h"
+
+using namespace llvm;
+
+PEISelDAGToDAG::PEISelDAGToDAG()
+ : SelectionDAGISel() {}
+
+// ...existing code...
\ No newline at end of file
diff --git a/llvm/lib/Target/PE/PEISelLowering.cpp b/llvm/lib/Target/PE/PEISelLowering.cpp
new file mode 100644
index 0000000000000..c797a943abf75
--- /dev/null
+++ b/llvm/lib/Target/PE/PEISelLowering.cpp
@@ -0,0 +1,6 @@
+#include "PE.h"
+
+using namespace llvm;
+
+PEISelLowering::PEISelLowering()
+ : TargetLowering() {}
\ No newline at end of file
diff --git a/llvm/lib/Target/PE/PEInstrInfo.cpp b/llvm/lib/Target/PE/PEInstrInfo.cpp
new file mode 100644
index 0000000000000..8420ec172271c
--- /dev/null
+++ b/llvm/lib/Target/PE/PEInstrInfo.cpp
@@ -0,0 +1,8 @@
+#include "PE.h"
+
+using namespace llvm;
+
+PEInstrInfo::PEInstrInfo()
+ : TargetInstrInfo() {}
+
+// ...existing code...
\ No newline at end of file
diff --git a/llvm/lib/Target/PE/PERegisterInfo.cpp b/llvm/lib/Target/PE/PERegisterInfo.cpp
new file mode 100644
index 0000000000000..5190f0d51f921
--- /dev/null
+++ b/llvm/lib/Target/PE/PERegisterInfo.cpp
@@ -0,0 +1,6 @@
+#include "PE.h"
+
+using namespace llvm;
+
+PERegisterInfo::PERegisterInfo()
+ : TargetRegisterInfo() {}
\ No newline at end of file
diff --git a/llvm/lib/Target/PE/PESubtarget.cpp b/llvm/lib/Target/PE/PESubtarget.cpp
new file mode 100644
index 0000000000000..efd1de9ee2880
--- /dev/null
+++ b/llvm/lib/Target/PE/PESubtarget.cpp
@@ -0,0 +1,6 @@
+#include "PE.h"
+
+using namespace llvm;
+
+PESubtarget::PESubtarget()
+ : TargetSubtargetInfo() {}
\ No newline at end of file
diff --git a/llvm/lib/Target/PE/PETargetMachine.cpp b/llvm/lib/Target/PE/PETargetMachine.cpp
new file mode 100644
index 0000000000000..e8bdf4af18848
--- /dev/null
+++ b/llvm/lib/Target/PE/PETargetMachine.cpp
@@ -0,0 +1,5 @@
+#include "PE.h"
+
+using namespace llvm;
+
+extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePETarget() {}
\ No newline at end of file
diff --git a/llvm/lib/Target/PE/TargetInfo/CMakeLists.txt b/llvm/lib/Target/PE/TargetInfo/CMakeLists.txt
new file mode 100644
index 0000000000000..4307f7d2abaf6
--- /dev/null
+++ b/llvm/lib/Target/PE/TargetInfo/CMakeLists.txt
@@ -0,0 +1,7 @@
+add_llvm_component_library(LLVMPEInfo
+ PETargetInfo.cpp
+ LINK_COMPONENTS #指定依赖的组件Machine Code
+ MC
+ ADD_TO_COMPONENT #归属于父组件PE
+ PE
+)
\ No newline at end of file
diff --git a/llvm/lib/Target/PE/TargetInfo/PETargetInfo.cpp b/llvm/lib/Target/PE/TargetInfo/PETargetInfo.cpp
new file mode 100644
index 0000000000000..ed848c01d54a5
--- /dev/null
+++ b/llvm/lib/Target/PE/TargetInfo/PETargetInfo.cpp
@@ -0,0 +1,22 @@
+#include "TargetInfo/PETargetInfo.h"
+#include "llvm/MC/TargetRegistry.h"
+#include "llvm/TargetParser/Triple.h"
+using namespace llvm;
+
+namespace llvm {
+ static Target PETarget;
+
+Target &getPETarget() {
+ return PETarget;
+}
+
+} // end namespace llvm
+
+extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePETargetInfo() {
+ RegisterTarget<Triple::pe,/*HasJIT=*/true> X(
+ getPETarget(), // 必须返回 Target 实例
+ "pe", // 目标短名称(命令行参数名)
+ "PE Architecture (32-bit)", // 描述
+ "PE" // 父组件名(可选,与 CMake 中的 ADD_TO_COMPONENT 对应)
+ );
+}
\ No newline at end of file
diff --git a/llvm/lib/Target/PE/TargetInfo/PETargetInfo.h b/llvm/lib/Target/PE/TargetInfo/PETargetInfo.h
new file mode 100644
index 0000000000000..509902df30aa2
--- /dev/null
+++ b/llvm/lib/Target/PE/TargetInfo/PETargetInfo.h
@@ -0,0 +1,12 @@
+#ifndef LLVM_LIB_TARGET_PE_TARGETINFO_PETARGETINFO_H
+#define LLVM_LIB_TARGET_PE_TARGETINFO_PETARGETINFO_H
+
+namespace llvm {
+
+class Target;
+
+Target &getPETarget();
+
+} // end namespace llvm
+
+#endif // LLVM_LIB_TARGET_PE_TARGETINFO_PETARGETINFO_H
\ No newline at end of file
diff --git a/llvm/lib/TargetParser/Triple.cpp b/llvm/lib/TargetParser/Triple.cpp
index ed58e72089839..55658986cd439 100644
--- a/llvm/lib/TargetParser/Triple.cpp
+++ b/llvm/lib/TargetParser/Triple.cpp
@@ -84,6 +84,7 @@ StringRef Triple::getArchTypeName(ArchType Kind) {
case x86_64: return "x86_64";
case xcore: return "xcore";
case xtensa: return "xtensa";
+ case pe: return "pe";
}
llvm_unreachable("Invalid ArchType!");
@@ -248,6 +249,8 @@ StringRef Triple::getArchTypePrefix(ArchType Kind) {
case dxil: return "dx";
case xtensa: return "xtensa";
+
+ case pe: return "pe";
}
}
@@ -486,6 +489,7 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
.Case("loongarch64", loongarch64)
.Case("dxil", dxil)
.Case("xtensa", xtensa)
+ .Case("pe", pe)
.Default(UnknownArch);
}
@@ -632,6 +636,7 @@ static Triple::ArchType parseArch(StringRef ArchName) {
"dxilv1.4", "dxilv1.5", "dxilv1.6", "dxilv1.7", "dxilv1.8",
Triple::dxil)
.Case("xtensa", Triple::xtensa)
+ .Case("pe", Triple::pe)
.Default(Triple::UnknownArch);
// Some architectures require special parsing logic just to compute the
@@ -959,6 +964,7 @@ static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
case Triple::r600:
case Triple::renderscript32:
case Triple::renderscript64:
+ case Triple::pe:
case Triple::riscv32:
case Triple::riscv64:
case Triple::shave:
@@ -1668,6 +1674,7 @@ unsigned Triple::getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
case llvm::Triple::r600:
case llvm::Triple::renderscript32:
case llvm::Triple::riscv32:
+ case llvm::Triple::pe:
case llvm::Triple::shave:
case llvm::Triple::sparc:
case llvm::Triple::sparcel:
@@ -1758,6 +1765,7 @@ Triple Triple::get32BitArchVariant() const {
case Triple::r600:
case Triple::renderscript32:
case Triple::riscv32:
+ case Triple::pe:
case Triple::shave:
case Triple::sparc:
case Triple::sparcel:
@@ -1822,6 +1830,7 @@ Triple Triple::get64BitArchVariant() const {
case Triple::tcele:
case Triple::xcore:
case Triple::xtensa:
+ case Triple::pe:
T.setArch(UnknownArch);
break;
>From d777e0cca43c8a7219d55ed5e2bb67dd01af9136 Mon Sep 17 00:00:00 2001
From: gyx <gyx5252 at 163.com>
Date: Thu, 3 Apr 2025 16:59:44 +0800
Subject: [PATCH 2/4] =?UTF-8?q?feat(PE):=20=E6=B7=BB=E5=8A=A0=E6=96=B0?=
=?UTF-8?q?=E6=8C=87=E4=BB=A4=E5=92=8C=E5=AF=84=E5=AD=98=E5=99=A8=E5=AE=9A?=
=?UTF-8?q?=E4=B9=89?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 新增了PE指令格式和编码的定义
- 添加了PE寄存器的详细描述
- 实现了PE目标机器的初始化
- 完善了PE子目标的初始化和特性解析
---
llvm/lib/Target/PE/AIM.txt | 39 ++++++++++++
llvm/lib/Target/PE/AsmParser/CMakeLists.txt | 0
llvm/lib/Target/PE/CMakeLists.txt | 20 ++----
.../lib/Target/PE/Disassembler/CMakeLists.txt | 0
.../lib/Target/PE/MCTargetDesc/CMakeLists.txt | 2 +
.../Target/PE/MCTargetDesc/PEMCAsmInfo.cpp | 18 ++++++
llvm/lib/Target/PE/MCTargetDesc/PEMCAsmInfo.h | 12 ++++
.../Target/PE/MCTargetDesc/PEMCTargetDesc.cpp | 57 ++++++++++++++++-
.../Target/PE/MCTargetDesc/PEMCTargetDesc.h | 15 +++++
llvm/lib/Target/PE/PE.h | 14 -----
llvm/lib/Target/PE/PE.td | 38 +++---------
llvm/lib/Target/PE/PECallingConv.td | 6 ++
llvm/lib/Target/PE/PEFrameLowering.cpp | 29 +++++++--
llvm/lib/Target/PE/PEFrameLowering.h | 38 ++++++++++++
llvm/lib/Target/PE/PEISelDAGToDAG.cpp | 8 ---
llvm/lib/Target/PE/PEISelLowering.cpp | 18 ++++--
llvm/lib/Target/PE/PEISelLowering.h | 20 ++++++
llvm/lib/Target/PE/PEInstrFormats.td | 49 +++++++++++++++
llvm/lib/Target/PE/PEInstrInfo.cpp | 22 +++++--
llvm/lib/Target/PE/PEInstrInfo.h | 28 +++++++++
llvm/lib/Target/PE/PEInstrInfo.td | 43 +++++++++++++
llvm/lib/Target/PE/PERegisterInfo.cpp | 48 ++++++++++++++-
llvm/lib/Target/PE/PERegisterInfo.h | 34 +++++++++++
llvm/lib/Target/PE/PERegisterInfo.td | 24 ++++++++
llvm/lib/Target/PE/PESubtarget.cpp | 35 ++++++++++-
llvm/lib/Target/PE/PESubtarget.h | 53 ++++++++++++++++
llvm/lib/Target/PE/PETargetMachine.cpp | 61 ++++++++++++++++++-
llvm/lib/Target/PE/PETargetMachine.h | 23 +++++++
28 files changed, 662 insertions(+), 92 deletions(-)
create mode 100755 llvm/lib/Target/PE/AIM.txt
delete mode 100644 llvm/lib/Target/PE/AsmParser/CMakeLists.txt
delete mode 100644 llvm/lib/Target/PE/Disassembler/CMakeLists.txt
create mode 100644 llvm/lib/Target/PE/MCTargetDesc/PEMCAsmInfo.cpp
create mode 100644 llvm/lib/Target/PE/MCTargetDesc/PEMCAsmInfo.h
create mode 100644 llvm/lib/Target/PE/MCTargetDesc/PEMCTargetDesc.h
delete mode 100644 llvm/lib/Target/PE/PE.h
mode change 100644 => 100755 llvm/lib/Target/PE/PE.td
create mode 100755 llvm/lib/Target/PE/PECallingConv.td
create mode 100644 llvm/lib/Target/PE/PEFrameLowering.h
delete mode 100644 llvm/lib/Target/PE/PEISelDAGToDAG.cpp
create mode 100644 llvm/lib/Target/PE/PEISelLowering.h
create mode 100755 llvm/lib/Target/PE/PEInstrFormats.td
create mode 100644 llvm/lib/Target/PE/PEInstrInfo.h
create mode 100755 llvm/lib/Target/PE/PEInstrInfo.td
create mode 100644 llvm/lib/Target/PE/PERegisterInfo.h
create mode 100755 llvm/lib/Target/PE/PERegisterInfo.td
create mode 100644 llvm/lib/Target/PE/PESubtarget.h
mode change 100644 => 100755 llvm/lib/Target/PE/PETargetMachine.cpp
create mode 100755 llvm/lib/Target/PE/PETargetMachine.h
diff --git a/llvm/lib/Target/PE/AIM.txt b/llvm/lib/Target/PE/AIM.txt
new file mode 100755
index 0000000000000..07f0dddef0366
--- /dev/null
+++ b/llvm/lib/Target/PE/AIM.txt
@@ -0,0 +1,39 @@
+第一阶段:
+寄存器 ABI 名字 描述 Saver
+x0 zero 0值寄存器,硬编码为0,写入数据忽略,读取永远为0 -
+x1 ra 返回地址 Caller
+x2 sp 栈指针 Callee
+x3 gp 全局指针 -
+x4 tp 线程指针 -
+x5 t0 临时寄存器或者备用的链接寄存器 Caller
+x6-x7 t1-t2 临时寄存器 Caller
+x8 s0/fp 需要保存的寄存器或者帧指针寄存器 Callee
+x9 s1 需要保存的寄存器,保存原进程中的关键数据,避免在函数调用过程中被破坏 Callee
+x10-x11 a0-a1 函数参数/返回值 Caller
+x12-x17 a2-a7 函数参数 Caller
+x18-x27 s2-s11 需要保存的寄存器 Callee
+x28-x31 t3-t6 临时寄存器 Caller
+
+测试程序test.ll
+define i32 @test() {
+ ret i32 1
+}
+
+RISCV生成汇编程序test.s
+ .text
+ .attribute 4, 16
+ .attribute 5, "rv32i2p0"
+ .file "test.ll"
+ .globl test # -- Begin function test
+ .p2align 2
+ .type test, at function
+test: # @test
+ .cfi_startproc
+# %bb.0:
+ addi a0, zero, 1
+ ret
+.Lfunc_end0:
+ .size test, .Lfunc_end0-test
+ .cfi_endproc
+ # -- End function
+ .section ".note.GNU-stack","", at progbits
\ No newline at end of file
diff --git a/llvm/lib/Target/PE/AsmParser/CMakeLists.txt b/llvm/lib/Target/PE/AsmParser/CMakeLists.txt
deleted file mode 100644
index e69de29bb2d1d..0000000000000
diff --git a/llvm/lib/Target/PE/CMakeLists.txt b/llvm/lib/Target/PE/CMakeLists.txt
index 8a2ec65fd8098..5c1f7f01cf432 100644
--- a/llvm/lib/Target/PE/CMakeLists.txt
+++ b/llvm/lib/Target/PE/CMakeLists.txt
@@ -6,35 +6,23 @@ set(LLVM_TARGET_DEFINITIONS PE.td)
set(LLVM_EXPERIMENTAL_TARGETS_TO_BUILD "PE")
#通过LLVM的TableGen工具,从PE.td生成C++头文件(.inc),用于后续编译
-#[[tablegen(LLVM PEGenAsmMatcher.inc -gen-asm-matcher)
tablegen(LLVM PEGenAsmWriter.inc -gen-asm-writer)
tablegen(LLVM PEGenCallingConv.inc -gen-callingconv)
-tablegen(LLVM PEGenDAGISel.inc -gen-dag-isel)
-tablegen(LLVM PEGenDisassemblerTables.inc -gen-disassembler)
-tablegen(LLVM PEGenFastISel.inc -gen-fast-isel)
-tablegen(LLVM PEGenGlobalISel.inc -gen-global-isel)
-tablegen(LLVM PEGenPostLegalizeGICombiner.inc -gen-global-isel-combiner
- -combiners="PEPostLegalizerCombiner")
tablegen(LLVM PEGenInstrInfo.inc -gen-instr-info)
-tablegen(LLVM PEGenMCCodeEmitter.inc -gen-emitter)
-tablegen(LLVM PEGenMCPseudoLowering.inc -gen-pseudo-lowering)
-tablegen(LLVM PEGenRegisterBank.inc -gen-register-bank)
tablegen(LLVM PEGenRegisterInfo.inc -gen-register-info)
tablegen(LLVM PEGenSubtargetInfo.inc -gen-subtarget)
-tablegen(LLVM PEGenExegesis.inc -gen-exegesis)]]
+tablegen(LLVM PEGenMCPseudoLowering.inc -gen-pseudo-lowering)
#将生成的TableGen文件(如PEGen*.inc)声明为公共构建目标,确保其他LLVM组件(如汇编器、反汇编器)能访问这些文件
-#add_public_tablegen_target(PECommonTableGen)
+add_public_tablegen_target(PECommonTableGen)
add_llvm_target(PECodeGen
PEFrameLowering.cpp
PEInstrInfo.cpp
- PEISelDAGToDAG.cpp
PEISelLowering.cpp
PERegisterInfo.cpp
PESubtarget.cpp
PETargetMachine.cpp
- PE.h # 添加新的头文件
LINK_COMPONENTS
Analysis
@@ -56,7 +44,7 @@ add_llvm_target(PECodeGen
PE
)
#递归构建子目录中的模块,通常包括
-add_subdirectory(AsmParser)
-add_subdirectory(Disassembler)
+# add_subdirectory(AsmParser)
+# add_subdirectory(Disassembler)
add_subdirectory(MCTargetDesc)
add_subdirectory(TargetInfo)
diff --git a/llvm/lib/Target/PE/Disassembler/CMakeLists.txt b/llvm/lib/Target/PE/Disassembler/CMakeLists.txt
deleted file mode 100644
index e69de29bb2d1d..0000000000000
diff --git a/llvm/lib/Target/PE/MCTargetDesc/CMakeLists.txt b/llvm/lib/Target/PE/MCTargetDesc/CMakeLists.txt
index 2f36298dd4a4f..5473a13714d21 100644
--- a/llvm/lib/Target/PE/MCTargetDesc/CMakeLists.txt
+++ b/llvm/lib/Target/PE/MCTargetDesc/CMakeLists.txt
@@ -1,5 +1,7 @@
add_llvm_component_library(LLVMPEDesc
PEMCTargetDesc.cpp
+ PEMCAsmInfo.cpp
+
ADD_TO_COMPONENT
PE
)
\ No newline at end of file
diff --git a/llvm/lib/Target/PE/MCTargetDesc/PEMCAsmInfo.cpp b/llvm/lib/Target/PE/MCTargetDesc/PEMCAsmInfo.cpp
new file mode 100644
index 0000000000000..f92c2f5dffa71
--- /dev/null
+++ b/llvm/lib/Target/PE/MCTargetDesc/PEMCAsmInfo.cpp
@@ -0,0 +1,18 @@
+#include "PEMCAsmInfo.h"
+
+namespace llvm{
+
+PEMCAsmInfo :: PEMCAsmInfo(const Triple &TT)
+{
+ // 设置目标特定的汇编信息,指定汇编的格式信息
+
+ CodePointerSize = 4; // 假设目标是32位架构
+ CalleeSaveStackSlotSize = 4;
+ IsLittleEndian = true;
+ StackGrowsUp = false;
+ HasSubsectionsViaSymbols = true;
+ SupportsDebugInformation = true;
+ ExceptionsType = ExceptionHandling::DwarfCFI;
+}
+
+}
\ No newline at end of file
diff --git a/llvm/lib/Target/PE/MCTargetDesc/PEMCAsmInfo.h b/llvm/lib/Target/PE/MCTargetDesc/PEMCAsmInfo.h
new file mode 100644
index 0000000000000..e66c263267305
--- /dev/null
+++ b/llvm/lib/Target/PE/MCTargetDesc/PEMCAsmInfo.h
@@ -0,0 +1,12 @@
+#include "llvm/MC/MCAsmInfoELF.h"
+#include "llvm/MC/TargetRegistry.h"
+
+namespace llvm{
+
+class Triple;
+
+class PEMCAsmInfo : public MCAsmInfoELF {
+public:
+ explicit PEMCAsmInfo(const Triple &TT);
+};
+}
\ No newline at end of file
diff --git a/llvm/lib/Target/PE/MCTargetDesc/PEMCTargetDesc.cpp b/llvm/lib/Target/PE/MCTargetDesc/PEMCTargetDesc.cpp
index 4fd00daddea1f..e0f84a908bbc6 100644
--- a/llvm/lib/Target/PE/MCTargetDesc/PEMCTargetDesc.cpp
+++ b/llvm/lib/Target/PE/MCTargetDesc/PEMCTargetDesc.cpp
@@ -1,3 +1,56 @@
-#include "llvm/Support/Compiler.h"
+#include "PEMCTargetDesc.h"
+#include "PEMCAsmInfo.h"
+#include "PEInstrInfo.h"
+#include "PERegisterInfo.h"
+#include "PESubtarget.h"
+#include "llvm/MC/TargetRegistry.h"
+#include "TargetInfo/PETargetInfo.h"
-extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePETargetMC() {}
\ No newline at end of file
+#define GET_INSTRINFO_MC_DESC
+#define ENABLE_INSTR_PREDICATE_VERIFIER
+#include "PEGenInstrInfo.inc"
+
+#define GET_REGINFO_MC_DESC
+#include "PEGenRegisterInfo.inc"
+
+#define GET_SUBTARGETINFO_MC_DESC
+#include "PEGenSubtargetInfo.inc"
+
+using namespace llvm;
+
+//注册MC(Machine Code)层核心组件,将PE后端的多个机器码生成模块注册到LLVM全局目标注册表中,包括:
+// 汇编信息 (RegisterMCAsmInfo):定义汇编语法规则(如指令分隔符、注释符号等)。
+// 目标文件信息 (RegisterMCObjectFileInfo):指定 ELF 等目标文件格式的生成规则。
+// 指令与寄存器信息 (RegisterMCInstrInfo, RegisterMCRegInfo):描述 RISC-V 指令集架构(ISA)和寄存器布局。
+// 代码发射器与汇编后端 (RegisterMCCodeEmitter, RegisterMCAsmBackend):负责将 LLVM IR 转换为机器码并生成汇编或二进制文件。
+// 指令流生成器 (RegisterELFStreamer, RegisterObjectTargetStreamer):控制目标文件流(如 ELF 文件)的生成逻辑。
+static MCAsmInfo *createPEMCAsmInfo(const MCRegisterInfo &MRI,
+ const Triple &TT,
+ const MCTargetOptions &Options){
+ return new PEMCAsmInfo(TT);
+
+ }
+static MCRegisterInfo *createPEMCRegisterInfo(const Triple &TT) {
+ MCRegisterInfo* X = new MCRegisterInfo();
+ InitPEMCRegisterInfo(X,PE::X1);
+ return X;
+}
+
+static MCInstrInfo *createPEMCInstrInfo() {
+ MCInstrInfo* X = new MCInstrInfo();
+ InitPEMCInstrInfo(X);
+ return X;
+}
+static MCSubtargetInfo *createPEMCSubtargetInfo(const Triple &TT,
+ StringRef CPU, StringRef FS){
+ if(CPU.empty() || CPU == "generic")
+ CPU = "PE";
+ return createPEMCSubtargetInfoImpl(TT,CPU,CPU,FS);
+}
+
+extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePETargetMC() {
+ TargetRegistry::RegisterMCAsmInfo(getPETarget(), createPEMCAsmInfo);
+ TargetRegistry::RegisterMCRegInfo(getPETarget(), createPEMCRegisterInfo);
+ TargetRegistry::RegisterMCInstrInfo(getPETarget(), createPEMCInstrInfo);
+ TargetRegistry::RegisterMCSubtargetInfo(getPETarget(), createPEMCSubtargetInfo);//子目标信息注册
+}
\ No newline at end of file
diff --git a/llvm/lib/Target/PE/MCTargetDesc/PEMCTargetDesc.h b/llvm/lib/Target/PE/MCTargetDesc/PEMCTargetDesc.h
new file mode 100644
index 0000000000000..0cd5d8a5313ce
--- /dev/null
+++ b/llvm/lib/Target/PE/MCTargetDesc/PEMCTargetDesc.h
@@ -0,0 +1,15 @@
+#ifndef PEMCTARGETDESC_H
+#define PEMCTARGETDESC_H
+
+//获取codegen生成文件,方便其他文件引用
+
+#define GET_REGINFO_ENUM
+#include "PEGenRegisterInfo.inc"
+
+#define GET_INSTRINFO_ENUM
+#include "PEGenInstrInfo.inc"
+
+#define GET_SUBTARGETINFO_ENUM
+#include "PEGenSubtargetInfo.inc"
+
+#endif //PEMCTARGETDESC_H
\ No newline at end of file
diff --git a/llvm/lib/Target/PE/PE.h b/llvm/lib/Target/PE/PE.h
deleted file mode 100644
index 5e253cd733a63..0000000000000
--- a/llvm/lib/Target/PE/PE.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef LLVM_LIB_TARGET_PE_PE_H
-#define LLVM_LIB_TARGET_PE_PE_H
-
-#include "llvm/CodeGen/TargetFrameLowering.h"
-#include "llvm/CodeGen/TargetInstrInfo.h"
-#include "llvm/CodeGen/TargetLowering.h"
-#include "llvm/CodeGen/TargetRegisterInfo.h"
-#include "llvm/CodeGen/TargetSubtargetInfo.h"
-#include "llvm/Target/TargetMachine.h"
-
-// 添加其他需要的头文件引用
-// ...
-
-#endif // LLVM_LIB_TARGET_PE_PE_H
diff --git a/llvm/lib/Target/PE/PE.td b/llvm/lib/Target/PE/PE.td
old mode 100644
new mode 100755
index e091b2fc8dfcb..2ace8c4f1ae42
--- a/llvm/lib/Target/PE/PE.td
+++ b/llvm/lib/Target/PE/PE.td
@@ -1,38 +1,14 @@
// 包含必要的 LLVM 定义文件
-include "llvm/IR/Intrinsics.td"
-include "llvm/Target/Target.td"
-// 定义 PE 指令集信息
-def PEInstrInfo : InstrInfo {
- let Name = "PE"; // 指令集名称
- let AllowRegisterRenaming = 0; // 其他可选属性
-}
+include "llvm/Target/Target.td"//llvm框架层内置的文件
+include "PEInstrInfo.td"
+include "PECallingConv.td"
+
+def : ProcessorModel<"generic", NoSchedModel, []>; // 定义一个处理器模型
+// 定义 PE 指令集信息
+def PEInstrInfo : InstrInfo;
// 定义PE目标
def PE : Target {
// 指定目标的名称
let InstructionSet = PEInstrInfo;
}
-
-// 定义寄存器类
-class RegisterClass<RegisterType, string Name, list<Register> Regs> {
- let Name = Name;
- let Registers = Regs;
-}
-
-// 定义一个简单的寄存器
-def R0 : Register;
-def R1 : Register;
-
-// 定义寄存器类
-def GPR : RegisterClass<"i32", "GPR", [R0, R1]>;
-
-// 定义一个简单的指令
-class Instruction {
- let Namespace = "PE";
-}
-
-def ADD : Instruction {
- let Inst = "add";
- let Operands = (outs GPR:$dst, GPR:$src1, GPR:$src2);
- let AsmString = "add $dst, $src1, $src2";
-}
\ No newline at end of file
diff --git a/llvm/lib/Target/PE/PECallingConv.td b/llvm/lib/Target/PE/PECallingConv.td
new file mode 100755
index 0000000000000..90c48512c9801
--- /dev/null
+++ b/llvm/lib/Target/PE/PECallingConv.td
@@ -0,0 +1,6 @@
+//定义了一个名为RetCC_PE的调用约定。调用约定决定了函数调用时参数如何传递,返回值如何存放等规则。
+//CCIfType<[i32]当返回值为i32时,执行后序
+//CCAssignToReg将返回值分配到 X10(RISC-V 的 a0 寄存器)和 X11(a1 寄存器)
+def RetCC_PE : CallingConv<[
+ CCIfType<[i32],CCAssignToReg<[X10,X11]>>,
+]>;
\ No newline at end of file
diff --git a/llvm/lib/Target/PE/PEFrameLowering.cpp b/llvm/lib/Target/PE/PEFrameLowering.cpp
index 4fd3e171ddbf8..1c03076eb8ea5 100644
--- a/llvm/lib/Target/PE/PEFrameLowering.cpp
+++ b/llvm/lib/Target/PE/PEFrameLowering.cpp
@@ -1,8 +1,29 @@
-#include "PE.h"
+/* --- PEFrameLowering.cpp --- */
+
+/* ------------------------------------------
+author: undefined
+date: 4/2/2025
+------------------------------------------ */
+
+#include "PEFrameLowering.h"
using namespace llvm;
-PEFrameLowering::PEFrameLowering()
- : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, Align(16), 0) {}
+//函数的汇编代码开头序言
+void PEFrameLowering::emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const{
+
+}
+
+//函数的汇编代码结尾序言
+void PEFrameLowering::emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const{
+
+}
+
+bool PEFrameLowering::hasFPImpl(const MachineFunction &MF) const{
+ return false;
+}
+
-// ...existing code...
\ No newline at end of file
+PEFrameLowering::~PEFrameLowering() {
+ // Destructor
+}
diff --git a/llvm/lib/Target/PE/PEFrameLowering.h b/llvm/lib/Target/PE/PEFrameLowering.h
new file mode 100644
index 0000000000000..e6b13c5fad4ac
--- /dev/null
+++ b/llvm/lib/Target/PE/PEFrameLowering.h
@@ -0,0 +1,38 @@
+/* --- PEFrameLowering.h --- */
+
+/* ------------------------------------------
+Author: 高宇翔
+Date: 4/2/2025
+------------------------------------------ */
+
+#ifndef PEFRAMELOWERING_H
+#define PEFRAMELOWERING_H
+
+#include "llvm/CodeGen/TargetFrameLowering.h"
+
+namespace llvm{
+
+class PESubtarget;
+
+class PEFrameLowering : public TargetFrameLowering{
+ const PESubtarget &STI;
+public:
+ explicit PEFrameLowering(const PESubtarget &STI)
+ : TargetFrameLowering(StackGrowsDown, Align(4), 0,
+ Align(4)),STI(STI){
+ }
+ ~PEFrameLowering();
+
+ //函数的汇编代码开头序言
+ void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
+
+ //函数的汇编代码结尾序言
+ void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
+
+protected:
+ bool hasFPImpl(const MachineFunction &MF) const override;
+
+};
+}
+
+#endif // PEFRAMELOWERING_H
diff --git a/llvm/lib/Target/PE/PEISelDAGToDAG.cpp b/llvm/lib/Target/PE/PEISelDAGToDAG.cpp
deleted file mode 100644
index 2be2b86d4f194..0000000000000
--- a/llvm/lib/Target/PE/PEISelDAGToDAG.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
-#include "PE.h"
-
-using namespace llvm;
-
-PEISelDAGToDAG::PEISelDAGToDAG()
- : SelectionDAGISel() {}
-
-// ...existing code...
\ No newline at end of file
diff --git a/llvm/lib/Target/PE/PEISelLowering.cpp b/llvm/lib/Target/PE/PEISelLowering.cpp
index c797a943abf75..6f7fe067140df 100644
--- a/llvm/lib/Target/PE/PEISelLowering.cpp
+++ b/llvm/lib/Target/PE/PEISelLowering.cpp
@@ -1,6 +1,16 @@
-#include "PE.h"
+/* --- PEISelLowering.cpp --- */
-using namespace llvm;
+/* ------------------------------------------
+author: undefined
+date: 4/3/2025
+------------------------------------------ */
-PEISelLowering::PEISelLowering()
- : TargetLowering() {}
\ No newline at end of file
+#include "PEISelLowering.h"
+
+PEISelLowering::PEISelLowering() {
+ // Constructor
+}
+
+PEISelLowering::~PEISelLowering() {
+ // Destructor
+}
diff --git a/llvm/lib/Target/PE/PEISelLowering.h b/llvm/lib/Target/PE/PEISelLowering.h
new file mode 100644
index 0000000000000..488b96338a496
--- /dev/null
+++ b/llvm/lib/Target/PE/PEISelLowering.h
@@ -0,0 +1,20 @@
+/* --- PEISelLowering.h --- */
+
+/* ------------------------------------------
+Author: undefined
+Date: 4/3/2025
+------------------------------------------ */
+
+#ifndef PEISELLOWERING_H
+#define PEISELLOWERING_H
+
+class PEISelLowering {
+public:
+ PEISelLowering();
+ ~PEISelLowering();
+
+private:
+
+};
+
+#endif // PEISELLOWERING_H
diff --git a/llvm/lib/Target/PE/PEInstrFormats.td b/llvm/lib/Target/PE/PEInstrFormats.td
new file mode 100755
index 0000000000000..31a966131b6a5
--- /dev/null
+++ b/llvm/lib/Target/PE/PEInstrFormats.td
@@ -0,0 +1,49 @@
+//通用指令模版,后序修改
+
+class PEOpcode<string name, bits<7> val,bits<3>funct3> {
+ string Name = name;
+ bits<7> Value = val;
+ bits<3> FUNCT3 = funct3;
+}
+
+//实例化操作码
+def OPC_ADDI : PEOpcode<"ADDI",0b0010011,0b000>;
+def OPC_JALR : PEOpcode<"JALR",0b1101111,0b000>;
+
+
+class PEInst<dag outs, dag ins, string asmstr,list<dag> pattern>
+: Instruction
+{
+ field bits<32> Inst;//指令的编码,每个bit意义
+ field bits<32> SoftFail = 0;//软件错误,传0,用于反汇编程序
+
+ let Size = 4;
+ let Namespace = "PE";
+ dag OutOperandList = outs;
+ dag InOperandList = ins;
+ let AsmString = asmstr;
+ let Pattern = pattern;
+}
+//伪指令
+class PseudoInst<dag outs, dag ins,list<dag> pattern,string asmstr = "">
+ : PEInst<outs, ins, asmstr, pattern> {
+ let isPseudo = 1;//表示为伪指令
+ let isCodeGenOnly = 1;//存在于代码生成
+ let Size = 4;
+}
+class I<PEOpcode opcode, dag outs, dag ins,
+ string asmstr, list<dag> pattern>
+ : PEInst< outs, ins, asmstr, pattern> {
+//RISCV32的I-type指令格式:imm[11:0] rs1 funct3 rd opcode
+ bits<7> Opcode = opcode.Value;
+ bits<5> rd;
+ bits<3> funct3 = opcode.FUNCT3;
+ bits<5> rs1;
+ bits<12> imm12;
+
+ let Inst{6-0} = Opcode;
+ let Inst{11-7} = rd;
+ let Inst{14-12} = funct3;
+ let Inst{19-15} = rs1;
+ let Inst{31-20} = imm12;
+}
\ No newline at end of file
diff --git a/llvm/lib/Target/PE/PEInstrInfo.cpp b/llvm/lib/Target/PE/PEInstrInfo.cpp
index 8420ec172271c..d3b6ce63945ba 100644
--- a/llvm/lib/Target/PE/PEInstrInfo.cpp
+++ b/llvm/lib/Target/PE/PEInstrInfo.cpp
@@ -1,8 +1,22 @@
-#include "PE.h"
+/* --- PEInstrInfo.cpp --- */
+
+/* ------------------------------------------
+author: 高宇翔
+date: 4/1/2025
+------------------------------------------ */
+
+#include "PEInstrInfo.h"
+#include "MCTargetDesc/PEMCTargetDesc.h"
using namespace llvm;
-PEInstrInfo::PEInstrInfo()
- : TargetInstrInfo() {}
+#define GET_INSTRINFO_CTOR_DTOR
+#include "PEGenInstrInfo.inc"
+
+PEInstrInfo::PEInstrInfo() : PEGenInstrInfo(){
+ // Constructor
+}
-// ...existing code...
\ No newline at end of file
+PEInstrInfo::~PEInstrInfo() {
+ // Destructor
+}
diff --git a/llvm/lib/Target/PE/PEInstrInfo.h b/llvm/lib/Target/PE/PEInstrInfo.h
new file mode 100644
index 0000000000000..43377e660d090
--- /dev/null
+++ b/llvm/lib/Target/PE/PEInstrInfo.h
@@ -0,0 +1,28 @@
+/* --- PEInstrInfo.h --- */
+
+/* ------------------------------------------
+Author: 高宇翔
+Date: 4/1/2025
+------------------------------------------ */
+
+#ifndef PEINSTRINFO_H
+#define PEINSTRINFO_H
+
+#include "llvm/CodeGen/TargetInstrInfo.h"
+
+//使用CodeGen生成的源文件
+#define GET_INSTRINFO_HEADER
+#include "PEGenInstrInfo.inc"
+namespace llvm{
+class PEInstrInfo : public PEGenInstrInfo{
+public:
+
+ explicit PEInstrInfo();
+ ~PEInstrInfo();
+
+private:
+
+};
+}
+
+#endif // PEINSTRINFO_H
diff --git a/llvm/lib/Target/PE/PEInstrInfo.td b/llvm/lib/Target/PE/PEInstrInfo.td
new file mode 100755
index 0000000000000..1eabf3e5d3d17
--- /dev/null
+++ b/llvm/lib/Target/PE/PEInstrInfo.td
@@ -0,0 +1,43 @@
+include "PEInstrFormats.td"
+include "PERegisterInfo.td"
+/*
+ 定义具体的指令信息,每一条指令对应一个def
+
+ BasicBlock(IR) -> SelectionDAG(SDNode)
+ 数据结构从IR到DAG图
+ ret语句需要调用特定后端的lowerReturn函数进行处理
+
+*/
+//SDNode代表指令约束,PEISD::RET_GLUE代表节点的枚举值,SDTNode:节点的类型约束
+//[SDNPHasChain,SDNPOptInGlue,SDNPVariadic] :指令属性
+def retglue : SDNode <"PEISD::RET_GLUE",SDTNone,
+ [SDNPHasChain,SDNPOptInGlue,SDNPVariadic]>;
+
+//class I 的实例化
+//OPC_ADDI:指令码,GPR:$rd:一个通用寄存器$rd,i32imm:$imm12:一个立即数$imm12
+//"addi $rd,$rs1,$imm12":汇编字符串
+//[]:模式匹配为空
+def ADDI : I<OPC_ADDI,(outs GPR:$rd),(ins GPR:$rs1,i32imm:$imm12),
+ "addi $rd,$rs1,$imm12",[]>;
+
+//当IR中出现形如i32 (imm:$imm12)的立即数操作时(例如加载一个32位整数到寄存器),TableGen会将其匹配为ADDI X0, imm:$imm12。X0为RISCV中的0寄存器,恒为0
+def : Pat<(i32 (imm:$imm12)),(ADDI X0,imm:$imm12)>;
+
+// JALR x1, x5, 0 # 跳转到x5的值,返回地址保存到x1
+// JALR x0, x10, 8 # 跳转到x10+8,不保存返回地址(用于纯跳转)
+// isCall = 1标识该指令为函数调用指令
+let isCall = 1 in{
+ def JALR : I<OPC_JALR,(outs GPR:$rd),(ins GPR:$rs1,i32imm:$imm12),
+ "jalr $rd,$rs1,$imm12",[]>;
+}
+
+//isReturn = 1**:标识为函数返回指令。
+// isTerminator = 1**:标记为基本块终止指令(如分支、返回等),编译器不会在其后插入其他指令。
+// isBarrier = 1**:防止指令重排序优化,确保返回操作原子性。
+//pseudoRET伪指令定义,无显示输入和输出。[(retglue)]:在LLVM的SelectionDAG中表示指令与返回操作的粘附(glue)依赖,确保代码生成顺序正确
+//PseudoInstExpansion<JALR X0, X1, 0>**:将伪指令pseudoRET映射到实际指令JALR X0, X1, 0
+
+//实际是做指令替换,将IR中的ret伪指令翻译成JALR X0, X1, 0
+let isBarrier = 1,isReturn = 1,isTerminator = 1 in{
+ def pseudoRET : PseudoInst<(outs),(ins),[(retglue)]>,PseudoInstExpansion<(JALR X0, X1, 0)>;
+}
\ No newline at end of file
diff --git a/llvm/lib/Target/PE/PERegisterInfo.cpp b/llvm/lib/Target/PE/PERegisterInfo.cpp
index 5190f0d51f921..08e1ea9513a49 100644
--- a/llvm/lib/Target/PE/PERegisterInfo.cpp
+++ b/llvm/lib/Target/PE/PERegisterInfo.cpp
@@ -1,6 +1,48 @@
-#include "PE.h"
+/* --- PERegisterInfo.cpp --- */
+/* ------------------------------------------
+author: 高宇翔
+date: 4/1/2025
+------------------------------------------ */
+
+#include "PERegisterInfo.h"
+#include "MCTargetDesc/PEMCTargetDesc.h"
+#include "llvm/ADT/BitVector.h"
+#include "PESubtarget.h"
using namespace llvm;
-PERegisterInfo::PERegisterInfo()
- : TargetRegisterInfo() {}
\ No newline at end of file
+#define GET_REGINFO_TARGET_DESC
+#include "PEGenRegisterInfo.inc"
+
+PERegisterInfo::PERegisterInfo() : PEGenRegisterInfo(PE::X1){
+}
+
+PERegisterInfo::~PERegisterInfo() {
+ // Destructor
+}
+
+const MCPhysReg *PERegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const{
+ static const MCPhysReg CalleeSavedRegs[] = {PE::X2,0};
+ return CalleeSavedRegs;
+
+}
+
+//BitVector代表一个位向量0&1
+BitVector PERegisterInfo::getReservedRegs(const MachineFunction &MF) const {
+ BitVector Reserved(getNumRegs());
+ Reserved.set(PE::X0);//不允许X0参与寄存器分配
+ return Reserved;
+
+}
+
+bool PERegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj,
+ unsigned FIOperandNum,
+ RegScavenger *RS) const {
+ return false;//false表示成功
+
+}
+
+Register PERegisterInfo::getFrameRegister(const MachineFunction &MF) const {
+ return PE::X2;
+
+}
\ No newline at end of file
diff --git a/llvm/lib/Target/PE/PERegisterInfo.h b/llvm/lib/Target/PE/PERegisterInfo.h
new file mode 100644
index 0000000000000..32e72b2a8b3b4
--- /dev/null
+++ b/llvm/lib/Target/PE/PERegisterInfo.h
@@ -0,0 +1,34 @@
+/* --- PERegisterInfo.h --- */
+
+/* ------------------------------------------
+Author: 高宇翔
+Date: 4/1/2025
+------------------------------------------ */
+
+#ifndef PEREGISTERINFO_H
+#define PEREGISTERINFO_H
+
+#define GET_REGINFO_HEADER
+#include "PEGenRegisterInfo.inc"
+
+namespace llvm{
+class PERegisterInfo : public PEGenRegisterInfo{
+public:
+ PERegisterInfo();
+ ~PERegisterInfo();
+
+ //实现codegen生成的虚函数
+ const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override;
+
+ BitVector getReservedRegs(const MachineFunction &MF) const override;
+
+ bool eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj,
+ unsigned FIOperandNum,
+ RegScavenger *RS = nullptr) const override;
+
+ Register getFrameRegister(const MachineFunction &MF) const override;
+private:
+
+};
+}
+#endif // PEREGISTERINFO_H
diff --git a/llvm/lib/Target/PE/PERegisterInfo.td b/llvm/lib/Target/PE/PERegisterInfo.td
new file mode 100755
index 0000000000000..c66c43cca852d
--- /dev/null
+++ b/llvm/lib/Target/PE/PERegisterInfo.td
@@ -0,0 +1,24 @@
+//寄存器信息
+//bit<5>代表5bit给寄存器标号,string n:寄存器名字,alt:寄存器别名
+class PEReg<bits<5> Enc, string n, list<string> alt = []> :
+Register<n> {
+ let HWEncoding{4-0} = Enc;//后5位为寄存器编码
+ let Namespace = "PE";
+ let AltNames = alt;
+}
+def ABIRegAltName : RegAltNameIndex;
+
+//描述寄存器信息
+let RegAltNameIndices = [ABIRegAltName] in {
+ let isConstant = true in{
+ def X0 : PEReg<0, "x0", ["zero"]>;
+ }
+
+ def X1 : PEReg<1, "x1", ["ra"]>;
+ def X2 : PEReg<2, "x2", ["sp"]>;
+
+ def X10 : PEReg<10, "x10", ["a0"]>;
+ def X11 : PEReg<11, "x11", ["a1"]>;
+}
+
+def GPR : RegisterClass<"PE",[i32],32,(add X0,X1,X10,X11)>;
\ No newline at end of file
diff --git a/llvm/lib/Target/PE/PESubtarget.cpp b/llvm/lib/Target/PE/PESubtarget.cpp
index efd1de9ee2880..ff65281d94b19 100644
--- a/llvm/lib/Target/PE/PESubtarget.cpp
+++ b/llvm/lib/Target/PE/PESubtarget.cpp
@@ -1,6 +1,35 @@
-#include "PE.h"
+/* --- PESubtarget.cpp --- */
+/* ------------------------------------------
+author: 高宇翔
+date: 4/2/2025
+------------------------------------------ */
+
+#include "PESubtarget.h"
+
+#define GET_SUBTARGETINFO_TARGET_DESC
+#define GET_SUBTARGETINFO_CTOR
+#include "PEGenSubtargetInfo.inc"
+
+#define DEBUG_TYPE "PE-Subtarget"
using namespace llvm;
-PESubtarget::PESubtarget()
- : TargetSubtargetInfo() {}
\ No newline at end of file
+
+PESubtarget::PESubtarget(const Triple &TT, StringRef CPU,
+ StringRef FS, const TargetMachine &TM) : PEGenSubtargetInfo(TT,CPU, CPU,FS),FrameLowering(*this){
+}
+
+PESubtarget::~PESubtarget() {
+ // Destructor
+}
+
+PESubtarget &PESubtarget::initializeSubtargetDependencies(
+ const Triple &TT, StringRef CPU, StringRef TuneCPU, StringRef FS,
+ StringRef ABIName) {
+ if (CPU.empty() || CPU == "generic")
+ CPU = "PE";
+
+ ParseSubtargetFeatures(CPU, CPU, FS);
+
+ return *this;
+}
diff --git a/llvm/lib/Target/PE/PESubtarget.h b/llvm/lib/Target/PE/PESubtarget.h
new file mode 100644
index 0000000000000..de1e4a0651cb6
--- /dev/null
+++ b/llvm/lib/Target/PE/PESubtarget.h
@@ -0,0 +1,53 @@
+/* --- PESubtarget.h --- */
+/* ------------------------------------------
+Author: 高宇翔
+Date: 4/2/2025
+------------------------------------------ */
+
+#ifndef PESUBTARGET_H
+#define PESUBTARGET_H
+
+#include "PEInstrInfo.h"
+#include "PERegisterInfo.h"
+#include "PEFrameLowering.h"
+
+#define GET_SUBTARGETINFO_HEADER
+#include "PEGenSubtargetInfo.inc"
+#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
+
+namespace llvm{
+class PESubtarget : public PEGenSubtargetInfo{
+private:
+ PEInstrInfo InstrInfo;
+ PERegisterInfo RegInfo;
+ PEFrameLowering FrameLowering;
+public:
+ PESubtarget(const Triple &TT, StringRef CPU,
+ StringRef Features, const TargetMachine &TM);
+ ~PESubtarget();
+
+ PESubtarget &initializeSubtargetDependencies(const Triple &TT,
+ StringRef CPU,
+ StringRef TuneCPU,
+ StringRef FS,
+ StringRef ABIName);
+
+ // Parses features string setting specified subtarget options. The
+ // definition of this function is auto-generated by tblgen.
+ void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
+
+ const PEInstrInfo *getInstrInfo() const override { return &InstrInfo; }
+
+ const PERegisterInfo *getRegisterInfo() const override {
+ return &RegInfo;
+ }
+
+ const PEFrameLowering *getFrameLowering() const override {
+ return &FrameLowering;
+ }
+
+private:
+
+};
+}
+#endif // PESUBTARGET_H
diff --git a/llvm/lib/Target/PE/PETargetMachine.cpp b/llvm/lib/Target/PE/PETargetMachine.cpp
old mode 100644
new mode 100755
index e8bdf4af18848..8ca6a3a9644ac
--- a/llvm/lib/Target/PE/PETargetMachine.cpp
+++ b/llvm/lib/Target/PE/PETargetMachine.cpp
@@ -1,5 +1,60 @@
-#include "PE.h"
+#include "llvm/MC/TargetRegistry.h"
+#include "TargetInfo/PETargetInfo.h"
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
+#include "PETargetMachine.h"
+namespace llvm{
-using namespace llvm;
+extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePETarget() {
+ RegisterTargetMachine<PETargetMachine>X(getPETarget());
+}
-extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePETarget() {}
\ No newline at end of file
+static StringRef computeDataLayout(const Triple&TT,const TargetOptions &Options){
+/*
+target datalayout = "e-m:e-p:32:32-i64:64-n32-S128"
+
+e ⼩端序, E 表示大端序
+m:e 表示elf格式, m:o表示Mach-O格式
+p:32:32 表示指针是size是32bit,align是32bit
+i64:64 i64类型,使用64bit对齐
+n32 ⽬标CPU的原⽣整型是32⽐特
+S128 栈以128⽐特⾃然对⻬
+
+target triple = "one-apple-macosx14.0.0"
+one: ⽬标架构为one架构
+apple: 供应商为Apple
+macosx14.0.0: ⽬标操作系统为macOS 14.0
+
+
+详细参考:https://llvm.org/docs/LangRef.html#langref-datalayout
+*/
+ assert(TT.isArch32Bit() && "only 32bit");//因为只有32位的后端
+
+ return "e-m:e-p:32:32-i64:64-n32-S128";
+}
+
+static Reloc::Model getEffectiveRelocModel(const Triple &TT,
+ std::optional<Reloc::Model> RM) {
+return RM.value_or(Reloc::Static);
+}
+
+PETargetMachine::PETargetMachine(const Target &T, const Triple &TT,
+ StringRef CPU, StringRef FS,
+ const TargetOptions &Options,
+ std::optional<Reloc::Model> RM,
+ std::optional<CodeModel::Model> CM,
+ CodeGenOptLevel OL, bool JIT)
+: CodeGenTargetMachineImpl(T, computeDataLayout(TT, Options), TT, CPU, FS,
+Options, getEffectiveRelocModel(TT, RM),
+getEffectiveCodeModel(CM, CodeModel::Small), OL),
+TLOF(std::make_unique<TargetLoweringObjectFileELF>()),Subtarget(TT, CPU, FS, *this){
+ /*
+ CodeModel
+ small : 支持一个数据段一个代码段,所有的数据和代码紧挨着
+ large : 支持多个代码段,多个数据段
+ tiny : 只支持运行在MS-DOS,tiny模型将所有的数据和代码放入一个段中,因此整个程序大小不能超过64k
+ medium : 介于small和large之间,支持多个代码段和单个数据段.
+ 参考链接:http://www.c-jump.com/CIS77/ASM/Directives/D77_0030_models.htm
+ */
+ initAsmInfo();
+}
+}//namespace LLVM
\ No newline at end of file
diff --git a/llvm/lib/Target/PE/PETargetMachine.h b/llvm/lib/Target/PE/PETargetMachine.h
new file mode 100755
index 0000000000000..ff292fdeb5e59
--- /dev/null
+++ b/llvm/lib/Target/PE/PETargetMachine.h
@@ -0,0 +1,23 @@
+#include "llvm/CodeGen/CodeGenTargetMachineImpl.h"
+#include "PESubtarget.h"
+
+namespace llvm{
+class PETargetMachine : public CodeGenTargetMachineImpl
+{
+ std::unique_ptr<TargetLoweringObjectFile> TLOF;
+ PESubtarget Subtarget;
+public:
+ PETargetMachine(const Target &T, const Triple &TT,
+ StringRef CPU, StringRef FS,
+ const TargetOptions &Options,
+ std::optional<Reloc::Model> RM,
+ std::optional<CodeModel::Model> CM,
+ CodeGenOptLevel OL, bool JIT);
+
+ const PESubtarget *getSubtargetImpl() const {return &Subtarget;}
+
+ const PESubtarget *getSubtargetImpl(const Function &F) const override{return &Subtarget;}
+
+};
+
+}
\ No newline at end of file
>From 779adb292abc0371d26a2e11a3a2f448bc39206f Mon Sep 17 00:00:00 2001
From: gyx <gyx5252 at 163.com>
Date: Thu, 3 Apr 2025 17:00:37 +0800
Subject: [PATCH 3/4] =?UTF-8?q?feat(PE):=20=E5=AE=9E=E7=8E=B0=E5=87=BD?=
=?UTF-8?q?=E6=95=B0=E8=BF=94=E5=9B=9E=E5=80=BC=E7=9A=84=20lowering?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 新增 LowerReturn 方法处理函数返回值
- 添加 RegisterClass 和 CallingConv 支持
- 更新 PESubtarget 以集成新的 TargetLowering
---
llvm/lib/Target/PE/PEISelLowering.cpp | 57 ++++++++++++++++++++++++---
llvm/lib/Target/PE/PEISelLowering.h | 37 ++++++++++++++---
llvm/lib/Target/PE/PESubtarget.cpp | 9 ++---
llvm/lib/Target/PE/PESubtarget.h | 9 +++--
4 files changed, 92 insertions(+), 20 deletions(-)
diff --git a/llvm/lib/Target/PE/PEISelLowering.cpp b/llvm/lib/Target/PE/PEISelLowering.cpp
index 6f7fe067140df..5343113a5882d 100644
--- a/llvm/lib/Target/PE/PEISelLowering.cpp
+++ b/llvm/lib/Target/PE/PEISelLowering.cpp
@@ -1,16 +1,61 @@
/* --- PEISelLowering.cpp --- */
/* ------------------------------------------
-author: undefined
+author: 高宇翔
date: 4/3/2025
------------------------------------------ */
#include "PEISelLowering.h"
+#include "PESubtarget.h"
+#include "llvm/CodeGen/CallingConvLower.h"
+#include "MCTargetDesc/PEMCTargetDesc.h"
-PEISelLowering::PEISelLowering() {
- // Constructor
-}
+using namespace llvm;
+
+#include "PEGenCallingConv.inc"
+
+PETargetLowering::PETargetLowering(const TargetMachine &TM,
+ const PESubtarget &STI)
+ : TargetLowering(TM), Subtarget(STI) {
+ ///注册RegisterClass
+ addRegisterClass(MVT::i32, &PE::GPRRegClass);
+
+ // 根据SubTargetInfo中的寄存器信息计算和更新寄存器属性
+ computeRegisterProperties(STI.getRegisterInfo());
+ }
-PEISelLowering::~PEISelLowering() {
- // Destructor
+SDValue PETargetLowering::LowerFormalArguments(
+ SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
+ const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
+ SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ return Chain;
}
+
+SDValue PETargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
+ bool IsVarArg,
+ const SmallVectorImpl<ISD::OutputArg> &Outs,
+ const SmallVectorImpl<SDValue> &OutVals,
+ const SDLoc &DL, SelectionDAG &DAG) const {
+ // 1. 返回物理寄存器
+ SmallVector<CCValAssign, 16> RVLocs;
+ CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(),RVLocs,*DAG.getContext());
+ CCInfo.AnalyzeReturn(Outs, RetCC_PE);
+
+ SDValue Glue;
+ SmallVector<SDValue, 4> RetOps(1, Chain);
+
+ for (unsigned i = 0, e = RVLocs.size(), OutIdx = 0; i < e; ++i, ++OutIdx) {
+ CCValAssign &VA = RVLocs[i];
+ assert(VA.isRegLoc() && "Can only return in registers!");
+ Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), OutVals[i], Glue);
+ Glue = Chain.getValue(1);
+ RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
+ }
+
+ RetOps[0] = Chain;
+ if (Glue.getNode())
+ {
+ RetOps.push_back(Glue);
+ }
+ return DAG.getNode(PEISD::RET_GLUE, DL, MVT::Other, RetOps);
+}
\ No newline at end of file
diff --git a/llvm/lib/Target/PE/PEISelLowering.h b/llvm/lib/Target/PE/PEISelLowering.h
index 488b96338a496..76a30e6ce2f1c 100644
--- a/llvm/lib/Target/PE/PEISelLowering.h
+++ b/llvm/lib/Target/PE/PEISelLowering.h
@@ -1,20 +1,45 @@
/* --- PEISelLowering.h --- */
/* ------------------------------------------
-Author: undefined
+Author: 高宇翔
Date: 4/3/2025
------------------------------------------ */
#ifndef PEISELLOWERING_H
#define PEISELLOWERING_H
-class PEISelLowering {
+#include "llvm/CodeGen/TargetLowering.h"
+
+namespace llvm {
+
+class PESubtarget;
+
+namespace PEISD {
+ enum NodeType : unsigned {
+ RET_GLUE
+ };
+
+} // namespace PEISD
+
+class PETargetLowering : public TargetLowering {
+ const PESubtarget &Subtarget;
+
public:
- PEISelLowering();
- ~PEISelLowering();
+ explicit PETargetLowering(const TargetMachine &TM, const PESubtarget &STI);
+ const PESubtarget &getSubtarget() const { return Subtarget; }
-private:
+ SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
+ bool IsVarArg,
+ const SmallVectorImpl<ISD::InputArg> &Ins,
+ const SDLoc &DL, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const override;
+ SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
+ const SmallVectorImpl<ISD::OutputArg> &Outs,
+ const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
+ SelectionDAG &DAG) const override;
};
-#endif // PEISELLOWERING_H
+} // namespace llvm
+
+#endif // PEISELLOWERING_H
\ No newline at end of file
diff --git a/llvm/lib/Target/PE/PESubtarget.cpp b/llvm/lib/Target/PE/PESubtarget.cpp
index ff65281d94b19..ba23a16da8319 100644
--- a/llvm/lib/Target/PE/PESubtarget.cpp
+++ b/llvm/lib/Target/PE/PESubtarget.cpp
@@ -16,11 +16,10 @@ using namespace llvm;
PESubtarget::PESubtarget(const Triple &TT, StringRef CPU,
- StringRef FS, const TargetMachine &TM) : PEGenSubtargetInfo(TT,CPU, CPU,FS),FrameLowering(*this){
-}
-
-PESubtarget::~PESubtarget() {
- // Destructor
+ StringRef FS, const TargetMachine &TM)
+ : PEGenSubtargetInfo(TT,CPU,CPU,FS),
+ FrameLowering(*this),
+ TLI(TM,*this){
}
PESubtarget &PESubtarget::initializeSubtargetDependencies(
diff --git a/llvm/lib/Target/PE/PESubtarget.h b/llvm/lib/Target/PE/PESubtarget.h
index de1e4a0651cb6..ee7f17d94d40e 100644
--- a/llvm/lib/Target/PE/PESubtarget.h
+++ b/llvm/lib/Target/PE/PESubtarget.h
@@ -10,6 +10,7 @@ Date: 4/2/2025
#include "PEInstrInfo.h"
#include "PERegisterInfo.h"
#include "PEFrameLowering.h"
+#include "PEISelLowering.h"
#define GET_SUBTARGETINFO_HEADER
#include "PEGenSubtargetInfo.inc"
@@ -21,11 +22,10 @@ class PESubtarget : public PEGenSubtargetInfo{
PEInstrInfo InstrInfo;
PERegisterInfo RegInfo;
PEFrameLowering FrameLowering;
+ PETargetLowering TLI;
public:
PESubtarget(const Triple &TT, StringRef CPU,
StringRef Features, const TargetMachine &TM);
- ~PESubtarget();
-
PESubtarget &initializeSubtargetDependencies(const Triple &TT,
StringRef CPU,
StringRef TuneCPU,
@@ -44,7 +44,10 @@ class PESubtarget : public PEGenSubtargetInfo{
const PEFrameLowering *getFrameLowering() const override {
return &FrameLowering;
- }
+ }
+ const PETargetLowering *getTargetLowering() const override{
+ return &TLI;
+ }
private:
>From 223c57c89bd82bdc9093821e4e5757e6d23f71a6 Mon Sep 17 00:00:00 2001
From: gyx <gyx5252 at 163.com>
Date: Mon, 21 Apr 2025 17:16:53 +0800
Subject: [PATCH 4/4] =?UTF-8?q?2025.04.21=E6=9A=82=E5=AD=98=E6=8F=90?=
=?UTF-8?q?=E4=BA=A4=EF=BC=8C=E7=84=B6=E5=90=8Egit=E5=88=B0=E6=9C=8D?=
=?UTF-8?q?=E5=8A=A1=E5=99=A8=E4=B8=8A?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
llvm/lib/Target/ARC/ARCMCInstLower.h | 2 +-
llvm/lib/Target/PE/CMakeLists.txt | 4 +
.../lib/Target/PE/MCTargetDesc/CMakeLists.txt | 7 ++
.../Target/PE/MCTargetDesc/PEInstPrinter.cpp | 59 ++++++++++++++
.../Target/PE/MCTargetDesc/PEInstPrinter.h | 51 ++++++++++++
.../Target/PE/MCTargetDesc/PEMCTargetDesc.cpp | 13 ++-
llvm/lib/Target/PE/PE.h | 19 +++++
llvm/lib/Target/PE/PE.td | 2 +-
llvm/lib/Target/PE/PEAsmPrinter.cpp | 56 +++++++++++++
llvm/lib/Target/PE/PEAsmPrinter.h | 44 ++++++++++
llvm/lib/Target/PE/PEISelDAGToDAG.cpp | 81 +++++++++++++++++++
llvm/lib/Target/PE/PEISelLowering.cpp | 14 +++-
llvm/lib/Target/PE/PEISelLowering.h | 1 +
llvm/lib/Target/PE/PEInstrFormats.td | 28 +------
llvm/lib/Target/PE/PEInstrInfo.td | 32 +++++++-
llvm/lib/Target/PE/PESubtarget.cpp | 6 +-
llvm/lib/Target/PE/PETargetMachine.cpp | 34 +++++++-
llvm/lib/Target/PE/PETargetMachine.h | 8 +-
18 files changed, 418 insertions(+), 43 deletions(-)
create mode 100644 llvm/lib/Target/PE/MCTargetDesc/PEInstPrinter.cpp
create mode 100644 llvm/lib/Target/PE/MCTargetDesc/PEInstPrinter.h
create mode 100644 llvm/lib/Target/PE/PE.h
create mode 100644 llvm/lib/Target/PE/PEAsmPrinter.cpp
create mode 100644 llvm/lib/Target/PE/PEAsmPrinter.h
create mode 100644 llvm/lib/Target/PE/PEISelDAGToDAG.cpp
diff --git a/llvm/lib/Target/ARC/ARCMCInstLower.h b/llvm/lib/Target/ARC/ARCMCInstLower.h
index 24a7f68c695de..d69a9a7ce403f 100644
--- a/llvm/lib/Target/ARC/ARCMCInstLower.h
+++ b/llvm/lib/Target/ARC/ARCMCInstLower.h
@@ -27,7 +27,7 @@ class LLVM_LIBRARY_VISIBILITY ARCMCInstLower {
using MachineOperandType = MachineOperand::MachineOperandType;
MCContext *Ctx;
AsmPrinter &Printer;
-
+
public:
ARCMCInstLower(MCContext *C, AsmPrinter &asmprinter);
void Lower(const MachineInstr *MI, MCInst &OutMI) const;
diff --git a/llvm/lib/Target/PE/CMakeLists.txt b/llvm/lib/Target/PE/CMakeLists.txt
index 5c1f7f01cf432..6985a1009321a 100644
--- a/llvm/lib/Target/PE/CMakeLists.txt
+++ b/llvm/lib/Target/PE/CMakeLists.txt
@@ -7,6 +7,7 @@ set(LLVM_EXPERIMENTAL_TARGETS_TO_BUILD "PE")
#通过LLVM的TableGen工具,从PE.td生成C++头文件(.inc),用于后续编译
tablegen(LLVM PEGenAsmWriter.inc -gen-asm-writer)
+tablegen(LLVM PEGenDAGISel.inc -gen-dag-isel)
tablegen(LLVM PEGenCallingConv.inc -gen-callingconv)
tablegen(LLVM PEGenInstrInfo.inc -gen-instr-info)
tablegen(LLVM PEGenRegisterInfo.inc -gen-register-info)
@@ -23,6 +24,9 @@ add_llvm_target(PECodeGen
PERegisterInfo.cpp
PESubtarget.cpp
PETargetMachine.cpp
+ PEISelDAGToDAG.cpp
+ PEAsmPrinter.cpp
+ PE.h
LINK_COMPONENTS
Analysis
diff --git a/llvm/lib/Target/PE/MCTargetDesc/CMakeLists.txt b/llvm/lib/Target/PE/MCTargetDesc/CMakeLists.txt
index 5473a13714d21..64b59083a8752 100644
--- a/llvm/lib/Target/PE/MCTargetDesc/CMakeLists.txt
+++ b/llvm/lib/Target/PE/MCTargetDesc/CMakeLists.txt
@@ -1,6 +1,13 @@
add_llvm_component_library(LLVMPEDesc
PEMCTargetDesc.cpp
PEMCAsmInfo.cpp
+ PEInstPrinter.cpp
+
+ LINK_COMPONENTS
+ MC
+ PEInfo
+ Support
+ TargetParser
ADD_TO_COMPONENT
PE
diff --git a/llvm/lib/Target/PE/MCTargetDesc/PEInstPrinter.cpp b/llvm/lib/Target/PE/MCTargetDesc/PEInstPrinter.cpp
new file mode 100644
index 0000000000000..c98b9d57753d9
--- /dev/null
+++ b/llvm/lib/Target/PE/MCTargetDesc/PEInstPrinter.cpp
@@ -0,0 +1,59 @@
+/* --- PEInstPrinter.cpp --- */
+
+/* ------------------------------------------
+author: 高宇翔
+date: 4/9/2025
+------------------------------------------ */
+
+#include "PEInstPrinter.h"
+#include "llvm/MC/MCRegister.h" // Include the header for MCRegister
+#include "llvm/MC/MCInst.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "asm-printer"
+
+#define PRINT_ALIAS_INSTR
+#include "PEGenAsmWriter.inc"
+
+void PEInstPrinter::printRegName(raw_ostream &OS, MCRegister Reg) {
+ OS << StringRef(getRegisterName(Reg,PE::ABIRegAltName)).lower();
+}
+
+void PEInstPrinter::printInst(const MCInst *MI, uint64_t Address,
+ StringRef Annot, const MCSubtargetInfo &STI,
+ raw_ostream &O) {
+ if(!printAliasInstr(MI, Address, O))
+ printInstruction(MI, Address, O);
+ printAnnotation(O, Annot);
+}
+
+void llvm::PEInstPrinter::PrintMemOperand(const MCInst *MI, unsigned OpNo,
+ raw_ostream &O) {
+
+//打印格式:12(sp)
+//先打印立即数
+printOperand(MI, OpNo+1, O);
+O<<"(";
+//再打印寄存器
+printOperand(MI, OpNo, O);
+O<<")";
+}
+
+void PEInstPrinter::printOperand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O) {
+ const MCOperand &Op = MI->getOperand(OpNum);
+ if (Op.isReg()) {
+ printRegName(O, Op.getReg());
+ return;
+ }
+
+ if (Op.isImm()) {
+ O << Op.getImm();
+ return;
+ }
+}
+const char *PEInstPrinter::getRegisterName(MCRegister Reg){
+ return getRegisterName(Reg,PE::NoRegAltName);
+
+}
\ No newline at end of file
diff --git a/llvm/lib/Target/PE/MCTargetDesc/PEInstPrinter.h b/llvm/lib/Target/PE/MCTargetDesc/PEInstPrinter.h
new file mode 100644
index 0000000000000..4bcc53a30e515
--- /dev/null
+++ b/llvm/lib/Target/PE/MCTargetDesc/PEInstPrinter.h
@@ -0,0 +1,51 @@
+/* --- PEInstPrinter.h --- */
+
+/* ------------------------------------------
+Author: 高宇翔
+Date: 4/9/2025
+------------------------------------------ */
+
+#ifndef PEINSTPRINTER_H
+#define PEINSTPRINTER_H
+
+#include "llvm/MC/MCInstPrinter.h"
+#include "MCTargetDesc/PEMCTargetDesc.h"
+
+namespace llvm {
+class PEInstPrinter : public MCInstPrinter {
+public:
+ PEInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
+ const MCRegisterInfo &MRI)
+ : MCInstPrinter(MAI, MII, MRI) {}
+
+ std::pair<const char *, uint64_t> getMnemonic(const MCInst &MI) const;
+ void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O);
+ static const char *getRegisterName(MCRegister Reg);
+ static const char *getRegisterName(MCRegister Reg, unsigned AltIdx);
+
+ void printRegName(raw_ostream &OS, MCRegister Reg) override;
+ void printInst(const MCInst *MI, uint64_t Address, StringRef Annot,
+ const MCSubtargetInfo &STI, raw_ostream &O) override;
+ void printCCOperand(const MCInst *MI, int OpNum, raw_ostream &O);
+ void printU6(const MCInst *MI, int OpNum, raw_ostream &O);
+
+ bool printAliasInstr(const MCInst *MI, uint64_t Address, raw_ostream &OS);
+
+ void PrintMemOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+
+private:
+ void printMemOperandRI(const MCInst *MI, unsigned OpNum, raw_ostream &O);
+ void printOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
+ void printOperand(const MCInst *MI, uint64_t /*Address*/, unsigned OpNum,
+ raw_ostream &O) {
+ printOperand(MI, OpNum, O);
+ }
+ void printPredicateOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
+ void printBRCCPredicateOperand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O);
+ void printU6ShiftedBy(unsigned ShiftBy, const MCInst *MI, int OpNum,
+ raw_ostream &O);
+};
+} // namespace llvm
+
+#endif // PEINSTPRINTER_H
\ No newline at end of file
diff --git a/llvm/lib/Target/PE/MCTargetDesc/PEMCTargetDesc.cpp b/llvm/lib/Target/PE/MCTargetDesc/PEMCTargetDesc.cpp
index e0f84a908bbc6..81ed3c78358b3 100644
--- a/llvm/lib/Target/PE/MCTargetDesc/PEMCTargetDesc.cpp
+++ b/llvm/lib/Target/PE/MCTargetDesc/PEMCTargetDesc.cpp
@@ -3,6 +3,7 @@
#include "PEInstrInfo.h"
#include "PERegisterInfo.h"
#include "PESubtarget.h"
+#include "PEInstPrinter.h"
#include "llvm/MC/TargetRegistry.h"
#include "TargetInfo/PETargetInfo.h"
@@ -43,14 +44,22 @@ static MCInstrInfo *createPEMCInstrInfo() {
}
static MCSubtargetInfo *createPEMCSubtargetInfo(const Triple &TT,
StringRef CPU, StringRef FS){
- if(CPU.empty() || CPU == "generic")
+ if(CPU.empty())
CPU = "PE";
return createPEMCSubtargetInfoImpl(TT,CPU,CPU,FS);
}
+static MCInstPrinter *createPEMCInstPrinter(const Triple &T,
+ unsigned SyntaxVariant,
+ const MCAsmInfo &MAI,
+ const MCInstrInfo &MII,
+ const MCRegisterInfo &MRI) {
+ return new PEInstPrinter(MAI, MII, MRI);
+}
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePETargetMC() {
TargetRegistry::RegisterMCAsmInfo(getPETarget(), createPEMCAsmInfo);
TargetRegistry::RegisterMCRegInfo(getPETarget(), createPEMCRegisterInfo);
TargetRegistry::RegisterMCInstrInfo(getPETarget(), createPEMCInstrInfo);
TargetRegistry::RegisterMCSubtargetInfo(getPETarget(), createPEMCSubtargetInfo);//子目标信息注册
-}
\ No newline at end of file
+ TargetRegistry::RegisterMCInstPrinter(getPETarget(), createPEMCInstPrinter);
+}
\ No newline at end of file
diff --git a/llvm/lib/Target/PE/PE.h b/llvm/lib/Target/PE/PE.h
new file mode 100644
index 0000000000000..7d0915f2fc91d
--- /dev/null
+++ b/llvm/lib/Target/PE/PE.h
@@ -0,0 +1,19 @@
+/* --- PE.h --- */
+
+/* ------------------------------------------
+Author: undefined
+Date: 4/7/2025
+------------------------------------------ */
+
+#ifndef PE_H
+#define PE_H
+#include "llvm/Target/TargetMachine.h"
+namespace llvm{
+ class FunctionPass;
+ class PETargetMachine;
+ FunctionPass *createPEISelDag(PETargetMachine &TM,CodeGenOptLevel OptLevel);
+ void initializePEDAGToDAGISelLegacyPass(PassRegistry &);
+}
+
+
+#endif // PE_H
diff --git a/llvm/lib/Target/PE/PE.td b/llvm/lib/Target/PE/PE.td
index 2ace8c4f1ae42..4a14a51c53818 100755
--- a/llvm/lib/Target/PE/PE.td
+++ b/llvm/lib/Target/PE/PE.td
@@ -3,7 +3,7 @@ include "llvm/Target/Target.td"//llvm框架层内置的文件
include "PEInstrInfo.td"
include "PECallingConv.td"
-def : ProcessorModel<"generic", NoSchedModel, []>; // 定义一个处理器模型
+def : ProcessorModel<"PE", NoSchedModel, []>; // 定义一个处理器模型
// 定义 PE 指令集信息
def PEInstrInfo : InstrInfo;
diff --git a/llvm/lib/Target/PE/PEAsmPrinter.cpp b/llvm/lib/Target/PE/PEAsmPrinter.cpp
new file mode 100644
index 0000000000000..81cacb022b0b4
--- /dev/null
+++ b/llvm/lib/Target/PE/PEAsmPrinter.cpp
@@ -0,0 +1,56 @@
+/* --- PEAsmPrinter.cpp --- */
+
+/* ------------------------------------------
+author: undefined
+date: 4/9/2025
+------------------------------------------ */
+
+#include "PEAsmPrinter.h"
+#include "MCTargetDesc/PEMCTargetDesc.h"
+using namespace llvm;
+#define DEBUG_TYPE "asm-printer"
+
+#include "PEGenMCPseudoLowering.inc"
+bool PEAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
+ AsmPrinter::runOnMachineFunction(MF);
+ return true;
+}
+
+void PEAsmPrinter::emitInstruction(const MachineInstr *MI) {
+
+ if(MCInst OutInst;lowerPseudoInstExpansion(MI, OutInst)){
+ EmitToStreamer(*OutStreamer, OutInst);
+ return;
+ }
+ MCInst TmpInst;
+ lowerToMCInst(MI, TmpInst);
+ EmitToStreamer(*OutStreamer, TmpInst);
+}
+
+bool PEAsmPrinter::lowerToMCInst(const MachineInstr *MI, MCInst &OutMI){
+ OutMI.setOpcode(MI->getOpcode());
+ for (const MachineOperand &MO : MI->operands()) {
+ MCOperand MCOp;
+ switch (MO.getType())
+ {
+ case MachineOperand::MO_Register:{
+ MCOp = MCOperand::createReg(MO.getReg());
+ break;
+ }
+ case MachineOperand::MO_Immediate:{
+ MCOp = MCOperand::createImm(MO.getImm());
+ break;
+ }
+ default:
+ llvm_unreachable("Unhandled operand type");
+ break;
+ }
+ OutMI.addOperand(MCOp);
+ }
+ return true;
+}
+
+extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePEAsmPrinter() {
+ RegisterAsmPrinter<PEAsmPrinter> X(getPETarget());
+ }
+
\ No newline at end of file
diff --git a/llvm/lib/Target/PE/PEAsmPrinter.h b/llvm/lib/Target/PE/PEAsmPrinter.h
new file mode 100644
index 0000000000000..c86ed1dd4eede
--- /dev/null
+++ b/llvm/lib/Target/PE/PEAsmPrinter.h
@@ -0,0 +1,44 @@
+/* --- PEAsmPrinter.h --- */
+
+/* ------------------------------------------
+Author: undefined
+Date: 4/9/2025
+------------------------------------------ */
+
+#ifndef PEASMPRINTER_H
+#define PEASMPRINTER_H
+
+#include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/TargetRegistry.h"
+#include "llvm/MC/MCInst.h"
+#include "PETargetMachine.h"
+#include "TargetInfo/PETargetInfo.h"
+#include "llvm/Target/TargetMachine.h"
+
+namespace llvm{
+
+class PESubtarget;
+class PEAsmPrinter : public AsmPrinter{
+ const PESubtarget *Subtarget;
+public:
+ explicit PEAsmPrinter(TargetMachine &TM,
+ std::unique_ptr<MCStreamer> Streamer)
+: AsmPrinter(TM, std::move(Streamer)) {}
+
+ StringRef getPassName() const override { return "PE Assembly Printer"; }
+
+ virtual bool runOnMachineFunction(MachineFunction &MF) override;
+
+ void emitInstruction(const MachineInstr *MI) override;
+
+private:
+ bool lowerPseudoInstExpansion(const MachineInstr *MI, MCInst &Inst);
+ bool lowerToMCInst(const MachineInstr *MI, MCInst &OutMI);
+
+private:
+
+};
+}
+
+#endif // PEASMPRINTER_H
diff --git a/llvm/lib/Target/PE/PEISelDAGToDAG.cpp b/llvm/lib/Target/PE/PEISelDAGToDAG.cpp
new file mode 100644
index 0000000000000..1d2f1bf950f20
--- /dev/null
+++ b/llvm/lib/Target/PE/PEISelDAGToDAG.cpp
@@ -0,0 +1,81 @@
+/* --- PEISelDAGToDAG.cpp --- */
+
+/* ------------------------------------------
+author: 高宇翔
+date: 4/7/2025
+------------------------------------------ */
+
+//指令选择pass
+#include "llvm/CodeGen/SelectionDAGISel.h"
+#include "PE.h"
+#include "PETargetMachine.h"
+#include "MCTargetDesc/PEMCTargetDesc.h"
+#include "PESubtarget.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "pe-isel"
+#define PASS_NAME "PE DAG->DAG Pattern Instruction Selection"
+
+class PEDAGToDAGISel : public SelectionDAGISel {
+ const PESubtarget *Subtarget = nullptr;
+
+public:
+ PEDAGToDAGISel() = delete;
+ explicit PEDAGToDAGISel(PETargetMachine &TM) : SelectionDAGISel(TM){}
+
+ bool runOnMachineFunction(MachineFunction &MF) override;
+
+ bool SelectAddrFI(SDNode *Parent,SDValue AddrFI, SDValue &Base, SDValue &Offset);
+
+private:
+#include "PEGenDAGISel.inc"
+ void Select(SDNode *Node) override;
+ const PETargetMachine &getTargetMachine() {
+ return static_cast<const PETargetMachine &>(TM);
+ }
+};
+
+class PEDAGToDAGISelLegacy : public SelectionDAGISelLegacy {
+public:
+ static char ID;
+ explicit PEDAGToDAGISelLegacy(PETargetMachine &TargetMachine, CodeGenOptLevel OptLevel);
+};
+
+bool PEDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) {
+ Subtarget = &MF.getSubtarget<PESubtarget>();
+ return SelectionDAGISel::runOnMachineFunction(MF);
+}
+
+bool PEDAGToDAGISel::SelectAddrFI(SDNode *Parent, SDValue AddrFI, SDValue &Base,
+ SDValue &Offset) {
+ if(FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(AddrFI)){
+ Base = CurDAG->getTargetFrameIndex(FIN->getIndex(),
+ AddrFI.getValueType());
+ Offset = CurDAG->getTargetConstant(0, SDLoc(AddrFI),
+ AddrFI.getValueType());
+ return true;
+ }
+ return false;
+}
+
+void PEDAGToDAGISel::Select(SDNode *Node) {
+ unsigned Opcode = Node->getOpcode();
+ SDLoc DL(Node);
+
+ LLVM_DEBUG(dbgs() << "== "; Node->dump(CurDAG); dbgs() << "\n");
+
+ SelectCode(Node);
+}
+
+FunctionPass *llvm::createPEISelDag(PETargetMachine &TM, CodeGenOptLevel OptLevel) {
+ return new PEDAGToDAGISelLegacy(TM, OptLevel);
+}
+
+char PEDAGToDAGISelLegacy::ID = 0;
+
+PEDAGToDAGISelLegacy::PEDAGToDAGISelLegacy(PETargetMachine &TM, CodeGenOptLevel OptLevel)
+ : SelectionDAGISelLegacy(ID, std::make_unique<PEDAGToDAGISel>(TM)) {}
+
+//注册一个pass
+INITIALIZE_PASS(PEDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false)
\ No newline at end of file
diff --git a/llvm/lib/Target/PE/PEISelLowering.cpp b/llvm/lib/Target/PE/PEISelLowering.cpp
index 5343113a5882d..ce88e75e089d3 100644
--- a/llvm/lib/Target/PE/PEISelLowering.cpp
+++ b/llvm/lib/Target/PE/PEISelLowering.cpp
@@ -34,7 +34,7 @@ SDValue PETargetLowering::LowerFormalArguments(
SDValue PETargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
bool IsVarArg,
const SmallVectorImpl<ISD::OutputArg> &Outs,
- const SmallVectorImpl<SDValue> &OutVals,
+ const SmallVectorImpl<SDValue> &OutVals,
const SDLoc &DL, SelectionDAG &DAG) const {
// 1. 返回物理寄存器
SmallVector<CCValAssign, 16> RVLocs;
@@ -58,4 +58,14 @@ SDValue PETargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
RetOps.push_back(Glue);
}
return DAG.getNode(PEISD::RET_GLUE, DL, MVT::Other, RetOps);
-}
\ No newline at end of file
+}
+
+const char *llvm::PETargetLowering::getTargetNodeName(unsigned Opcode) const {
+ switch (Opcode) {
+ case PEISD::RET_GLUE:
+ return "PEISD::RET_GLUE";
+ default:
+ return nullptr;
+ }
+ return nullptr;
+}
diff --git a/llvm/lib/Target/PE/PEISelLowering.h b/llvm/lib/Target/PE/PEISelLowering.h
index 76a30e6ce2f1c..6f51883014e87 100644
--- a/llvm/lib/Target/PE/PEISelLowering.h
+++ b/llvm/lib/Target/PE/PEISelLowering.h
@@ -38,6 +38,7 @@ class PETargetLowering : public TargetLowering {
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
SelectionDAG &DAG) const override;
+ const char *getTargetNodeName(unsigned Opcode) const override;
};
} // namespace llvm
diff --git a/llvm/lib/Target/PE/PEInstrFormats.td b/llvm/lib/Target/PE/PEInstrFormats.td
index 31a966131b6a5..cca993bcd6bde 100755
--- a/llvm/lib/Target/PE/PEInstrFormats.td
+++ b/llvm/lib/Target/PE/PEInstrFormats.td
@@ -1,20 +1,6 @@
-//通用指令模版,后序修改
-
-class PEOpcode<string name, bits<7> val,bits<3>funct3> {
- string Name = name;
- bits<7> Value = val;
- bits<3> FUNCT3 = funct3;
-}
-
-//实例化操作码
-def OPC_ADDI : PEOpcode<"ADDI",0b0010011,0b000>;
-def OPC_JALR : PEOpcode<"JALR",0b1101111,0b000>;
-
-
class PEInst<dag outs, dag ins, string asmstr,list<dag> pattern>
: Instruction
{
- field bits<32> Inst;//指令的编码,每个bit意义
field bits<32> SoftFail = 0;//软件错误,传0,用于反汇编程序
let Size = 4;
@@ -31,19 +17,7 @@ class PseudoInst<dag outs, dag ins,list<dag> pattern,string asmstr = "">
let isCodeGenOnly = 1;//存在于代码生成
let Size = 4;
}
-class I<PEOpcode opcode, dag outs, dag ins,
+class I<dag outs, dag ins,
string asmstr, list<dag> pattern>
: PEInst< outs, ins, asmstr, pattern> {
-//RISCV32的I-type指令格式:imm[11:0] rs1 funct3 rd opcode
- bits<7> Opcode = opcode.Value;
- bits<5> rd;
- bits<3> funct3 = opcode.FUNCT3;
- bits<5> rs1;
- bits<12> imm12;
-
- let Inst{6-0} = Opcode;
- let Inst{11-7} = rd;
- let Inst{14-12} = funct3;
- let Inst{19-15} = rs1;
- let Inst{31-20} = imm12;
}
\ No newline at end of file
diff --git a/llvm/lib/Target/PE/PEInstrInfo.td b/llvm/lib/Target/PE/PEInstrInfo.td
index 1eabf3e5d3d17..81b6ac1f52b2e 100755
--- a/llvm/lib/Target/PE/PEInstrInfo.td
+++ b/llvm/lib/Target/PE/PEInstrInfo.td
@@ -13,21 +13,42 @@ include "PERegisterInfo.td"
def retglue : SDNode <"PEISD::RET_GLUE",SDTNone,
[SDNPHasChain,SDNPOptInGlue,SDNPVariadic]>;
+def imm12 : Operand<i32>,ImmLeaf<i32,[{return isInt<12>(Imm);}]>;
+// def imm12Pat : ImmLeaf<i32,[{return isInt<12>(Imm);}]>;
+
+//自定义内存操作数
+def mem : Operand<iPTR>{
+ ///指明具体操作数
+ let MIOperandInfo = (ops GPR,imm12);
+
+ ///指明自定义打印函数
+ let PrintMethod = "PrintMemOperand";
+}
+
+//地址约束规则,判断是不是地址
+def memPat : ComplexPattern<iPTR,2,"SelectAddrFI",[frameindex],[SDNPWantParent]>;
+
+def LOAD : PEInst<(outs GPR: $ra),(ins mem: $addr),"lw \t$ta,$addr">;
+def : Pat<(loat memPat:$addr),(LOAD memPat:$addr)>;
+
+def STORE : PEInst<(outs),(ins GPR: $ra,mem: $addr),"sw \t$ta,$addr">;
+def : Pat<(store GPR:$ra memPat:$addr),(STORE GPR:$ra memPat:$addr)>;
+
//class I 的实例化
//OPC_ADDI:指令码,GPR:$rd:一个通用寄存器$rd,i32imm:$imm12:一个立即数$imm12
//"addi $rd,$rs1,$imm12":汇编字符串
//[]:模式匹配为空
-def ADDI : I<OPC_ADDI,(outs GPR:$rd),(ins GPR:$rs1,i32imm:$imm12),
+def ADDI : I<(outs GPR:$rd),(ins GPR:$rs1,imm12:$imm12),
"addi $rd,$rs1,$imm12",[]>;
//当IR中出现形如i32 (imm:$imm12)的立即数操作时(例如加载一个32位整数到寄存器),TableGen会将其匹配为ADDI X0, imm:$imm12。X0为RISCV中的0寄存器,恒为0
-def : Pat<(i32 (imm:$imm12)),(ADDI X0,imm:$imm12)>;
+def : Pat<(i32 (imm12:$imm12)),(ADDI X0,imm12:$imm12)>;
// JALR x1, x5, 0 # 跳转到x5的值,返回地址保存到x1
// JALR x0, x10, 8 # 跳转到x10+8,不保存返回地址(用于纯跳转)
// isCall = 1标识该指令为函数调用指令
let isCall = 1 in{
- def JALR : I<OPC_JALR,(outs GPR:$rd),(ins GPR:$rs1,i32imm:$imm12),
+ def JALR : I<(outs GPR:$rd),(ins GPR:$rs1,imm12:$imm12),
"jalr $rd,$rs1,$imm12",[]>;
}
@@ -40,4 +61,7 @@ let isCall = 1 in{
//实际是做指令替换,将IR中的ret伪指令翻译成JALR X0, X1, 0
let isBarrier = 1,isReturn = 1,isTerminator = 1 in{
def pseudoRET : PseudoInst<(outs),(ins),[(retglue)]>,PseudoInstExpansion<(JALR X0, X1, 0)>;
-}
\ No newline at end of file
+}
+
+def : InstAlias<"ret",(JALR X0, X1, 0)>;
+def : InstAlias<"li $rd,&imm",(ADDI GPR:$rd,X0,imm12:&imm)>;
\ No newline at end of file
diff --git a/llvm/lib/Target/PE/PESubtarget.cpp b/llvm/lib/Target/PE/PESubtarget.cpp
index ba23a16da8319..71833d980f105 100644
--- a/llvm/lib/Target/PE/PESubtarget.cpp
+++ b/llvm/lib/Target/PE/PESubtarget.cpp
@@ -9,9 +9,9 @@ date: 4/2/2025
#define GET_SUBTARGETINFO_TARGET_DESC
#define GET_SUBTARGETINFO_CTOR
-#include "PEGenSubtargetInfo.inc"
-
#define DEBUG_TYPE "PE-Subtarget"
+
+#include "PEGenSubtargetInfo.inc"
using namespace llvm;
@@ -25,7 +25,7 @@ PESubtarget::PESubtarget(const Triple &TT, StringRef CPU,
PESubtarget &PESubtarget::initializeSubtargetDependencies(
const Triple &TT, StringRef CPU, StringRef TuneCPU, StringRef FS,
StringRef ABIName) {
- if (CPU.empty() || CPU == "generic")
+ if (CPU.empty())
CPU = "PE";
ParseSubtargetFeatures(CPU, CPU, FS);
diff --git a/llvm/lib/Target/PE/PETargetMachine.cpp b/llvm/lib/Target/PE/PETargetMachine.cpp
index 8ca6a3a9644ac..1d2847d7ef437 100755
--- a/llvm/lib/Target/PE/PETargetMachine.cpp
+++ b/llvm/lib/Target/PE/PETargetMachine.cpp
@@ -1,11 +1,17 @@
#include "llvm/MC/TargetRegistry.h"
#include "TargetInfo/PETargetInfo.h"
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
+#include "llvm/CodeGen/TargetPassConfig.h"
#include "PETargetMachine.h"
-namespace llvm{
+#include "PE.h"
+
+using namespace llvm;
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePETarget() {
RegisterTargetMachine<PETargetMachine>X(getPETarget());
+
+ auto *PR = PassRegistry::getPassRegistry();
+ initializePEDAGToDAGISelLegacyPass(*PR);
}
static StringRef computeDataLayout(const Triple&TT,const TargetOptions &Options){
@@ -57,4 +63,28 @@ TLOF(std::make_unique<TargetLoweringObjectFileELF>()),Subtarget(TT, CPU, FS, *th
*/
initAsmInfo();
}
-}//namespace LLVM
\ No newline at end of file
+
+namespace {
+class PEPassConfig : public TargetPassConfig {
+public:
+ PEPassConfig(PETargetMachine &TM, PassManagerBase &PM)
+ : TargetPassConfig(TM, PM) {}
+
+ PETargetMachine &getPETargetMachine() const {
+ return getTM<PETargetMachine>();
+ }
+ const PESubtarget &getPESubtarget() const {
+ return *getPETargetMachine().getSubtargetImpl();
+ }
+ bool addInstSelector() override;
+};
+}
+
+TargetPassConfig *PETargetMachine::createPassConfig(PassManagerBase &PM) {
+ return new PEPassConfig(*this, PM);
+}
+
+bool PEPassConfig::addInstSelector() {
+ addPass(createPEISelDag(getPETargetMachine(), CodeGenOptLevel::None));
+ return false;
+}
\ No newline at end of file
diff --git a/llvm/lib/Target/PE/PETargetMachine.h b/llvm/lib/Target/PE/PETargetMachine.h
index ff292fdeb5e59..da7d7d8c2808d 100755
--- a/llvm/lib/Target/PE/PETargetMachine.h
+++ b/llvm/lib/Target/PE/PETargetMachine.h
@@ -1,7 +1,9 @@
#include "llvm/CodeGen/CodeGenTargetMachineImpl.h"
#include "PESubtarget.h"
+
namespace llvm{
+
class PETargetMachine : public CodeGenTargetMachineImpl
{
std::unique_ptr<TargetLoweringObjectFile> TLOF;
@@ -17,7 +19,11 @@ class PETargetMachine : public CodeGenTargetMachineImpl
const PESubtarget *getSubtargetImpl() const {return &Subtarget;}
const PESubtarget *getSubtargetImpl(const Function &F) const override{return &Subtarget;}
-
+ TargetLoweringObjectFile *getObjFileLowering() const override
+ {
+ return TLOF.get();
+ }
+ TargetPassConfig *createPassConfig(PassManagerBase &PM) override;
};
}
\ No newline at end of file
More information about the llvm-commits
mailing list