[PATCH] [x86] Add x86_16 target
David Woodhouse
dwmw2 at infradead.org
Wed Jan 8 05:48:47 PST 2014
This is now fairly trivial. With the corresponding patch (qv) to Clang
to enable -m16, and with PR18303 fixed and PR3997 worked around, I can
now correctly build all the Linux kernel's 16-bit startup code and get a
bootable kernel.
The x86_16 target is equivalent to building with GCC and
asm(".code16gcc"). It doesn't have sizeof(int)==2 etc.; it uses the same
ABI as 32-bit x86, and you just see a lot of OpSize and AdSize prefixes
in the resulting code. Thus, it won't actually run on a *real* i8086 but
it does work fine on modern CPUs in 16-bit mode.
---
include/llvm/ADT/Triple.h | 1 +
lib/MC/MCObjectFileInfo.cpp | 5 ++--
lib/Support/Triple.cpp | 10 +++++++-
lib/Target/TargetLibraryInfo.cpp | 2 +-
lib/Target/X86/AsmParser/X86AsmParser.cpp | 1 +
lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp | 32 +++++++++++++++++++++----
lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h | 2 +-
lib/Target/X86/TargetInfo/X86TargetInfo.cpp | 5 +++-
lib/Target/X86/X86AsmPrinter.cpp | 1 +
lib/Target/X86/X86Subtarget.cpp | 2 +-
lib/Target/X86/X86TargetMachine.cpp | 1 +
11 files changed, 50 insertions(+), 12 deletions(-)
diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h
index 314ee4e..633c6c4 100644
--- a/include/llvm/ADT/Triple.h
+++ b/include/llvm/ADT/Triple.h
@@ -65,6 +65,7 @@ public:
thumb, // Thumb: thumb, thumbv.*
x86, // X86: i[3-9]86
x86_64, // X86-64: amd64, x86_64
+ x86_16, // X86-16: 16-bit mode (equivalent to .code16gcc)
xcore, // XCore: xcore
nvptx, // NVPTX: 32-bit
nvptx64, // NVPTX: 64-bit
diff --git a/lib/MC/MCObjectFileInfo.cpp b/lib/MC/MCObjectFileInfo.cpp
index 5d7a5f8..5d28667 100644
--- a/lib/MC/MCObjectFileInfo.cpp
+++ b/lib/MC/MCObjectFileInfo.cpp
@@ -156,7 +156,8 @@ void MCObjectFileInfo::InitMachOMCObjectFileInfo(Triple T) {
MCSectionMachO::S_ATTR_DEBUG,
SectionKind::getReadOnly());
- if (T.getArch() == Triple::x86_64 || T.getArch() == Triple::x86)
+ if (T.getArch() == Triple::x86_64 || T.getArch() == Triple::x86 ||
+ T.getArch() == Triple::x86_16)
CompactUnwindDwarfEHFrameOnly = 0x04000000;
}
@@ -252,7 +253,7 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) {
else
FDECFIEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
- if (T.getArch() == Triple::x86) {
+ if (T.getArch() == Triple::x86 || T.getArch() == Triple::x86_16) {
PersonalityEncoding = (RelocM == Reloc::PIC_)
? dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4
: dwarf::DW_EH_PE_absptr;
diff --git a/lib/Support/Triple.cpp b/lib/Support/Triple.cpp
index 273316a..8acf319 100644
--- a/lib/Support/Triple.cpp
+++ b/lib/Support/Triple.cpp
@@ -38,6 +38,7 @@ const char *Triple::getArchTypeName(ArchType Kind) {
case thumb: return "thumb";
case x86: return "i386";
case x86_64: return "x86_64";
+ case x86_16: return "x86_16";
case xcore: return "xcore";
case nvptx: return "nvptx";
case nvptx64: return "nvptx64";
@@ -79,7 +80,8 @@ const char *Triple::getArchTypePrefix(ArchType Kind) {
case systemz: return "systemz";
case x86:
- case x86_64: return "x86";
+ case x86_64:
+ case x86_16: return "x86";
case xcore: return "xcore";
@@ -181,6 +183,7 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
.Case("thumb", thumb)
.Case("x86", x86)
.Case("x86-64", x86_64)
+ .Case("x86-16", x86_16)
.Case("xcore", xcore)
.Case("nvptx", nvptx)
.Case("nvptx64", nvptx64)
@@ -199,6 +202,7 @@ const char *Triple::getArchNameForAssembler() {
return StringSwitch<const char*>(getArchName())
.Case("i386", "i386")
.Case("x86_64", "x86_64")
+ .Case("x86_16", "x86_16")
.Case("powerpc", "ppc")
.Case("powerpc64", "ppc64")
.Case("powerpc64le", "ppc64le")
@@ -223,6 +227,7 @@ static Triple::ArchType parseArch(StringRef ArchName) {
// FIXME: Do we need to support these?
.Cases("i786", "i886", "i986", Triple::x86)
.Cases("amd64", "x86_64", "x86_64h", Triple::x86_64)
+ .Cases("x86_16", "i8086", "i86", Triple::x86_16)
.Case("powerpc", Triple::ppc)
.Cases("powerpc64", "ppu", Triple::ppc64)
.Case("powerpc64le", Triple::ppc64le)
@@ -688,6 +693,7 @@ static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
case llvm::Triple::tce:
case llvm::Triple::thumb:
case llvm::Triple::x86:
+ case llvm::Triple::x86_16:
case llvm::Triple::xcore:
case llvm::Triple::spir:
return 32;
@@ -744,6 +750,7 @@ Triple Triple::get32BitArchVariant() const {
case Triple::tce:
case Triple::thumb:
case Triple::x86:
+ case Triple::x86_16:
case Triple::xcore:
// Already 32-bit.
break;
@@ -793,6 +800,7 @@ Triple Triple::get64BitArchVariant() const {
case Triple::nvptx: T.setArch(Triple::nvptx64); break;
case Triple::ppc: T.setArch(Triple::ppc64); break;
case Triple::sparc: T.setArch(Triple::sparcv9); break;
+ case Triple::x86_16:
case Triple::x86: T.setArch(Triple::x86_64); break;
case Triple::spir: T.setArch(Triple::spir64); break;
}
diff --git a/lib/Target/TargetLibraryInfo.cpp b/lib/Target/TargetLibraryInfo.cpp
index 93c008a..59fc07d 100644
--- a/lib/Target/TargetLibraryInfo.cpp
+++ b/lib/Target/TargetLibraryInfo.cpp
@@ -349,7 +349,7 @@ static bool hasSinCosPiStret(const Triple &T) {
return false;
// The ABI is rather complicated on x86, so don't do anything special there.
- if (T.getArch() == Triple::x86)
+ if (T.getArch() == Triple::x86 || T.getArch() == Triple::x86_16)
return false;
if (T.isMacOSX() && T.isMacOSXVersionLT(10, 9))
diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp
index 3ed20d9..c2cde2e 100644
--- a/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -2759,6 +2759,7 @@ bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
// Force static initialization.
extern "C" void LLVMInitializeX86AsmParser() {
+ RegisterMCAsmParser<X86AsmParser> W(TheX86_16Target);
RegisterMCAsmParser<X86AsmParser> X(TheX86_32Target);
RegisterMCAsmParser<X86AsmParser> Y(TheX86_64Target);
}
diff --git a/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp b/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
index 9d5ff10..0fdd9de 100644
--- a/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
+++ b/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
@@ -48,8 +48,12 @@ std::string X86_MC::ParseX86Triple(StringRef TT) {
std::string FS;
if (TheTriple.getArch() == Triple::x86_64)
FS = "+64bit-mode,-32bit-mode,-16bit-mode";
- else
+ else if (TheTriple.getArch() == Triple::x86)
FS = "-64bit-mode,+32bit-mode,-16bit-mode";
+ else if (TheTriple.getArch() == Triple::x86_16)
+ FS = "-64bit-mode,-32bit-mode,+16bit-mode";
+ else
+ llvm_unreachable("no valid arch type");
return FS;
}
@@ -402,58 +406,76 @@ static MCInstrAnalysis *createX86MCInstrAnalysis(const MCInstrInfo *Info) {
// Force static initialization.
extern "C" void LLVMInitializeX86TargetMC() {
// Register the MC asm info.
- RegisterMCAsmInfoFn A(TheX86_32Target, createX86MCAsmInfo);
- RegisterMCAsmInfoFn B(TheX86_64Target, createX86MCAsmInfo);
+ RegisterMCAsmInfoFn A(TheX86_16Target, createX86MCAsmInfo);
+ RegisterMCAsmInfoFn B(TheX86_32Target, createX86MCAsmInfo);
+ RegisterMCAsmInfoFn C(TheX86_64Target, createX86MCAsmInfo);
// Register the MC codegen info.
- RegisterMCCodeGenInfoFn C(TheX86_32Target, createX86MCCodeGenInfo);
- RegisterMCCodeGenInfoFn D(TheX86_64Target, createX86MCCodeGenInfo);
+ RegisterMCCodeGenInfoFn D(TheX86_16Target, createX86MCCodeGenInfo);
+ RegisterMCCodeGenInfoFn E(TheX86_32Target, createX86MCCodeGenInfo);
+ RegisterMCCodeGenInfoFn F(TheX86_64Target, createX86MCCodeGenInfo);
// Register the MC instruction info.
+ TargetRegistry::RegisterMCInstrInfo(TheX86_16Target, createX86MCInstrInfo);
TargetRegistry::RegisterMCInstrInfo(TheX86_32Target, createX86MCInstrInfo);
TargetRegistry::RegisterMCInstrInfo(TheX86_64Target, createX86MCInstrInfo);
// Register the MC register info.
+ TargetRegistry::RegisterMCRegInfo(TheX86_16Target, createX86MCRegisterInfo);
TargetRegistry::RegisterMCRegInfo(TheX86_32Target, createX86MCRegisterInfo);
TargetRegistry::RegisterMCRegInfo(TheX86_64Target, createX86MCRegisterInfo);
// Register the MC subtarget info.
+ TargetRegistry::RegisterMCSubtargetInfo(TheX86_16Target,
+ X86_MC::createX86MCSubtargetInfo);
TargetRegistry::RegisterMCSubtargetInfo(TheX86_32Target,
X86_MC::createX86MCSubtargetInfo);
TargetRegistry::RegisterMCSubtargetInfo(TheX86_64Target,
X86_MC::createX86MCSubtargetInfo);
// Register the MC instruction analyzer.
+ TargetRegistry::RegisterMCInstrAnalysis(TheX86_16Target,
+ createX86MCInstrAnalysis);
TargetRegistry::RegisterMCInstrAnalysis(TheX86_32Target,
createX86MCInstrAnalysis);
TargetRegistry::RegisterMCInstrAnalysis(TheX86_64Target,
createX86MCInstrAnalysis);
// Register the code emitter.
+ TargetRegistry::RegisterMCCodeEmitter(TheX86_16Target,
+ createX86MCCodeEmitter);
TargetRegistry::RegisterMCCodeEmitter(TheX86_32Target,
createX86MCCodeEmitter);
TargetRegistry::RegisterMCCodeEmitter(TheX86_64Target,
createX86MCCodeEmitter);
// Register the asm backend.
+ TargetRegistry::RegisterMCAsmBackend(TheX86_16Target,
+ createX86_32AsmBackend);
TargetRegistry::RegisterMCAsmBackend(TheX86_32Target,
createX86_32AsmBackend);
TargetRegistry::RegisterMCAsmBackend(TheX86_64Target,
createX86_64AsmBackend);
// Register the object streamer.
+ TargetRegistry::RegisterMCObjectStreamer(TheX86_16Target,
+ createMCStreamer);
TargetRegistry::RegisterMCObjectStreamer(TheX86_32Target,
createMCStreamer);
TargetRegistry::RegisterMCObjectStreamer(TheX86_64Target,
createMCStreamer);
// Register the MCInstPrinter.
+ TargetRegistry::RegisterMCInstPrinter(TheX86_16Target,
+ createX86MCInstPrinter);
TargetRegistry::RegisterMCInstPrinter(TheX86_32Target,
createX86MCInstPrinter);
TargetRegistry::RegisterMCInstPrinter(TheX86_64Target,
createX86MCInstPrinter);
// Register the MC relocation info.
+ TargetRegistry::RegisterMCRelocationInfo(TheX86_16Target,
+ createX86MCRelocationInfo);
TargetRegistry::RegisterMCRelocationInfo(TheX86_32Target,
createX86MCRelocationInfo);
TargetRegistry::RegisterMCRelocationInfo(TheX86_64Target,
diff --git a/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h b/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h
index 41ae435..6febed2 100644
--- a/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h
+++ b/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h
@@ -30,7 +30,7 @@ class Target;
class StringRef;
class raw_ostream;
-extern Target TheX86_32Target, TheX86_64Target;
+extern Target TheX86_16Target, TheX86_32Target, TheX86_64Target;
/// DWARFFlavour - Flavour of dwarf regnumbers
///
diff --git a/lib/Target/X86/TargetInfo/X86TargetInfo.cpp b/lib/Target/X86/TargetInfo/X86TargetInfo.cpp
index 815d235..4e89c25 100644
--- a/lib/Target/X86/TargetInfo/X86TargetInfo.cpp
+++ b/lib/Target/X86/TargetInfo/X86TargetInfo.cpp
@@ -12,9 +12,12 @@
#include "llvm/Support/TargetRegistry.h"
using namespace llvm;
-Target llvm::TheX86_32Target, llvm::TheX86_64Target;
+Target llvm::TheX86_16Target, llvm::TheX86_32Target, llvm::TheX86_64Target;
extern "C" void LLVMInitializeX86TargetInfo() {
+ RegisterTarget<Triple::x86_16, /*HasJIT=*/true>
+ W(TheX86_16Target, "x86-16", "16-bit X86: Pentium-Pro and above");
+
RegisterTarget<Triple::x86, /*HasJIT=*/true>
X(TheX86_32Target, "x86", "32-bit X86: Pentium-Pro and above");
diff --git a/lib/Target/X86/X86AsmPrinter.cpp b/lib/Target/X86/X86AsmPrinter.cpp
index 70f9e17..513b6de 100644
--- a/lib/Target/X86/X86AsmPrinter.cpp
+++ b/lib/Target/X86/X86AsmPrinter.cpp
@@ -718,6 +718,7 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
// Force static initialization.
extern "C" void LLVMInitializeX86AsmPrinter() {
+ RegisterAsmPrinter<X86AsmPrinter> W(TheX86_16Target);
RegisterAsmPrinter<X86AsmPrinter> X(TheX86_32Target);
RegisterAsmPrinter<X86AsmPrinter> Y(TheX86_64Target);
}
diff --git a/lib/Target/X86/X86Subtarget.cpp b/lib/Target/X86/X86Subtarget.cpp
index b183ed0..cc8935b 100644
--- a/lib/Target/X86/X86Subtarget.cpp
+++ b/lib/Target/X86/X86Subtarget.cpp
@@ -559,7 +559,7 @@ X86Subtarget::X86Subtarget(const std::string &TT, const std::string &CPU,
, StackAlignOverride(StackAlignOverride)
, In64BitMode(TargetTriple.getArch() == Triple::x86_64)
, In32BitMode(TargetTriple.getArch() == Triple::x86)
- , In16BitMode(false) {
+ , In16BitMode(TargetTriple.getArch() == Triple::x86_16) {
initializeEnvironment();
resetSubtargetFeatures(CPU, FS);
}
diff --git a/lib/Target/X86/X86TargetMachine.cpp b/lib/Target/X86/X86TargetMachine.cpp
index 462dae3..1a903b8 100644
--- a/lib/Target/X86/X86TargetMachine.cpp
+++ b/lib/Target/X86/X86TargetMachine.cpp
@@ -24,6 +24,7 @@ using namespace llvm;
extern "C" void LLVMInitializeX86Target() {
// Register the target.
+ RegisterTargetMachine<X86TargetMachine> W(TheX86_16Target);
RegisterTargetMachine<X86TargetMachine> X(TheX86_32Target);
RegisterTargetMachine<X86TargetMachine> Y(TheX86_64Target);
}
--
1.8.4.2
--
dwmw2
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 5745 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140108/9736ac1a/attachment.bin>
More information about the llvm-commits
mailing list