[RFC PATCH 3/8] [x86] First pass at adding .code16 support
David Woodhouse
dwmw2 at infradead.org
Fri Dec 13 15:31:48 PST 2013
---
lib/Target/X86/AsmParser/X86AsmParser.cpp | 41 +++++++++++++++++++-----
lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp | 12 ++++++-
lib/Target/X86/X86.td | 2 ++
lib/Target/X86/X86Subtarget.h | 9 +++++-
4 files changed, 54 insertions(+), 10 deletions(-)
diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp
index 15dcc5c..55f5b35 100644
--- a/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -544,10 +544,18 @@ private:
// FIXME: Can tablegen auto-generate this?
return (STI.getFeatureBits() & X86::Mode64Bit) != 0;
}
- void SwitchMode() {
+ bool is16BitMode() const {
+ // FIXME: Can tablegen auto-generate this?
+ return (STI.getFeatureBits() & X86::Mode16Bit) != 0;
+ }
+ void SwitchMode64() {
unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(X86::Mode64Bit));
setAvailableFeatures(FB);
}
+ void SwitchMode16() {
+ unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(X86::Mode16Bit));
+ setAvailableFeatures(FB);
+ }
bool isParsingIntelSyntax() {
return getParser().getAssemblerDialect();
@@ -1033,7 +1041,8 @@ struct X86Operand : public MCParsedAsmOperand {
} // end anonymous namespace.
bool X86AsmParser::isSrcOp(X86Operand &Op) {
- unsigned basereg = is64BitMode() ? X86::RSI : X86::ESI;
+ unsigned basereg = is64BitMode() ? X86::RSI :
+ (is16BitMode() ? X86::SI : X86::ESI);
return (Op.isMem() &&
(Op.Mem.SegReg == 0 || Op.Mem.SegReg == X86::DS) &&
@@ -1043,7 +1052,8 @@ bool X86AsmParser::isSrcOp(X86Operand &Op) {
}
bool X86AsmParser::isDstOp(X86Operand &Op) {
- unsigned basereg = is64BitMode() ? X86::RDI : X86::EDI;
+ unsigned basereg = is64BitMode() ? X86::RDI :
+ (is16BitMode() ? X86::SI : X86::EDI);
return Op.isMem() &&
(Op.Mem.SegReg == 0 || Op.Mem.SegReg == X86::ES) &&
@@ -1193,7 +1203,8 @@ X86AsmParser::CreateMemForInlineAsm(unsigned SegReg, const MCExpr *Disp,
// operand to ensure proper matching. Just pick a GPR based on the size of
// a pointer.
if (!Info.IsVarDecl) {
- unsigned RegNo = is64BitMode() ? X86::RBX : X86::EBX;
+ unsigned RegNo = is64BitMode() ? X86::RBX :
+ (is16BitMode() ? X86::BX : X86::EBX);
return X86Operand::CreateReg(RegNo, Start, End, /*AddressOf=*/true,
SMLoc(), Identifier, Info.OpDecl);
}
@@ -1587,7 +1598,8 @@ X86Operand *X86AsmParser::ParseIntelOffsetOfOperator() {
// The offset operator will have an 'r' constraint, thus we need to create
// register operand to ensure proper matching. Just pick a GPR based on
// the size of a pointer.
- unsigned RegNo = is64BitMode() ? X86::RBX : X86::EBX;
+ unsigned RegNo = is64BitMode() ? X86::RBX :
+ (is16BitMode() ? X86::BX : X86::EBX);
return X86Operand::CreateReg(RegNo, Start, End, /*GetAddress=*/true,
OffsetOfLoc, Identifier, Info.OpDecl);
}
@@ -2648,16 +2660,29 @@ bool X86AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
/// ParseDirectiveCode
/// ::= .code32 | .code64
bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
- if (IDVal == ".code32") {
+ if (IDVal == ".code16") {
+ Parser.Lex();
+ if (!is16BitMode()) {
+ if (is64BitMode())
+ SwitchMode64();
+ SwitchMode16();
+ getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
+ }
+ } else if (IDVal == ".code32") {
Parser.Lex();
if (is64BitMode()) {
- SwitchMode();
+ SwitchMode64();
+ getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
+ } else if (is16BitMode()) {
+ SwitchMode16();
getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
}
} else if (IDVal == ".code64") {
Parser.Lex();
if (!is64BitMode()) {
- SwitchMode();
+ if (is16BitMode())
+ SwitchMode16();
+ SwitchMode64();
getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64);
}
} else {
diff --git a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
index 3f7ed26..845cc8b 100644
--- a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
+++ b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
@@ -49,7 +49,13 @@ public:
bool is32BitMode() const {
// FIXME: Can tablegen auto-generate this?
- return (STI.getFeatureBits() & X86::Mode64Bit) == 0;
+ return (STI.getFeatureBits() & X86::Mode64Bit) == 0 &&
+ (STI.getFeatureBits() & X86::Mode16Bit) == 0;
+ }
+
+ bool is16BitMode() const {
+ // FIXME: Can tablegen auto-generate this?
+ return (STI.getFeatureBits() & X86::Mode16Bit) != 0;
}
unsigned GetX86RegNum(const MCOperand &MO) const {
@@ -1148,6 +1154,9 @@ void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
} else if (is64BitMode()) {
assert(!Is16BitMemOperand(MI, MemOperand));
need_address_override = Is32BitMemOperand(MI, MemOperand);
+ } else if (is16BitMode()) {
+ assert(!Is64BitMemOperand(MI, MemOperand));
+ need_address_override = !Is16BitMemOperand(MI, MemOperand);
} else if (is32BitMode()) {
assert(!Is64BitMemOperand(MI, MemOperand));
need_address_override = Is16BitMemOperand(MI, MemOperand);
@@ -1159,6 +1168,7 @@ void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
EmitByte(0x67, CurByte, OS);
// Emit the operand size opcode prefix as needed.
+ // FIXME for is16BitMode().
if (TSFlags & X86II::OpSize)
EmitByte(0x66, CurByte, OS);
diff --git a/lib/Target/X86/X86.td b/lib/Target/X86/X86.td
index d55178e..7ec9468 100644
--- a/lib/Target/X86/X86.td
+++ b/lib/Target/X86/X86.td
@@ -22,6 +22,8 @@ include "llvm/Target/Target.td"
def Mode64Bit : SubtargetFeature<"64bit-mode", "In64BitMode", "true",
"64-bit mode (x86_64)">;
+def Mode16Bit : SubtargetFeature<"16bit-mode", "In16BitMode", "true",
+ "16-bit mode (i8086)">;
//===----------------------------------------------------------------------===//
// X86 Subtarget features
diff --git a/lib/Target/X86/X86Subtarget.h b/lib/Target/X86/X86Subtarget.h
index 08dbf02..449df8f 100644
--- a/lib/Target/X86/X86Subtarget.h
+++ b/lib/Target/X86/X86Subtarget.h
@@ -205,9 +205,12 @@ private:
/// StackAlignOverride - Override the stack alignment.
unsigned StackAlignOverride;
- /// In64BitMode - True if compiling for 64-bit, false for 32-bit.
+ /// In64BitMode - True if compiling for 64-bit, false for 32-bit or 16-bit
bool In64BitMode;
+ /// In16BitMode - True if compiling for 16-bit, false for 32-bit or 64-bit
+ bool In16BitMode;
+
public:
/// This constructor initializes the data members to match that
/// of the specified triple.
@@ -244,6 +247,10 @@ public:
return In64BitMode;
}
+ bool is16Bit() const {
+ return In16BitMode;
+ }
+
/// Is this x86_64 with the ILP32 programming model (x32 ABI)?
bool isTarget64BitILP32() const {
return In64BitMode && (TargetTriple.getEnvironment() == Triple::GNUX32);
--
1.8.3.1
--
David Woodhouse Open Source Technology Centre
David.Woodhouse at intel.com Intel Corporation
-------------- 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/20131213/751a854b/attachment.bin>
More information about the llvm-commits
mailing list