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