<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head><body ><div>I did it that way first. Someone, probably Jörg, got me to change it to be this way instead.</div><div><br></div><div><br></div>-- <div>dwmw2<div>(Apologies for HTML and top-posting; Android mailer is broken.)</div></div><br><br>-------- Original message --------<br>From: Craig Topper <craig.topper@gmail.com> <br>Date:05/01/2014  13:32  (GMT+00:00) <br>To: David Woodhouse <dwmw2@infradead.org> <br>Cc: llvm-commits@cs.uiuc.edu <br>Subject: Re: [PATCH v2 02/14] [x86] Add basic support for .code16 <br><br><div dir="ltr">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?<div><br></div><div>I believe AssemblerPredicate takes a comma separated list of feature names with negations.</div>
</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Dec 18, 2013 at 12:08 PM, David Woodhouse <span dir="ltr"><<a href="mailto:dwmw2@infradead.org" target="_blank">dwmw2@infradead.org</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
---<br>
 lib/Target/X86/AsmParser/X86AsmParser.cpp        | 41 +++++++++++++++++++-----<br>
 lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp | 12 ++++++-<br>
 lib/Target/X86/X86.td                            |  2 ++<br>
 lib/Target/X86/X86Subtarget.h                    |  9 +++++-<br>
 4 files changed, 54 insertions(+), 10 deletions(-)<br>
<br>
diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp<br>
index 15dcc5c..3f5b266 100644<br>
--- a/lib/Target/X86/AsmParser/X86AsmParser.cpp<br>
+++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp<br>
@@ -544,10 +544,18 @@ private:<br>
     // FIXME: Can tablegen auto-generate this?<br>
     return (STI.getFeatureBits() & X86::Mode64Bit) != 0;<br>
   }<br>
-  void SwitchMode() {<br>
+  bool is16BitMode() const {<br>
+    // FIXME: Can tablegen auto-generate this?<br>
+    return (STI.getFeatureBits() & X86::Mode16Bit) != 0;<br>
+  }<br>
+  void SwitchMode64() {<br>
     unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(X86::Mode64Bit));<br>
     setAvailableFeatures(FB);<br>
   }<br>
