<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0in;
margin-bottom:.0001pt;
font-size:12.0pt;
font-family:"Times New Roman",serif;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-priority:99;
color:purple;
text-decoration:underline;}
span.EmailStyle17
{mso-style-type:personal;
font-family:"Calibri",sans-serif;
color:#1F497D;}
span.EmailStyle18
{mso-style-type:personal-reply;
font-family:"Calibri",sans-serif;
color:#1F497D;}
.MsoChpDefault
{mso-style-type:export-only;
font-size:10.0pt;}
@page WordSection1
{size:8.5in 11.0in;
margin:1.0in 1.25in 1.0in 1.25in;}
div.WordSection1
{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">Committed a fix in revision 258312.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">Please let me know if you encounter additional issues.<o:p></o:p></span></p>
<p class="MsoNormal"><a name="_MailEndCompose"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"><o:p> </o:p></span></a></p>
<div>
<div style="border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><a name="_____replyseparator"></a><b><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">From:</span></b><span style="font-size:11.0pt;font-family:"Calibri",sans-serif"> Yatsina, Marina
<br>
<b>Sent:</b> Wednesday, January 20, 2016 14:19<br>
<b>To:</b> 'Diego Novillo'<br>
<b>Cc:</b> llvm-commits@lists.llvm.org<br>
<b>Subject:</b> RE: [llvm] r258132 - [X86] Adding support for missing variations of X86 string related instructions<o:p></o:p></span></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">There is indeed a bug in my code because there’s an overloading of the “movsd” and “cmpsd” instructions, e.g. movsd can be either “Move Data from String to String”
(the case I wanted to handle) or “Move or Merge Scalar Double-Precision Floating-Point Value” (the case that causes the unreachable).<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">Will have a fix soon.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">BTW, you were right to change the asserts to llvm_unreachanbles.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">Thanks,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">Marina<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><b><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">From:</span></b><span style="font-size:11.0pt;font-family:"Calibri",sans-serif"> Diego Novillo [</span><a href="mailto:dnovillo@google.com"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">mailto:dnovillo@google.com</span></a><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">]
<br>
<b>Sent:</b> Wednesday, January 20, 2016 03:56<br>
<b>To:</b> Yatsina, Marina<br>
<b>Cc:</b> </span><a href="mailto:llvm-commits@lists.llvm.org"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">llvm-commits@lists.llvm.org</span></a><span style="font-size:11.0pt;font-family:"Calibri",sans-serif"><br>
<b>Subject:</b> Re: [llvm] r258132 - [X86] Adding support for missing variations of X86 string related instructions<o:p></o:p></span></p>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<p class="MsoNormal">There seems to be something buggy with this patch. In our internal builds, we enable -Wstring-conversion. This picked up a couple of bad invocations of assert() in the patch:<o:p></o:p></p>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<div>
<p class="MsoNormal"> lib/Target/X86/AsmParser/X86AsmParser.cpp:1010:12: error: implicit conversion turns string literal into bool: 'const char [39]' to 'bool' [-Werror,-Wstring-conversion]<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"> lib/Target/X86/AsmParser/X86AsmParser.cpp:1027:12: error: implicit conversion turns string literal into bool: 'const char [26]' to 'bool' [-Werror,-Wstring-conversion]<o:p></o:p></p>
</div>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">I fixed them by turning the assertions into llvm_unreachable() calls:<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<div>
<p class="MsoNormal">- assert("Only (R|E)SI and (R|E)DI are expected!");<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">+ llvm_unreachable("Only (R|E)SI and (R|E)DI are expected!");<o:p></o:p></p>
</div>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<div>
<p class="MsoNormal">- assert("Unexpected register class");<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">+ llvm_unreachable("Unexpected register class");<o:p></o:p></p>
</div>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">It turns out, that we are hitting these assertions in a couple of tests which are now failing with my patch. I believe this points to a problem with the original patch (r258132). These tests are now failing:<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<div>
<p class="MsoNormal">Failing Tests (2):<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"> LLVM :: CodeGen/X86/pr3154.ll<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"> LLVM :: MC/X86/x86-32-coverage.s<o:p></o:p></p>
</div>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">They are both hitting the llvm_unreachable("Unexpected register class") at lib/Target/X86/AsmParser/X86AsmParser.cpp:1027<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Could you take a look or revert? Perhaps the intention was not to assert something else at that point?<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Thanks. Diego.<o:p></o:p></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<p class="MsoNormal">On Tue, Jan 19, 2016 at 7:37 AM, Marina Yatsina via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>> wrote:<o:p></o:p></p>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0in;margin-bottom:5.0pt">
<p class="MsoNormal">Author: myatsina<br>
Date: Tue Jan 19 09:37:56 2016<br>
New Revision: 258132<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=258132&view=rev" target="_blank">
http://llvm.org/viewvc/llvm-project?rev=258132&view=rev</a><br>
Log:<br>
[X86] Adding support for missing variations of X86 string related instructions<br>
<br>
The following are legal according to X86 spec:<br>
ins mem, DX<br>
outs DX, mem<br>
lods mem<br>
stos mem<br>
scas mem<br>
cmps mem, mem<br>
movs mem, mem<br>
<br>
Differential Revision: <a href="http://reviews.llvm.org/D14827" target="_blank">http://reviews.llvm.org/D14827</a><br>
<br>
<br>
Modified:<br>
llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp<br>
llvm/trunk/lib/Target/X86/X86InstrInfo.td<br>
llvm/trunk/test/MC/X86/index-operations.s<br>
llvm/trunk/test/MC/X86/intel-syntax.s<br>
<br>
Modified: llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp?rev=258132&r1=258131&r2=258132&view=diff" target="_blank">
http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp?rev=258132&r1=258131&r2=258132&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp (original)<br>
+++ llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp Tue Jan 19 09:37:56 2016<br>
@@ -683,9 +683,14 @@ private:<br>
<br>
std::unique_ptr<X86Operand> DefaultMemSIOperand(SMLoc Loc);<br>
std::unique_ptr<X86Operand> DefaultMemDIOperand(SMLoc Loc);<br>
- void AddDefaultSrcDestOperands(<br>
- OperandVector& Operands, std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,<br>
- std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst);<br>
+ bool IsSIReg(unsigned Reg);<br>
+ unsigned GetSIDIForRegClass(unsigned RegClassID, unsigned Reg, bool IsSIReg);<br>
+ void<br>
+ AddDefaultSrcDestOperands(OperandVector &Operands,<br>
+ std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,<br>
+ std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst);<br>
+ bool VerifyAndAdjustOperands(OperandVector &OrigOperands,<br>
+ OperandVector &FinalOperands);<br>
std::unique_ptr<X86Operand> ParseOperand();<br>
std::unique_ptr<X86Operand> ParseATTOperand();<br>
std::unique_ptr<X86Operand> ParseIntelOperand();<br>
@@ -747,11 +752,6 @@ private:<br>
<br>
bool OmitRegisterFromClobberLists(unsigned RegNo) override;<br>
<br>
- /// doSrcDstMatch - Returns true if operands are matching in their<br>
- /// word size (%si and %di, %esi and %edi, etc.). Order depends on<br>
- /// the parsing mode (Intel vs. AT&T).<br>
- bool doSrcDstMatch(X86Operand &Op1, X86Operand &Op2);<br>
-<br>
/// Parses AVX512 specific operand primitives: masked registers ({%k<NUM>}, {z})<br>
/// and memory broadcasting ({1to<NUM>}) primitives, updating Operands vector if required.<br>
/// \return \c true if no parsing errors occurred, \c false otherwise.<br>
@@ -867,27 +867,6 @@ static bool CheckBaseRegAndIndexReg(unsi<br>
return false;<br>
}<br>
<br>
-bool X86AsmParser::doSrcDstMatch(X86Operand &Op1, X86Operand &Op2)<br>
-{<br>
- // Return true and let a normal complaint about bogus operands happen.<br>
- if (!Op1.isMem() || !Op2.isMem())<br>
- return true;<br>
-<br>
- // Actually these might be the other way round if Intel syntax is<br>
- // being used. It doesn't matter.<br>
- unsigned diReg = Op1.Mem.BaseReg;<br>
- unsigned siReg = Op2.Mem.BaseReg;<br>
-<br>
- if (X86MCRegisterClasses[X86::GR16RegClassID].contains(siReg))<br>
- return X86MCRegisterClasses[X86::GR16RegClassID].contains(diReg);<br>
- if (X86MCRegisterClasses[X86::GR32RegClassID].contains(siReg))<br>
- return X86MCRegisterClasses[X86::GR32RegClassID].contains(diReg);<br>
- if (X86MCRegisterClasses[X86::GR64RegClassID].contains(siReg))<br>
- return X86MCRegisterClasses[X86::GR64RegClassID].contains(diReg);<br>
- // Again, return true and let another error happen.<br>
- return true;<br>
-}<br>
-<br>
bool X86AsmParser::ParseRegister(unsigned &RegNo,<br>
SMLoc &StartLoc, SMLoc &EndLoc) {<br>
MCAsmParser &Parser = getParser();<br>
@@ -1025,6 +1004,37 @@ std::unique_ptr<X86Operand> X86AsmParser<br>
Loc, Loc, 0);<br>
}<br>
<br>
+bool X86AsmParser::IsSIReg(unsigned Reg) {<br>
+ switch (Reg) {<br>
+ default:<br>
+ assert("Only (R|E)SI and (R|E)DI are expected!");<br>
+ return false;<br>
+ case X86::RSI:<br>
+ case X86::ESI:<br>
+ case X86::SI:<br>
+ return true;<br>
+ case X86::RDI:<br>
+ case X86::EDI:<br>
+ case X86::DI:<br>
+ return false;<br>
+ }<br>
+}<br>
+<br>
+unsigned X86AsmParser::GetSIDIForRegClass(unsigned RegClassID, unsigned Reg,<br>
+ bool IsSIReg) {<br>
+ switch (RegClassID) {<br>
+ default:<br>
+ assert("Unexpected register class");<br>
+ return Reg;<br>
+ case X86::GR64RegClassID:<br>
+ return IsSIReg ? X86::RSI : X86::RDI;<br>
+ case X86::GR32RegClassID:<br>
+ return IsSIReg ? X86::ESI : X86::EDI;<br>
+ case X86::GR16RegClassID:<br>
+ return IsSIReg ? X86::SI : X86::DI;<br>
+ }<br>
+}<br>
+<br>
void X86AsmParser::AddDefaultSrcDestOperands(<br>
OperandVector& Operands, std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,<br>
std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst) {<br>
@@ -1038,6 +1048,76 @@ void X86AsmParser::AddDefaultSrcDestOper<br>
}<br>
}<br>
<br>
+bool X86AsmParser::VerifyAndAdjustOperands(OperandVector &OrigOperands,<br>
+ OperandVector &FinalOperands) {<br>
+<br>
+ if (OrigOperands.size() > 1) {<br>
+ // Check if sizes match, OrigOpernads also contains the instruction name<br>
+ assert(OrigOperands.size() == FinalOperands.size() + 1 &&<br>
+ "Opernand size mismatch");<br>
+<br>
+ // Verify types match<br>
+ int RegClassID = -1;<br>
+ for (unsigned int i = 0; i < FinalOperands.size(); ++i) {<br>
+ X86Operand &OrigOp = static_cast<X86Operand &>(*OrigOperands[i + 1]);<br>
+ X86Operand &FinalOp = static_cast<X86Operand &>(*FinalOperands[i]);<br>
+<br>
+ if (FinalOp.isReg() &&<br>
+ (!OrigOp.isReg() || FinalOp.getReg() != OrigOp.getReg()))<br>
+ // Return false and let a normal complaint about bogus operands happen<br>
+ return false;<br>
+<br>
+ if (FinalOp.isMem()) {<br>
+<br>
+ if (!OrigOp.isMem())<br>
+ // Return false and let a normal complaint about bogus operands happen<br>
+ return false;<br>
+<br>
+ unsigned OrigReg = OrigOp.Mem.BaseReg;<br>
+ unsigned FinalReg = FinalOp.Mem.BaseReg;<br>
+<br>
+ // If we've already encounterd a register class, make sure all register<br>
+ // bases are of the same register class<br>
+ if (RegClassID != -1 &&<br>
+ !X86MCRegisterClasses[RegClassID].contains(OrigReg)) {<br>
+ return Error(OrigOp.getStartLoc(),<br>
+ "mismatching source and destination index registers");<br>
+ }<br>
+<br>
+ if (X86MCRegisterClasses[X86::GR64RegClassID].contains(OrigReg))<br>
+ RegClassID = X86::GR64RegClassID;<br>
+ else if (X86MCRegisterClasses[X86::GR32RegClassID].contains(OrigReg))<br>
+ RegClassID = X86::GR32RegClassID;<br>
+ else if (X86MCRegisterClasses[X86::GR16RegClassID].contains(OrigReg))<br>
+ RegClassID = X86::GR16RegClassID;<br>
+<br>
+ bool IsSI = IsSIReg(FinalReg);<br>
+ FinalReg = GetSIDIForRegClass(RegClassID, FinalReg, IsSI);<br>
+<br>
+ if (FinalReg != OrigReg) {<br>
+ std::string RegName = IsSI ? "ES:(R|E)SI" : "ES:(R|E)DI";<br>
+ Warning(OrigOp.getStartLoc(),<br>
+ "memory operand is only for determining the size, " +<br>
+ RegName + " will be used for the location");<br>
+ }<br>
+<br>
+ FinalOp.Mem.Size = OrigOp.Mem.Size;<br>
+ FinalOp.Mem.SegReg = OrigOp.Mem.SegReg;<br>
+ FinalOp.Mem.BaseReg = FinalReg;<br>
+ }<br>
+ }<br>
+<br>
+ // Remove old operandss<br>
+ for (unsigned int i = 0; i < FinalOperands.size(); ++i)<br>
+ OrigOperands.pop_back();<br>
+ }<br>
+ // OrigOperands.append(FinalOperands.begin(), FinalOperands.end());<br>
+ for (unsigned int i = 0; i < FinalOperands.size(); ++i)<br>
+ OrigOperands.push_back(std::move(FinalOperands[i]));<br>
+<br>
+ return false;<br>
+}<br>
+<br>
std::unique_ptr<X86Operand> X86AsmParser::ParseOperand() {<br>
if (isParsingIntelSyntax())<br>
return ParseIntelOperand();<br>
@@ -2274,84 +2354,92 @@ bool X86AsmParser::ParseInstruction(Pars<br>
}<br>
}<br>
<br>
+ SmallVector<std::unique_ptr<MCParsedAsmOperand>, 2> TmpOperands;<br>
+ bool HadVerifyError = false;<br>
+<br>
// Append default arguments to "ins[bwld]"<br>
- if (Name.startswith("ins") && Operands.size() == 1 &&<br>
- (Name == "insb" || Name == "insw" || Name == "insl" || Name == "insd")) {<br>
- AddDefaultSrcDestOperands(Operands,<br>
+ if (Name.startswith("ins") &&<br>
+ (Operands.size() == 1 || Operands.size() == 3) &&<br>
+ (Name == "insb" || Name == "insw" || Name == "insl" || Name == "insd" ||<br>
+ Name == "ins")) {<br>
+<br>
+ AddDefaultSrcDestOperands(TmpOperands,<br>
X86Operand::CreateReg(X86::DX, NameLoc, NameLoc),<br>
DefaultMemDIOperand(NameLoc));<br>
+ HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);<br>
}<br>
<br>
// Append default arguments to "outs[bwld]"<br>
- if (Name.startswith("outs") && Operands.size() == 1 &&<br>
+ if (Name.startswith("outs") &&<br>
+ (Operands.size() == 1 || Operands.size() == 3) &&<br>
(Name == "outsb" || Name == "outsw" || Name == "outsl" ||<br>
- Name == "outsd" )) {<br>
- AddDefaultSrcDestOperands(Operands,<br>
- DefaultMemSIOperand(NameLoc),<br>
+ Name == "outsd" || Name == "outs")) {<br>
+ AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),<br>
X86Operand::CreateReg(X86::DX, NameLoc, NameLoc));<br>
+ HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);<br>
}<br>
<br>
// Transform "lods[bwlq]" into "lods[bwlq] ($SIREG)" for appropriate<br>
// values of $SIREG according to the mode. It would be nice if this<br>
// could be achieved with InstAlias in the tables.<br>
- if (Name.startswith("lods") && Operands.size() == 1 &&<br>
+ if (Name.startswith("lods") &&<br>
+ (Operands.size() == 1 || Operands.size() == 2) &&<br>
(Name == "lods" || Name == "lodsb" || Name == "lodsw" ||<br>
- Name == "lodsl" || Name == "lodsd" || Name == "lodsq"))<br>
- Operands.push_back(DefaultMemSIOperand(NameLoc));<br>
+ Name == "lodsl" || Name == "lodsd" || Name == "lodsq")) {<br>
+ TmpOperands.push_back(DefaultMemSIOperand(NameLoc));<br>
+ HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);<br>
+ }<br>
<br>
// Transform "stos[bwlq]" into "stos[bwlq] ($DIREG)" for appropriate<br>
// values of $DIREG according to the mode. It would be nice if this<br>
// could be achieved with InstAlias in the tables.<br>
- if (Name.startswith("stos") && Operands.size() == 1 &&<br>
+ if (Name.startswith("stos") &&<br>
+ (Operands.size() == 1 || Operands.size() == 2) &&<br>
(Name == "stos" || Name == "stosb" || Name == "stosw" ||<br>
- Name == "stosl" || Name == "stosd" || Name == "stosq"))<br>
- Operands.push_back(DefaultMemDIOperand(NameLoc));<br>
+ Name == "stosl" || Name == "stosd" || Name == "stosq")) {<br>
+ TmpOperands.push_back(DefaultMemDIOperand(NameLoc));<br>
+ HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);<br>
+ }<br>
<br>
// Transform "scas[bwlq]" into "scas[bwlq] ($DIREG)" for appropriate<br>
// values of $DIREG according to the mode. It would be nice if this<br>
// could be achieved with InstAlias in the tables.<br>
- if (Name.startswith("scas") && Operands.size() == 1 &&<br>
+ if (Name.startswith("scas") &&<br>
+ (Operands.size() == 1 || Operands.size() == 2) &&<br>
(Name == "scas" || Name == "scasb" || Name == "scasw" ||<br>
- Name == "scasl" || Name == "scasd" || Name == "scasq"))<br>
- Operands.push_back(DefaultMemDIOperand(NameLoc));<br>
+ Name == "scasl" || Name == "scasd" || Name == "scasq")) {<br>
+ TmpOperands.push_back(DefaultMemDIOperand(NameLoc));<br>
+ HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);<br>
+ }<br>
<br>
// Add default SI and DI operands to "cmps[bwlq]".<br>
if (Name.startswith("cmps") &&<br>
+ (Operands.size() == 1 || Operands.size() == 3) &&<br>
(Name == "cmps" || Name == "cmpsb" || Name == "cmpsw" ||<br>
Name == "cmpsl" || Name == "cmpsd" || Name == "cmpsq")) {<br>
- if (Operands.size() == 1) {<br>
- AddDefaultSrcDestOperands(Operands,<br>
- DefaultMemDIOperand(NameLoc),<br>
- DefaultMemSIOperand(NameLoc));<br>
- } else if (Operands.size() == 3) {<br>
- X86Operand &Op = (X86Operand &)*Operands[1];<br>
- X86Operand &Op2 = (X86Operand &)*Operands[2];<br>
- if (!doSrcDstMatch(Op, Op2))<br>
- return Error(Op.getStartLoc(),<br>
- "mismatching source and destination index registers");<br>
- }<br>
+ AddDefaultSrcDestOperands(TmpOperands, DefaultMemDIOperand(NameLoc),<br>
+ DefaultMemSIOperand(NameLoc));<br>
+ HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);<br>
}<br>
<br>
// Add default SI and DI operands to "movs[bwlq]".<br>
- if ((Name.startswith("movs") &&<br>
- (Name == "movs" || Name == "movsb" || Name == "movsw" ||<br>
- Name == "movsl" || Name == "movsd" || Name == "movsq")) ||<br>
- (Name.startswith("smov") &&<br>
- (Name == "smov" || Name == "smovb" || Name == "smovw" ||<br>
- Name == "smovl" || Name == "smovd" || Name == "smovq"))) {<br>
- if (Operands.size() == 1) {<br>
- if (Name == "movsd")<br>
- Operands.back() = X86Operand::CreateToken("movsl", NameLoc);<br>
- AddDefaultSrcDestOperands(Operands,<br>
- DefaultMemSIOperand(NameLoc),<br>
- DefaultMemDIOperand(NameLoc));<br>
- } else if (Operands.size() == 3) {<br>
- X86Operand &Op = (X86Operand &)*Operands[1];<br>
- X86Operand &Op2 = (X86Operand &)*Operands[2];<br>
- if (!doSrcDstMatch(Op, Op2))<br>
- return Error(Op.getStartLoc(),<br>
- "mismatching source and destination index registers");<br>
- }<br>
+ if (((Name.startswith("movs") &&<br>
+ (Name == "movs" || Name == "movsb" || Name == "movsw" ||<br>
+ Name == "movsl" || Name == "movsd" || Name == "movsq")) ||<br>
+ (Name.startswith("smov") &&<br>
+ (Name == "smov" || Name == "smovb" || Name == "smovw" ||<br>
+ Name == "smovl" || Name == "smovd" || Name == "smovq"))) &&<br>
+ (Operands.size() == 1 || Operands.size() == 3)) {<br>
+ if (Name == "movsd" && Operands.size() == 1)<br>
+ Operands.back() = X86Operand::CreateToken("movsl", NameLoc);<br>
+ AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),<br>
+ DefaultMemDIOperand(NameLoc));<br>
+ HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);<br>
+ }<br>
+<br>
+ // Check if we encountered an error for one the string insturctions<br>
+ if (HadVerifyError) {<br>
+ return HadVerifyError;<br>
}<br>
<br>
// FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>. Canonicalize to<br>
<br>
Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=258132&r1=258131&r2=258132&view=diff" target="_blank">
http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=258132&r1=258131&r2=258132&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original)<br>
+++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Tue Jan 19 09:37:56 2016<br>
@@ -2782,6 +2782,11 @@ def : InstAlias<"lods\t{$src, %al|al, $s<br>
def : InstAlias<"lods\t{$src, %ax|ax, $src}", (LODSW srcidx16:$src), 0>;<br>
def : InstAlias<"lods\t{$src, %eax|eax, $src}", (LODSL srcidx32:$src), 0>;<br>
def : InstAlias<"lods\t{$src, %rax|rax, $src}", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;<br>
+def : InstAlias<"lods\t$src", (LODSB srcidx8:$src), 0>;<br>
+def : InstAlias<"lods\t$src", (LODSW srcidx16:$src), 0>;<br>
+def : InstAlias<"lods\t$src", (LODSL srcidx32:$src), 0>;<br>
+def : InstAlias<"lods\t$src", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;<br>
+<br>
<br>
// stos aliases. Accept the source being omitted because it's implicit in<br>
// the mnemonic, or the mnemonic suffix being omitted because it's implicit<br>
@@ -2794,6 +2799,11 @@ def : InstAlias<"stos\t{%al, $dst|$dst,<br>
def : InstAlias<"stos\t{%ax, $dst|$dst, ax}", (STOSW dstidx16:$dst), 0>;<br>
def : InstAlias<"stos\t{%eax, $dst|$dst, eax}", (STOSL dstidx32:$dst), 0>;<br>
def : InstAlias<"stos\t{%rax, $dst|$dst, rax}", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;<br>
+def : InstAlias<"stos\t$dst", (STOSB dstidx8:$dst), 0>;<br>
+def : InstAlias<"stos\t$dst", (STOSW dstidx16:$dst), 0>;<br>
+def : InstAlias<"stos\t$dst", (STOSL dstidx32:$dst), 0>;<br>
+def : InstAlias<"stos\t$dst", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;<br>
+<br>
<br>
// scas aliases. Accept the destination being omitted because it's implicit<br>
// in the mnemonic, or the mnemonic suffix being omitted because it's implicit<br>
@@ -2806,6 +2816,24 @@ def : InstAlias<"scas\t{$dst, %al|al, $d<br>
def : InstAlias<"scas\t{$dst, %ax|ax, $dst}", (SCASW dstidx16:$dst), 0>;<br>
def : InstAlias<"scas\t{$dst, %eax|eax, $dst}", (SCASL dstidx32:$dst), 0>;<br>
def : InstAlias<"scas\t{$dst, %rax|rax, $dst}", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;<br>
+def : InstAlias<"scas\t$dst", (SCASB dstidx8:$dst), 0>;<br>
+def : InstAlias<"scas\t$dst", (SCASW dstidx16:$dst), 0>;<br>
+def : InstAlias<"scas\t$dst", (SCASL dstidx32:$dst), 0>;<br>
+def : InstAlias<"scas\t$dst", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;<br>
+<br>
+// cmps aliases. Mnemonic suffix being omitted because it's implicit<br>
+// in the destination.<br>
+def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSB dstidx8:$dst, srcidx8:$src), 0>;<br>
+def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSW dstidx16:$dst, srcidx16:$src), 0>;<br>
+def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSL dstidx32:$dst, srcidx32:$src), 0>;<br>
+def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSQ dstidx64:$dst, srcidx64:$src), 0>, Requires<[In64BitMode]>;<br>
+<br>
+// movs aliases. Mnemonic suffix being omitted because it's implicit<br>
+// in the destination.<br>
+def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSB dstidx8:$dst, srcidx8:$src), 0>;<br>
+def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSW dstidx16:$dst, srcidx16:$src), 0>;<br>
+def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSL dstidx32:$dst, srcidx32:$src), 0>;<br>
+def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSQ dstidx64:$dst, srcidx64:$src), 0>, Requires<[In64BitMode]>;<br>
<br>
// div and idiv aliases for explicit A register.<br>
def : InstAlias<"div{b}\t{$src, %al|al, $src}", (DIV8r GR8 :$src)>;<br>
@@ -2918,6 +2946,18 @@ def : InstAlias<"imul{l}\t{$imm, $r|$r,<br>
def : InstAlias<"imul{q}\t{$imm, $r|$r, $imm}", (IMUL64rri32 GR64:$r, GR64:$r, i64i32imm:$imm), 0>;<br>
def : InstAlias<"imul{q}\t{$imm, $r|$r, $imm}", (IMUL64rri8 GR64:$r, GR64:$r, i64i8imm:$imm), 0>;<br>
<br>
+// ins aliases. Accept the mnemonic suffix being omitted because it's implicit<br>
+// in the destination.<br>
+def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSB dstidx8:$dst), 0>;<br>
+def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSW dstidx16:$dst), 0>;<br>
+def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSL dstidx32:$dst), 0>;<br>
+<br>
+// outs aliases. Accept the mnemonic suffix being omitted because it's implicit<br>
+// in the source.<br>
+def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSB srcidx8:$src), 0>;<br>
+def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSW srcidx16:$src), 0>;<br>
+def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSL srcidx32:$src), 0>;<br>
+<br>
// inb %dx -> inb %al, %dx<br>
def : InstAlias<"inb\t{%dx|dx}", (IN8rr), 0>;<br>
def : InstAlias<"inw\t{%dx|dx}", (IN16rr), 0>;<br>
<br>
Modified: llvm/trunk/test/MC/X86/index-operations.s<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/X86/index-operations.s?rev=258132&r1=258131&r2=258132&view=diff" target="_blank">
http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/X86/index-operations.s?rev=258132&r1=258131&r2=258132&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/MC/X86/index-operations.s (original)<br>
+++ llvm/trunk/test/MC/X86/index-operations.s Tue Jan 19 09:37:56 2016<br>
@@ -144,3 +144,19 @@ insw %dx, (%edi)<br>
// 64: insw %dx, %es:(%edi) # encoding: [0x66,0x67,0x6d]<br>
// 32: insw %dx, %es:(%edi) # encoding: [0x66,0x6d]<br>
// 16: insw %dx, %es:(%edi) # encoding: [0x67,0x6d]<br>
+<br>
+insw %dx, (%bx)<br>
+// ERR64: invalid 16-bit base register<br>
+// 32: insw %dx, %es:(%di) # encoding: [0x66,0x67,0x6d]<br>
+// 16: insw %dx, %es:(%di) # encoding: [0x6d]<br>
+<br>
+insw %dx, (%ebx)<br>
+// 64: insw %dx, %es:(%edi) # encoding: [0x66,0x67,0x6d]<br>
+// 32: insw %dx, %es:(%edi) # encoding: [0x66,0x6d]<br>
+// 16: insw %dx, %es:(%edi) # encoding: [0x67,0x6d]<br>
+<br>
+insw %dx, (%rbx)<br>
+// 64: insw %dx, %es:(%rdi) # encoding: [0x66,0x6d]<br>
+// ERR32: 64-bit<br>
+// ERR16: 64-bit<br>
+<br>
<br>
Modified: llvm/trunk/test/MC/X86/intel-syntax.s<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/X86/intel-syntax.s?rev=258132&r1=258131&r2=258132&view=diff" target="_blank">
http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/X86/intel-syntax.s?rev=258132&r1=258131&r2=258132&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/MC/X86/intel-syntax.s (original)<br>
+++ llvm/trunk/test/MC/X86/intel-syntax.s Tue Jan 19 09:37:56 2016<br>
@@ -751,3 +751,27 @@ loopnz _foo<br>
<br>
sidt fword ptr [eax]<br>
// CHECK: sidtq (%eax)<br>
+<br>
+ins byte ptr [eax], dx<br>
+// CHECK: insb %dx, %es:(%edi)<br>
+// CHECK-STDERR: memory operand is only for determining the size, ES:(R|E)DI will be used for the location<br>
+outs dx, word ptr [eax]<br>
+// CHECK: outsw (%esi), %dx<br>
+// CHECK-STDERR: memory operand is only for determining the size, ES:(R|E)SI will be used for the location<br>
+lods dword ptr [eax]<br>
+// CHECK: lodsl (%esi), %eax<br>
+// CHECK-STDERR: memory operand is only for determining the size, ES:(R|E)SI will be used for the location<br>
+stos qword ptr [eax]<br>
+// CHECK: stosq %rax, %es:(%edi)<br>
+// CHECK-STDERR: memory operand is only for determining the size, ES:(R|E)DI will be used for the location<br>
+scas byte ptr [eax]<br>
+// CHECK: scasb %es:(%edi), %al<br>
+// CHECK-STDERR: memory operand is only for determining the size, ES:(R|E)DI will be used for the location<br>
+cmps word ptr [eax], word ptr [ebx]<br>
+// CHECK: cmpsw %es:(%edi), (%esi)<br>
+// CHECK-STDERR: memory operand is only for determining the size, ES:(R|E)SI will be used for the location<br>
+// CHECK-STDERR: memory operand is only for determining the size, ES:(R|E)DI will be used for the location<br>
+movs dword ptr [eax], dword ptr [ebx]<br>
+// CHECK: movsl (%esi), %es:(%edi)<br>
+// CHECK-STDERR: memory operand is only for determining the size, ES:(R|E)DI will be used for the location<br>
+// CHECK-STDERR: memory operand is only for determining the size, ES:(R|E)SI will be used for the location<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><o:p></o:p></p>
</blockquote>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</div>
<p>---------------------------------------------------------------------<br>
Intel Israel (74) Limited</p>
<p>This e-mail and any attachments may contain confidential material for<br>
the sole use of the intended recipient(s). Any review or distribution<br>
by others is strictly prohibited. If you are not the intended<br>
recipient, please contact the sender and delete all copies.</p></body>
</html>