summaryrefslogtreecommitdiffstats
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
commit592b90a4763673471ac2d684e999a3865d35b5ee (patch)
tree8440f454e28342cca0ebc5b5912669873dcd6299
parent80c13773e3a49b23d2c20da3545099686cbbcbd9 (diff)
downloadbcm5719-llvm-592b90a4763673471ac2d684e999a3865d35b5ee.tar.gz
bcm5719-llvm-592b90a4763673471ac2d684e999a3865d35b5ee.zip
[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. llvm-svn: 162026
-rw-r--r--clang/lib/Sema/SemaStmt.cpp32
-rw-r--r--clang/test/CodeGen/ms-inline-asm.c17
2 files changed, 45 insertions, 4 deletions
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index b14c7c41163..5bd5c8a96b2 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/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/clang/test/CodeGen/ms-inline-asm.c b/clang/test/CodeGen/ms-inline-asm.c
index ee4ca019c73..43ecbe34f47 100644
--- a/clang/test/CodeGen/ms-inline-asm.c
+++ b/clang/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]]
+}
OpenPOWER on IntegriCloud