diff options
author | Chad Rosier <mcrosier@apple.com> | 2012-10-19 20:57:14 +0000 |
---|---|---|
committer | Chad Rosier <mcrosier@apple.com> | 2012-10-19 20:57:14 +0000 |
commit | 96d58e64cfe88356f8be4ce622b829fbd9fb5908 (patch) | |
tree | aa5883e266315318a6b7835bbd46cb0652797d13 /lib/MC/MCParser/AsmParser.cpp | |
parent | e2b95ebfb031c3defc75417521e89ef289a94171 (diff) |
[ms-inline asm] Have the TargetParser callback to Sema to determine the size of
a memory operand. Retain this information and then add the sizing directives
to the IR. This allows the backend to do proper instruction selection.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@166316 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC/MCParser/AsmParser.cpp')
-rw-r--r-- | lib/MC/MCParser/AsmParser.cpp | 46 |
1 files changed, 35 insertions, 11 deletions
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index 1573799433..6669780c7d 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -3577,17 +3577,18 @@ namespace { enum AsmOpRewriteKind { AOK_Imm, AOK_Input, - AOK_Output + AOK_Output, + AOK_SizeDirective }; struct AsmOpRewrite { AsmOpRewriteKind Kind; SMLoc Loc; unsigned Len; - + unsigned Size; public: - AsmOpRewrite(AsmOpRewriteKind kind, SMLoc loc, unsigned len) - : Kind(kind), Loc(loc), Len(len) { } + AsmOpRewrite(AsmOpRewriteKind kind, SMLoc loc, unsigned len, unsigned size = 0) + : Kind(kind), Loc(loc), Len(len), Size(size) { } }; } @@ -3650,6 +3651,11 @@ bool AsmParser::ParseMSInlineAsm(void *AsmLoc, std::string &AsmString, Size); if (OpDecl) { bool isOutput = (i == 1) && Desc.mayStore(); + if (Operand->needSizeDirective()) + AsmStrRewrites.push_back(AsmOpRewrite(AOK_SizeDirective, + Operand->getStartLoc(), 0, + Operand->getMemSize())); + if (isOutput) { std::string Constraint = "="; ++InputIdx; @@ -3701,17 +3707,23 @@ bool AsmParser::ParseMSInlineAsm(void *AsmLoc, std::string &AsmString, // Build the IR assembly string. std::string AsmStringIR; + AsmOpRewriteKind PrevKind = AOK_Imm; raw_string_ostream OS(AsmStringIR); const char *Start = SrcMgr.getMemoryBuffer(0)->getBufferStart(); for (SmallVectorImpl<struct AsmOpRewrite>::iterator I = AsmStrRewrites.begin(), E = AsmStrRewrites.end(); I != E; ++I) { const char *Loc = (*I).Loc.getPointer(); - - // Emit everything up to the immediate/expression. - OS << StringRef(Start, Loc - Start); - + + AsmOpRewriteKind Kind = (*I).Kind; + + // Emit everything up to the immediate/expression. If the previous rewrite + // was a size directive, then this has already been done. + if (PrevKind != AOK_SizeDirective) + OS << StringRef(Start, Loc - Start); + PrevKind = Kind; + // Rewrite expressions in $N notation. - switch ((*I).Kind) { + switch (Kind) { case AOK_Imm: OS << Twine("$$") + StringRef(Loc, (*I).Len); break; @@ -3723,10 +3735,22 @@ bool AsmParser::ParseMSInlineAsm(void *AsmLoc, std::string &AsmString, OS << '$'; OS << OutputIdx++; break; + case AOK_SizeDirective: + switch((*I).Size) { + default: break; + case 8: OS << "byte ptr "; break; + case 16: OS << "word ptr "; break; + case 32: OS << "dword ptr "; break; + case 64: OS << "qword ptr "; break; + case 80: OS << "xword ptr "; break; + case 128: OS << "xmmword ptr "; break; + case 256: OS << "ymmword ptr "; break; + } } - + // Skip the original expression. - Start = Loc + (*I).Len; + if (Kind != AOK_SizeDirective) + Start = Loc + (*I).Len; } // Emit the remainder of the asm string. |