]> granicus.if.org Git - clang/commitdiff
Convert x86 target specific inline asm constraints to LLVM.
authorLauro Ramos Venancio <lauro.venancio@gmail.com>
Tue, 26 Feb 2008 18:33:46 +0000 (18:33 +0000)
committerLauro Ramos Venancio <lauro.venancio@gmail.com>
Tue, 26 Feb 2008 18:33:46 +0000 (18:33 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47609 91177308-0d34-0410-b5e6-96231b3b80d8

Basic/TargetInfo.cpp
Basic/Targets.cpp
CodeGen/CGStmt.cpp
include/clang/Basic/TargetInfo.h
test/CodeGen/x86-inline-asm.c [new file with mode: 0644]

index 6b600a43a9b14027c8c532d80810c9adea09c8ee..069e144a74ea679557b1654589b25e57b94fe37e 100644 (file)
@@ -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();
index 6888d44f5efce78e0560abc3cb8d777256afdd84..ed2e0e0a448a34692d3e2be685f27a13a3781103 100644 (file)
@@ -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();
   }  
index 5ef8b96cbf477ec301e574116b206293f2f61117..0da91dabe63af3a39e8534f4b5400a47b6ddc154 100644 (file)
@@ -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;
     
index 04d89437d32c78e6a0ea5b6e89a48947c17a8b4d..6d4147c35353242ebc8ed89893ae4a1a9e1f3cd1 100644 (file)
@@ -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 (file)
index 0000000..41fd7a7
--- /dev/null
@@ -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));
+}