Files
scriptc/native/llvm-codegen/src/target.cpp
Chris Tate 3f66c8e20b Make LLVM the sole production backend
- Remove C emission, debugging options, and automatic backend fallback.
- Complete LLVM lowering and native bootstrap coverage across supported targets.
- Link executables and libraries with precompiled C runtime packs, including iOS and Android.
2026-09-29 20:54:09 -05:00

130 lines
3.6 KiB
C++

#include "target.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/TargetParser/Triple.h"
using namespace llvm;
#if defined(SCRIPTC_ENABLE_AARCH64)
extern "C" {
void LLVMInitializeAArch64TargetInfo();
void LLVMInitializeAArch64Target();
void LLVMInitializeAArch64TargetMC();
void LLVMInitializeAArch64AsmPrinter();
}
#endif
#if defined(SCRIPTC_ENABLE_X86)
extern "C" {
void LLVMInitializeX86TargetInfo();
void LLVMInitializeX86Target();
void LLVMInitializeX86TargetMC();
void LLVMInitializeX86AsmPrinter();
}
#endif
#if defined(SCRIPTC_ENABLE_WEBASSEMBLY)
extern "C" {
void LLVMInitializeWebAssemblyTargetInfo();
void LLVMInitializeWebAssemblyTarget();
void LLVMInitializeWebAssemblyTargetMC();
void LLVMInitializeWebAssemblyAsmPrinter();
}
#endif
namespace scriptc {
void initializeTargets() {
static bool Initialized = false;
if (Initialized)
return;
#if defined(SCRIPTC_ENABLE_AARCH64)
LLVMInitializeAArch64TargetInfo();
LLVMInitializeAArch64Target();
LLVMInitializeAArch64TargetMC();
LLVMInitializeAArch64AsmPrinter();
#endif
#if defined(SCRIPTC_ENABLE_X86)
LLVMInitializeX86TargetInfo();
LLVMInitializeX86Target();
LLVMInitializeX86TargetMC();
LLVMInitializeX86AsmPrinter();
#endif
#if defined(SCRIPTC_ENABLE_WEBASSEMBLY)
LLVMInitializeWebAssemblyTargetInfo();
LLVMInitializeWebAssemblyTarget();
LLVMInitializeWebAssemblyTargetMC();
LLVMInitializeWebAssemblyAsmPrinter();
#endif
Initialized = true;
}
bool supportsTarget(StringRef TripleName) {
bool Allowed = false;
StringRef Remaining = AllowedTargets;
while (!Remaining.empty()) {
auto Split = Remaining.split(',');
if (Split.first == TripleName) {
Allowed = true;
break;
}
Remaining = Split.second;
}
if (!Allowed)
return false;
Triple Triple(TripleName);
switch (Triple.getArch()) {
#if defined(SCRIPTC_ENABLE_AARCH64)
case Triple::aarch64:
case Triple::aarch64_be:
return Triple.isOSBinFormatMachO() || Triple.isOSBinFormatELF();
#endif
#if defined(SCRIPTC_ENABLE_X86)
case Triple::x86_64:
case Triple::x86:
return Triple.isOSBinFormatMachO() || Triple.isOSBinFormatELF() ||
Triple.isOSBinFormatCOFF();
#endif
#if defined(SCRIPTC_ENABLE_WEBASSEMBLY)
case Triple::wasm32:
return Triple.isOSBinFormatWasm();
#endif
default:
return false;
}
}
static CodeGenOptLevel codeGenLevel(StringRef Level) {
if (Level == "0")
return CodeGenOptLevel::None;
if (Level == "1")
return CodeGenOptLevel::Less;
if (Level == "3")
return CodeGenOptLevel::Aggressive;
return CodeGenOptLevel::Default;
}
std::unique_ptr<TargetMachine> createTargetMachine(StringRef TripleName,
StringRef OptLevel,
std::string &Error) {
initializeTargets();
if (!supportsTarget(TripleName)) {
Error = (Twine("target '") + TripleName + "' was not compiled into this helper").str();
return nullptr;
}
Triple TargetTriple(TripleName);
const Target *Definition = TargetRegistry::lookupTarget(TargetTriple, Error);
if (Definition == nullptr)
return nullptr;
TargetOptions Options;
// The Android API 26 runtime pack uses the NDK's emulated TLS ABI.
// Program globals and runtime thread instances must use the same ABI.
Options.EmulatedTLS = TargetTriple.isAndroid();
return std::unique_ptr<TargetMachine>(Definition->createTargetMachine(
TargetTriple, "generic", "", Options, Reloc::PIC_, CodeModel::Small,
codeGenLevel(OptLevel)));
}
} // namespace scriptc