[PATCH v2 02/14] [x86] Add basic support for .code16

David Woodhouse dwmw2 at infradead.org
Wed Dec 18 10:08:02 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..3f5b266 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::DI : 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 7a8e71d..1ce876b 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 {
@@ -1146,6 +1152,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);
@@ -1157,6 +1166,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/20131218/60cdfdfe/attachment.bin>


More information about the llvm-commits mailing list