From: Lauro Ramos Venancio Date: Tue, 26 Feb 2008 18:33:46 +0000 (+0000) Subject: Convert x86 target specific inline asm constraints to LLVM. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a5694b8b0096215137bf1c273764ec93ac4898fd;p=clang Convert x86 target specific inline asm constraints to LLVM. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47609 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Basic/TargetInfo.cpp b/Basic/TargetInfo.cpp index 6b600a43a9..069e144a74 100644 --- a/Basic/TargetInfo.cpp +++ b/Basic/TargetInfo.cpp @@ -454,6 +454,10 @@ bool TargetInfo::validateInputConstraint(const char *Name, return true; } +std::string TargetInfo::convertConstraint(const char Constraint) const { + return PrimaryTarget->convertConstraint(Constraint); +} + const char *TargetInfo::getClobbers() const { return PrimaryTarget->getClobbers(); diff --git a/Basic/Targets.cpp b/Basic/Targets.cpp index 6888d44f5e..ed2e0e0a44 100644 --- a/Basic/Targets.cpp +++ b/Basic/Targets.cpp @@ -493,6 +493,28 @@ namespace X86 { } } + static std::string convertConstraint(const char Constraint) { + switch (Constraint) { + case 'a': return std::string("{ax}"); + case 'b': return std::string("{bx}"); + case 'c': return std::string("{cx}"); + case 'd': return std::string("{dx}"); + case 'S': return std::string("{si}"); + case 'D': return std::string("{di}"); + case 't': // top of floating point stack. + return std::string("{st}"); + case 'u': // second from top of floating point stack. + return std::string("{st(1)}"); // second from top of floating point stack. + case 'A': // edx:eax. + case 'q': // a, b, c, d registers or any integer register in 64-bit. + case 'Z': // 32-bit integer constant for used with zero-extending x86_64 + // instructions. + assert(false && "Unimplemented inline asm constraint"); + default: + return std::string(1, Constraint); + } + } + const char *getClobbers() { return "~{dirflag},~{fpsr},~{flags}"; } @@ -614,6 +636,11 @@ public: TargetInfo::ConstraintInfo &info) const { return X86::validateAsmConstraint(c, info); } + + virtual std::string convertConstraint(const char Constraint) const { + return X86::convertConstraint(Constraint); + } + virtual const char *getClobbers() const { return X86::getClobbers(); } @@ -650,7 +677,10 @@ public: virtual bool validateAsmConstraint(char c, TargetInfo::ConstraintInfo &info) const { return X86::validateAsmConstraint(c, info); - } + } + virtual std::string convertConstraint(const char Constraint) const { + return X86::convertConstraint(Constraint); + } virtual const char *getClobbers() const { return X86::getClobbers(); } @@ -732,6 +762,9 @@ public: TargetInfo::ConstraintInfo &info) const { return X86::validateAsmConstraint(c, info); } + virtual std::string convertConstraint(const char Constraint) const { + return X86::convertConstraint(Constraint); + } virtual const char *getClobbers() const { return X86::getClobbers(); } diff --git a/CodeGen/CGStmt.cpp b/CodeGen/CGStmt.cpp index 5ef8b96cbf..0da91dabe6 100644 --- a/CodeGen/CGStmt.cpp +++ b/CodeGen/CGStmt.cpp @@ -594,14 +594,14 @@ static inline std::string ConvertAsmString(const char *Start, return Result; } -static std::string SimplifyConstraint(const char* Constraint) -{ +static std::string SimplifyConstraint(const char* Constraint, + TargetInfo &Target) { std::string Result; while (*Constraint) { switch (*Constraint) { default: - Result += *Constraint; + Result += Target.convertConstraint(*Constraint); break; // Ignore these case '*': @@ -648,7 +648,7 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { assert(result && "Failed to parse output constraint"); // Simplify the output constraint. - OutputConstraint = SimplifyConstraint(OutputConstraint.c_str() + 1); + OutputConstraint = SimplifyConstraint(OutputConstraint.c_str() + 1, Target); LValue Dest = EmitLValue(S.getOutputExpr(i)); const llvm::Type *DestValueType = @@ -713,7 +713,7 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { Constraints += ','; // Simplify the input constraint. - InputConstraint = SimplifyConstraint(InputConstraint.c_str()); + InputConstraint = SimplifyConstraint(InputConstraint.c_str(), Target); llvm::Value *Arg; diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h index 04d89437d3..6d4147c353 100644 --- a/include/clang/Basic/TargetInfo.h +++ b/include/clang/Basic/TargetInfo.h @@ -227,6 +227,8 @@ public: bool validateOutputConstraint(const char *Name, ConstraintInfo &Info) const; bool validateInputConstraint (const char *Name, unsigned NumOutputs, ConstraintInfo &info) const; + + std::string convertConstraint(const char Constraint) const; // Returns a string of target-specific clobbers, in LLVM format. const char *getClobbers() const; @@ -346,6 +348,10 @@ public: virtual bool validateAsmConstraint(char c, TargetInfo::ConstraintInfo &info) const= 0; + + virtual std::string convertConstraint(const char Constraint) const { + return std::string(1, Constraint); + } virtual const char *getClobbers() const = 0; private: diff --git a/test/CodeGen/x86-inline-asm.c b/test/CodeGen/x86-inline-asm.c new file mode 100644 index 0000000000..41fd7a72d8 --- /dev/null +++ b/test/CodeGen/x86-inline-asm.c @@ -0,0 +1,15 @@ +// RUN: clang %s -triple=i686-pc-linux-gnu -emit-llvm -o - > %t1 +// RUN: grep "ax" %t1 +// RUN: grep "bx" %t1 +// RUN: grep "cx" %t1 +// RUN: grep "dx" %t1 +// RUN: grep "di" %t1 +// RUN: grep "si" %t1 +// RUN: grep "st" %t1 +// RUN: grep "st(1)" %t1 + +void f() { + int d1, d2; + asm ("" : "=a" (d1), "=b" (d2) : + "c" (0), "d" (0), "S" (0), "D" (0), "t" (0), "u" (0)); +}