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

David Woodhouse dwmw2 at infradead.org
Sun Jan 5 06:05:03 PST 2014


I did it that way first. Someone, probably Jörg, got me to change it to be this way instead.


-- 
dwmw2
(Apologies for HTML and top-posting; Android mailer is broken.)

-------- Original message --------
From: Craig Topper <craig.topper at gmail.com> 
Date:05/01/2014  13:32  (GMT+00:00) 
To: David Woodhouse <dwmw2 at infradead.org> 
Cc: llvm-commits at cs.uiuc.edu 
Subject: Re: [PATCH v2 02/14] [x86] Add basic support for .code16 

Is it possible to do this with only one new feature bit. Can we just have Mode16Bit and Mode64Bit with Mode32 implied if the others aren't set?

I believe AssemblerPredicate takes a comma separated list of feature names with negations.


On Wed, Dec 18, 2013 at 12:08 PM, David Woodhouse <dwmw2 at infradead.org> wrote:

---
 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

_______________________________________________
llvm-commits mailing list
llvm-commits at cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




-- 
~Craig
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140105/f3b2a6c7/attachment.html>


More information about the llvm-commits mailing list