aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChad Rosier <mcrosier@apple.com>2012-08-16 17:10:59 +0000
committerChad Rosier <mcrosier@apple.com>2012-08-16 17:10:59 +0000
commitf64c11815e68f025737dc41d8d94e31e1426274d (patch)
tree0b9d0df8078f1aca80cc6f994afee418be6e3e42
parent089e5b3bf2e57da0173b170ad501867b43395385 (diff)
[ms-inline asm] Start tracking which tokens are registers and which are
variables, function or label references. The former is a potential clobber. The latter is either an input or an output. Unfortunately, it's difficult to test this patch at the moment, but the added test case will eventually do so. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@162026 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaStmt.cpp32
-rw-r--r--test/CodeGen/ms-inline-asm.c17
2 files changed, 45 insertions, 4 deletions
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index b14c7c4116..5bd5c8a96b 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -28,6 +28,7 @@
#include "clang/Lex/Preprocessor.h"
#include "clang/Basic/TargetInfo.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
@@ -2767,6 +2768,8 @@ static void patchMSAsmStrings(Sema &SemaRef, bool &IsSimple,
SourceLocation AsmLoc,
ArrayRef<Token> AsmToks,
const TargetInfo &TI,
+ std::vector<llvm::BitVector> &AsmRegs,
+ std::vector<llvm::BitVector> &AsmNames,
std::vector<std::string> &AsmStrings) {
assert (!AsmToks.empty() && "Didn't expect an empty AsmToks!");
@@ -2792,6 +2795,8 @@ static void patchMSAsmStrings(Sema &SemaRef, bool &IsSimple,
// Start a new asm string with the opcode.
if (isNewAsm) {
+ AsmRegs[NumAsmStrings].resize(AsmToks.size());
+ AsmNames[NumAsmStrings].resize(AsmToks.size());
Asm = AsmToks[i].getIdentifierInfo()->getName().str();
continue;
}
@@ -2821,14 +2826,28 @@ static void patchMSAsmStrings(Sema &SemaRef, bool &IsSimple,
case tok::identifier: {
StringRef Name = AsmToks[i].getIdentifierInfo()->getName();
- // Valid registers don't need modification.
+ // Valid register?
if (TI.isValidGCCRegisterName(Name)) {
+ AsmRegs[NumAsmStrings].set(i);
Asm += Name;
break;
}
- // TODO: Lookup the identifier.
IsSimple = false;
+
+ // FIXME: Why are we missing this segment register?
+ if (Name == "fs") {
+ Asm += Name;
+ break;
+ }
+
+ // Not a register, so this must be a variable, function or label
+ // reference. Track these as they are either an Input or an Output.
+ // Unfortunately, we don't know which is which until after we feed
+ // the patched asms to the AsmParser.
+ AsmNames[NumAsmStrings].set(i);
+
+ // TODO: Lookup the identifier and patch appropriately.
break;
}
} // AsmToks[i].getKind()
@@ -2897,12 +2916,17 @@ StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc,
std::string AsmString = buildMSAsmString(*this, AsmToks, NumAsmStrings);
bool IsSimple;
+ std::vector<llvm::BitVector> Regs;
+ std::vector<llvm::BitVector> Names;
std::vector<std::string> PatchedAsmStrings;
+
+ Regs.resize(NumAsmStrings);
+ Names.resize(NumAsmStrings);
PatchedAsmStrings.resize(NumAsmStrings);
// Rewrite operands to appease the AsmParser.
- patchMSAsmStrings(*this, IsSimple, AsmLoc, AsmToks, Context.getTargetInfo(),
- PatchedAsmStrings);
+ patchMSAsmStrings(*this, IsSimple, AsmLoc, AsmToks,
+ Context.getTargetInfo(), Regs, Names, PatchedAsmStrings);
// patchMSAsmStrings doesn't correctly patch non-simple asm statements.
if (!IsSimple) {
diff --git a/test/CodeGen/ms-inline-asm.c b/test/CodeGen/ms-inline-asm.c
index ee4ca019c7..43ecbe34f4 100644
--- a/test/CodeGen/ms-inline-asm.c
+++ b/test/CodeGen/ms-inline-asm.c
@@ -82,3 +82,20 @@ void t10() {
// CHECK: t10
// CHECK: call void asm sideeffect "push ebx\0Amov ebx, 0x07\0Apop ebx", "~{ebx},~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect
}
+
+unsigned t11(void) {
+ unsigned i = 1, j;
+ __asm {
+ mov eax, i
+ mov j, eax
+ }
+ return j;
+// CHECK: t11
+// CHECK: entry:
+// CHECK: [[I:%[a-zA-Z0-9]+]] = alloca i32, align 4
+// CHECK: [[J:%[a-zA-Z0-9]+]] = alloca i32, align 4
+// CHECK: store i32 1, i32* [[I]], align 4
+// CHECK: call void asm sideeffect "mov eax, i\0Amov j, eax", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect
+// CHECK: [[RET:%[a-zA-Z0-9]+]] = load i32* [[J]], align 4
+// CHECK: ret i32 [[RET]]
+}