forked from OSchip/llvm-project
Convert x86 target specific inline asm constraints to LLVM.
llvm-svn: 47609
This commit is contained in:
parent
a39cff3aaa
commit
c9fbd7301a
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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));
|
||||
}
|
Loading…
Reference in New Issue