diff options
author | Anders Carlsson <andersca@mac.com> | 2008-11-09 18:54:14 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2008-11-09 18:54:14 +0000 |
commit | ce179ab4358c152164899c032302d8b0e81982b6 (patch) | |
tree | 6e9f85224acdc16df886357970187097468a7a4a /lib/CodeGen/CGStmt.cpp | |
parent | 9324e58a23f03cfe1c00fee1e27cdb5af8359077 (diff) |
Support named operands in inline asm statements.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@58940 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGStmt.cpp')
-rw-r--r-- | lib/CodeGen/CGStmt.cpp | 57 |
1 files changed, 51 insertions, 6 deletions
diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp index ece4aeeff8..a9a7a013c6 100644 --- a/lib/CodeGen/CGStmt.cpp +++ b/lib/CodeGen/CGStmt.cpp @@ -623,8 +623,16 @@ void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) { CaseRangeBlock = SavedCRBlock; } -static std::string ConvertAsmString(const char *Start, unsigned NumOperands, - bool IsSimple, bool &Failed) { +static std::string ConvertAsmString(const AsmStmt& S, bool &Failed) +{ + // FIXME: No need to create new std::string here, we could just make sure + // that we don't read past the end of the string data. + std::string str(S.getAsmString()->getStrData(), + S.getAsmString()->getByteLength()); + const char *Start = str.c_str(); + + unsigned NumOperands = S.getNumOutputs() + S.getNumInputs(); + bool IsSimple = S.isSimple(); Failed = false; static unsigned AsmCounter = 0; @@ -697,6 +705,46 @@ static std::string ConvertAsmString(const char *Start, unsigned NumOperands, Result += "${" + llvm::utostr(n) + ':' + EscapedChar + '}'; Start = End - 1; + } else if (EscapedChar == '[') { + std::string SymbolicName; + + Start++; + + while (*Start && *Start != ']') { + SymbolicName += *Start; + + Start++; + } + + if (!Start) { + // FIXME: Should be caught by sema. + assert(0 && "Could not parse symbolic name"); + } + + assert(*Start == ']' && "Error parsing symbolic name"); + + int Index = -1; + + // Check if this is an output operand. + for (unsigned i = 0; i < S.getNumOutputs(); i++) { + if (S.getOutputName(i) == SymbolicName) { + Index = i; + break; + } + } + + if (Index == -1) { + for (unsigned i = 0; i < S.getNumInputs(); i++) { + if (S.getInputName(i) == SymbolicName) { + Index = S.getNumOutputs() + i; + } + } + } + + assert(Index != -1 && "Did not find right operand!"); + + Result += '$' + llvm::utostr(Index); + } else { Failed = true; return ""; @@ -736,10 +784,7 @@ static std::string SimplifyConstraint(const char* Constraint, void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { bool Failed; std::string AsmString = - ConvertAsmString(std::string(S.getAsmString()->getStrData(), - S.getAsmString()->getByteLength()).c_str(), - S.getNumOutputs() + S.getNumInputs(), S.isSimple(), - Failed); + ConvertAsmString(S, Failed); if (Failed) { ErrorUnsupported(&S, "asm string"); |