#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"
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!");
// 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;
}
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()
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) {
// 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]]
+}