LLVM 22.x tile for building compilers, language runtimes, and out-of-tree tooling
88
83%
Does it follow best practices?
Impact
96%
1.23xAverage score across 5 eval scenarios
Passed
No known issues
Use this skill when the user wants to add a brand-new ISA target to LLVM 22. This produces a compilable, registered skeleton — not a production backend. Extend each layer incrementally after the skeleton builds.
Pick a short, capitalized name: MyISA. This will be used as:
llvm/lib/Target/MyISA/llvm (all LLVM code lives here)MyISACodeGen, MyISADesc, MyISAInfo, MyISAAsmParsermyisa (lower-case, used in target triples)LLVMInitializeMyISATarget()CMakeLists.txt# llvm/CMakeLists.txt — add to LLVM_ALL_TARGETS list
set(LLVM_ALL_TARGETS
...
MyISA
...
)And in llvm/include/llvm/Config/llvm-config.h.cmake (auto-generated, handled
by cmake) — no manual edit needed; cmake regenerates it.
llvm/lib/Target/MyISA/
├── CMakeLists.txt
├── MyISA.h # Forward declarations, target init prototype
├── MyISA.td # Top-level TableGen file
├── MyISARegisterInfo.td # Register definitions
├── MyISAInstrInfo.td # Instruction definitions (stub)
├── MyISATargetMachine.h
├── MyISATargetMachine.cpp
├── MyISARegisterInfo.h
├── MyISARegisterInfo.cpp
├── MyISAInstrInfo.h
├── MyISAInstrInfo.cpp
├── MyISAFrameLowering.h
├── MyISAFrameLowering.cpp
├── MyISAISelLowering.h
├── MyISAISelLowering.cpp
├── MyISASubtarget.h
├── MyISASubtarget.cpp
└── MCTargetDesc/
├── CMakeLists.txt
├── MyISAMCAsmInfo.h
├── MyISAMCAsmInfo.cpp
├── MyISAMCTargetDesc.h
└── MyISAMCTargetDesc.cppMyISARegisterInfo.tdclass MyISAReg<bits<5> num, string name> : Register<name> {
let HWEncoding{4-0} = num;
let Namespace = "MyISA";
}
// General purpose registers
def R0 : MyISAReg<0, "r0">;
def R1 : MyISAReg<1, "r1">;
// ... add R2-R31 as needed
def GPR : RegisterClass<"MyISA", [i32], 32, (add R0, R1)>;MyISAInstrInfo.td// Minimal — just enough to compile
class MyISAInst<dag outs, dag ins, string asmstr, list<dag> pattern>
: Instruction {
let Namespace = "MyISA";
let OutOperandList = outs;
let InOperandList = ins;
let AsmString = asmstr;
let Pattern = pattern;
}
// Example: NOP
def NOP : MyISAInst<(outs), (ins), "nop", []>;MyISA.td (top-level)include "llvm/Target/Target.td"
include "MyISARegisterInfo.td"
include "MyISAInstrInfo.td"
def MyISAInstrInfo : InstrInfo;
def MyISA : Target {
let InstructionSet = MyISAInstrInfo;
}MyISAMCTargetDesc.h#ifndef LLVM_LIB_TARGET_MYISA_MCTARGETDESC_MYISAMCTARGETDESC_H
#define LLVM_LIB_TARGET_MYISA_MCTARGETDESC_MYISAMCTARGETDESC_H
#include "llvm/Support/DataTypes.h"
#include <memory>
namespace llvm {
class MCAsmInfo;
class MCContext;
class MCInstrInfo;
class MCRegisterInfo;
class MCSubtargetInfo;
class MCTargetOptions;
class Target;
Target &getTheMyISATarget();
} // namespace llvm
// Generated by TableGen:
#define GET_REGINFO_ENUM
#include "MyISAGenRegisterInfo.inc"
#define GET_INSTRINFO_ENUM
#include "MyISAGenInstrInfo.inc"
#endifMyISAMCTargetDesc.cpp#include "MyISAMCTargetDesc.h"
#include "MyISAMCAsmInfo.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/FormattedStream.h"
using namespace llvm;
#define GET_INSTRINFO_MC_DESC
#include "MyISAGenInstrInfo.inc"
#define GET_REGINFO_MC_DESC
#include "MyISAGenRegisterInfo.inc"
#define GET_SUBTARGETINFO_MC_DESC
#include "MyISAGenSubtargetInfo.inc"
static MCInstrInfo *createMyISAMCInstrInfo() {
MCInstrInfo *X = new MCInstrInfo();
InitMyISAMCInstrInfo(X);
return X;
}
static MCRegisterInfo *createMyISAMCRegisterInfo(const Triple &TT) {
MCRegisterInfo *X = new MCRegisterInfo();
InitMyISAMCRegisterInfo(X, MyISA::R0); // return address register
return X;
}
static MCSubtargetInfo *
createMyISAMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) {
return createMyISAMCSubtargetInfoImpl(TT, CPU, /*TuneCPU=*/CPU, FS);
}
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMyISATargetMC() {
TargetRegistry::RegisterMCInstrInfo(getTheMyISATarget(),
createMyISAMCInstrInfo);
TargetRegistry::RegisterMCRegInfo(getTheMyISATarget(),
createMyISAMCRegisterInfo);
TargetRegistry::RegisterMCSubtargetInfo(getTheMyISATarget(),
createMyISAMCSubtargetInfo);
}MCTargetDesc/CMakeLists.txtadd_llvm_component_library(LLVMMyISADesc
MyISAMCAsmInfo.cpp
MyISAMCTargetDesc.cpp
LINK_COMPONENTS
MC
Support
TargetParser
ADD_TO_COMPONENT MyISA
)MyISATargetMachine.h#ifndef LLVM_LIB_TARGET_MYISA_MYISATARGETMACHINE_H
#define LLVM_LIB_TARGET_MYISA_MYISATARGETMACHINE_H
#include "MyISASubtarget.h"
#include "llvm/Target/TargetMachine.h"
namespace llvm {
class MyISATargetMachine : public LLVMTargetMachine {
MyISASubtarget Subtarget;
public:
MyISATargetMachine(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 MyISASubtarget *getSubtargetImpl(const Function &) const override {
return &Subtarget;
}
TargetPassConfig *createPassConfig(PassManagerBase &PM) override;
};
} // namespace llvm
#endifMyISATargetMachine.cpp#include "MyISATargetMachine.h"
#include "MCTargetDesc/MyISAMCTargetDesc.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/PassRegistry.h"
using namespace llvm;
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMyISATarget() {
RegisterTargetMachine<MyISATargetMachine> X(getTheMyISATarget());
}
static const char *MyISADataLayout =
"e-m:e-p:32:32-i64:64-n32-S128"; // adjust for your ISA
MyISATargetMachine::MyISATargetMachine(
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)
: LLVMTargetMachine(T, MyISADataLayout, TT, CPU, FS, Options,
RM.value_or(Reloc::Static),
CM.value_or(CodeModel::Small), OL),
Subtarget(TT, CPU, FS, *this) {}
namespace {
class MyISAPassConfig : public TargetPassConfig {
public:
MyISAPassConfig(MyISATargetMachine &TM, PassManagerBase &PM)
: TargetPassConfig(TM, PM) {}
bool addInstSelector() override {
// TODO: addPass(createMyISAISelDag(...));
return false;
}
};
} // namespace
TargetPassConfig *MyISATargetMachine::createPassConfig(PassManagerBase &PM) {
return new MyISAPassConfig(*this, PM);
}In MyISA.h / MCTargetDesc/MyISAMCTargetDesc.cpp, expose getTheMyISATarget():
// MyISA.h
namespace llvm {
Target &getTheMyISATarget();
}
// MyISATargetInfo.cpp (new file, add to CMakeLists.txt under TargetInfo/)
#include "llvm/MC/TargetRegistry.h"
namespace llvm {
Target &getTheMyISATarget() {
static Target TheMyISATarget;
return TheMyISATarget;
}
} // namespace llvm
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMyISATargetInfo() {
RegisterTarget<Triple::myisa, /*HasJIT=*/false> X(
getTheMyISATarget(), "myisa", "MyISA (32-bit)", "MyISA");
}Add the myisa arch to llvm/include/llvm/TargetParser/Triple.h (the ArchType enum) and the string mapping in Triple.cpp.
CMakeLists.txt for the target# llvm/lib/Target/MyISA/CMakeLists.txt
add_llvm_component_group(MyISA)
set(LLVM_TARGET_DEFINITIONS MyISA.td)
tablegen(LLVM MyISAGenRegisterInfo.inc -gen-register-info)
tablegen(LLVM MyISAGenInstrInfo.inc -gen-instr-info)
tablegen(LLVM MyISAGenSubtargetInfo.inc -gen-subtarget)
tablegen(LLVM MyISAGenAsmWriter.inc -gen-asm-writer)
add_public_tablegen_target(MyISACommonTableGen)
add_llvm_component_library(LLVMMyISACodeGen
MyISAFrameLowering.cpp
MyISAInstrInfo.cpp
MyISAISelLowering.cpp
MyISARegisterInfo.cpp
MyISASubtarget.cpp
MyISATargetMachine.cpp
LINK_COMPONENTS
Analysis
AsmPrinter
CodeGen
CodeGenTypes
Core
MC
MyISADesc
MyISAInfo
SelectionDAG
Support
Target
TransformUtils
ADD_TO_COMPONENT MyISA
)
add_subdirectory(MCTargetDesc)
add_subdirectory(TargetInfo)cmake --build build --target LLVMMyISACodeGen -j$(nproc)
# Verify the target appears in llc/opt
llc --version | grep myisa
opt --version | grep myisa # opt doesn't list targets, but no crash = good
# Attempt codegen (will fail gracefully without an isel):
echo 'define void @f() { ret void }' | \
llc -march=myisa -.td patterns or GlobalISel GISelCombiner + Legalizer..s text output.Triple.h and Triple.cpp — the target won't be found by llc -march=.LLVMInitializeMyISATargetInfo() / LLVMInitializeMyISATargetMC() — they must all be called for the target to be usable.Reloc::PIC_ without implementing PIC support in ISelLowering — default to Reloc::Static in the skeleton.ADD_TO_COMPONENT MyISA in all sub-library CMakeLists.txt so llvm_map_components_to_libnames(MyISA) works for downstream users.tablegen targets before the main library target — the .inc files must exist at compile time.docs
evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
skills
add-alias-analysis
add-attributes-metadata
add-calling-convention
add-debug-info
add-exception-handling
add-gc-statepoints
add-intrinsic
add-lto
add-sanitizer
add-vectorization-hint
frontend-to-ir
jit-setup
lit-filecheck
lower-struct-types
new-target
out-of-tree-setup
tessl-llvm
version-sync