aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGStmt.cpp
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2008-11-09 18:54:14 +0000
committerAnders Carlsson <andersca@mac.com>2008-11-09 18:54:14 +0000
commitce179ab4358c152164899c032302d8b0e81982b6 (patch)
tree6e9f85224acdc16df886357970187097468a7a4a /lib/CodeGen/CGStmt.cpp
parent9324e58a23f03cfe1c00fee1e27cdb5af8359077 (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.cpp57
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");