+  void SwitchMode16() {<br>
+    unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(X86::Mode16Bit));<br>
+    setAvailableFeatures(FB);<br>
+  }<br>
<br>
   bool isParsingIntelSyntax() {<br>
     return getParser().getAssemblerDialect();<br>
@@ -1033,7 +1041,8 @@ struct X86Operand : public MCParsedAsmOperand {<br>
 } // end anonymous namespace.<br>
<br>
 bool X86AsmParser::isSrcOp(X86Operand &Op) {<br>
-  unsigned basereg = is64BitMode() ? X86::RSI : X86::ESI;<br>
+  unsigned basereg = is64BitMode() ? X86::RSI :<br>
+    (is16BitMode() ? X86::SI : X86::ESI);<br>
<br>
   return (Op.isMem() &&<br>
     (Op.Mem.SegReg == 0 || Op.Mem.SegReg == X86::DS) &&<br>
@@ -1043,7 +1052,8 @@ bool X86AsmParser::isSrcOp(X86Operand &Op) {<br>
 }<br>
<br>
 bool X86AsmParser::isDstOp(X86Operand &Op) {<br>
-  unsigned basereg = is64BitMode() ? X86::RDI : X86::EDI;<br>
+  unsigned basereg = is64BitMode() ? X86::RDI :<br>
+    (is16BitMode() ? X86::DI : X86::EDI);<br>
<br>
   return Op.isMem() &&<br>
     (Op.Mem.SegReg == 0 || Op.Mem.SegReg == X86::ES) &&<br>
@@ -1193,7 +1203,8 @@ X86AsmParser::CreateMemForInlineAsm(unsigned SegReg, const MCExpr *Disp,<br>
     // operand to ensure proper matching.  Just pick a GPR based on the size of<br>
     // a pointer.<br>
     if (!Info.IsVarDecl) {<br>
-      unsigned RegNo = is64BitMode() ? X86::RBX : X86::EBX;<br>
+           unsigned RegNo = is64BitMode() ? X86::RBX :<br>
+              (is16BitMode() ? X86::BX : X86::EBX);<br>
       return X86Operand::CreateReg(RegNo, Start, End, /*AddressOf=*/true,<br>
                                    SMLoc(), Identifier, Info.OpDecl);<br>
     }<br>
@@ -1587,7 +1598,8 @@ X86Operand *X86AsmParser::ParseIntelOffsetOfOperator() {<br>
   // The offset operator will have an 'r' constraint, thus we need to create<br>
   // register operand to ensure proper matching.  Just pick a GPR based on<br>
   // the size of a pointer.<br>
-  unsigned RegNo = is64BitMode() ? X86::RBX : X86::EBX;<br>
+  unsigned RegNo = is64BitMode() ? X86::RBX :<br>
+    (is16BitMode() ? X86::BX : X86::EBX);<br>
   return X86Operand::CreateReg(RegNo, Start, End, /*GetAddress=*/true,<br>
                                OffsetOfLoc, Identifier, Info.OpDecl);<br>
 }<br>
@@ -2648,16 +2660,29 @@ bool X86AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {<br>
 /// ParseDirectiveCode<br>
 ///  ::= .code32 | .code64<br>
 bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {<br>
-  if (IDVal == ".code32") {<br>
+  if (IDVal == ".code16") {<br>
+    Parser.Lex();<br>
+    if (!is16BitMode()) {<br>
+      if (is64BitMode())<br>
+        SwitchMode64();<br>
+      SwitchMode16();<br>
+      getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);<br>
+    }<br>
+   } else  if (IDVal == ".code32") {<br>
     Parser.Lex();<br>
     if (is64BitMode()) {<br>
-      SwitchMode();<br>
+      SwitchMode64();<br>
+      getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);<br>
+    } else if (is16BitMode()) {<br>
+      SwitchMode16();<br>
       getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);<br>
     }<br>
   } else if (IDVal == ".code64") {<br>
     Parser.Lex();<br>
     if (!is64BitMode()) {<br>
-      SwitchMode();<br>
+      if (is16BitMode())<br>
+        SwitchMode16();<br>
+      SwitchMode64();<br>
       getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64);<br>
     }<br>
   } else {<br>
diff --git a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp<br>
index 7a8e71d..1ce876b 100644<br>
--- a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp<br>
+++ b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp<br>
@@ -49,7 +49,13 @@ public:<br>
<br>
   bool is32BitMode() const {<br>
     // FIXME: Can tablegen auto-generate this?<br>
-    return (STI.getFeatureBits() & X86::Mode64Bit) == 0;<br>
+    return (STI.getFeatureBits() & X86::Mode64Bit) == 0 &&<br>
+           (STI.getFeatureBits() & X86::Mode16Bit) == 0;<br>
+  }<br>
+<br>
+  bool is16BitMode() const {<br>
+    // FIXME: Can tablegen auto-generate this?<br>
+    return (STI.getFeatureBits() & X86::Mode16Bit) != 0;<br>
   }<br>
<br>
   unsigned GetX86RegNum(const MCOperand &MO) const {<br>
@@ -1146,6 +1152,9 @@ void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,<br>
   } else if (is64BitMode()) {<br>
     assert(!Is16BitMemOperand(MI, MemOperand));<br>
     need_address_override = Is32BitMemOperand(MI, MemOperand);<br>
+  } else if (is16BitMode()) {<br>
+    assert(!Is64BitMemOperand(MI, MemOperand));<br>
+    need_address_override = !Is16BitMemOperand(MI, MemOperand);<br>
   } else if (is32BitMode()) {<br>
     assert(!Is64BitMemOperand(MI, MemOperand));<br>
     need_address_override = Is16BitMemOperand(MI, MemOperand);<br>
@@ -1157,6 +1166,7 @@ void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,<br>
     EmitByte(0x67, CurByte, OS);<br>
<br>
   // Emit the operand size opcode prefix as needed.<br>
+  // FIXME for is16BitMode().<br>
   if (TSFlags & X86II::OpSize)<br>
     EmitByte(0x66, CurByte, OS);<br>
<br>
diff --git a/lib/Target/X86/X86.td b/lib/Target/X86/X86.td<br>
index d55178e..7ec9468 100644<br>
--- a/lib/Target/X86/X86.td<br>
+++ b/lib/Target/X86/X86.td<br>
@@ -22,6 +22,8 @@ include "llvm/Target/Target.td"<br>
<br>
 def Mode64Bit : SubtargetFeature<"64bit-mode", "In64BitMode", "true",<br>
                                   "64-bit mode (x86_64)">;<br>
+def Mode16Bit : SubtargetFeature<"16bit-mode", "In16BitMode", "true",<br>
+                                  "16-bit mode (i8086)">;<br>
<br>
 //===----------------------------------------------------------------------===//<br>
 // X86 Subtarget features<br>
diff --git a/lib/Target/X86/X86Subtarget.h b/lib/Target/X86/X86Subtarget.h<br>
index 08dbf02..449df8f 100644<br>
--- a/lib/Target/X86/X86Subtarget.h<br>
+++ b/lib/Target/X86/X86Subtarget.h<br>
@@ -205,9 +205,12 @@ private:<br>
   /// StackAlignOverride - Override the stack alignment.<br>
   unsigned StackAlignOverride;<br>
<br>
-  /// In64BitMode - True if compiling for 64-bit, false for 32-bit.<br>
+  /// In64BitMode - True if compiling for 64-bit, false for 32-bit or 16-bit<br>
   bool In64BitMode;<br>
<br>
+  /// In16BitMode - True if compiling for 16-bit, false for 32-bit or 64-bit<br>
+  bool In16BitMode;<br>
+<br>
 public:<br>
   /// This constructor initializes the data members to match that<br>
   /// of the specified triple.<br>
@@ -244,6 +247,10 @@ public:<br>
     return In64BitMode;<br>
   }<br>
<br>
+  bool is16Bit() const {<br>
+    return In16BitMode;<br>
+  }<br>
+<br>
   /// Is this x86_64 with the ILP32 programming model (x32 ABI)?<br>
   bool isTarget64BitILP32() const {<br>
     return In64BitMode && (TargetTriple.getEnvironment() == Triple::GNUX32);<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.8.3.1<br>
<br>
<br>
--<br>
David Woodhouse                            Open Source Technology Centre<br>
<a href="mailto:David.Woodhouse@intel.com">David.Woodhouse@intel.com</a>                              Intel Corporation<br>
</font></span><br>_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
<br></blockquote></div><br><br clear="all"><div><br></div>-- <br>~Craig
</div>
</body>