[clang] 6685a3f - [cfe] Support target-specific escaped character in inline asm

Min-Yih Hsu via cfe-commits cfe-commits at lists.llvm.org
Mon May 24 21:40:27 PDT 2021


Author: Min-Yih Hsu
Date: 2021-05-24T21:39:21-07:00
New Revision: 6685a3f3e4c497a3a0fd06aa4e77cb442325d1ba

URL: https://github.com/llvm/llvm-project/commit/6685a3f3e4c497a3a0fd06aa4e77cb442325d1ba
DIFF: https://github.com/llvm/llvm-project/commit/6685a3f3e4c497a3a0fd06aa4e77cb442325d1ba.diff

LOG: [cfe] Support target-specific escaped character in inline asm

GCC allows each target to define a set of non-letter and non-digit
escaped characters for inline assembly that will be replaced by another
string (They call this "punctuation" characters. The existing "%%" and
"%{" -- replaced by '%' and '{' at the end -- can be seen as special
cases shared by all targets).
This patch implements this feature by adding a new hook in `TargetInfo`.

Differential Revision: https://reviews.llvm.org/D103036

Added: 
    clang/test/CodeGen/m68k-asm.c

Modified: 
    clang/include/clang/Basic/TargetInfo.h
    clang/lib/AST/Stmt.cpp
    clang/lib/Basic/Targets/M68k.cpp
    clang/lib/Basic/Targets/M68k.h

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h
index 29b957607f3e5..d59bad30e7428 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -1091,6 +1091,12 @@ class TargetInfo : public virtual TransferrableTargetInfo,
     return std::string(1, *Constraint);
   }
 
+  /// Replace some escaped characters with another string based on
+  /// target-specific rules
+  virtual llvm::Optional<std::string> handleAsmEscapedChar(char C) const {
+    return llvm::None;
+  }
+
   /// Returns a string of target-specific clobbers, in LLVM format.
   virtual const char *getClobbers() const = 0;
 

diff  --git a/clang/lib/AST/Stmt.cpp b/clang/lib/AST/Stmt.cpp
index d30df296dbd57..47693ef9fee3e 100644
--- a/clang/lib/AST/Stmt.cpp
+++ b/clang/lib/AST/Stmt.cpp
@@ -646,6 +646,8 @@ unsigned GCCAsmStmt::AnalyzeAsmString(SmallVectorImpl<AsmStringPiece>&Pieces,
       continue;
     }
 
+    const TargetInfo &TI = C.getTargetInfo();
+
     // Escaped "%" character in asm string.
     if (CurPtr == StrEnd) {
       // % at end of string is invalid (no escape).
@@ -656,6 +658,11 @@ unsigned GCCAsmStmt::AnalyzeAsmString(SmallVectorImpl<AsmStringPiece>&Pieces,
     char EscapedChar = *CurPtr++;
     switch (EscapedChar) {
     default:
+      // Handle target-specific escaped characters.
+      if (auto MaybeReplaceStr = TI.handleAsmEscapedChar(EscapedChar)) {
+        CurStringPiece += *MaybeReplaceStr;
+        continue;
+      }
       break;
     case '%': // %% -> %
     case '{': // %{ -> {
@@ -688,7 +695,6 @@ unsigned GCCAsmStmt::AnalyzeAsmString(SmallVectorImpl<AsmStringPiece>&Pieces,
       EscapedChar = *CurPtr++;
     }
 
-    const TargetInfo &TI = C.getTargetInfo();
     const SourceManager &SM = C.getSourceManager();
     const LangOptions &LO = C.getLangOpts();
 

diff  --git a/clang/lib/Basic/Targets/M68k.cpp b/clang/lib/Basic/Targets/M68k.cpp
index 9fcd58ee6401a..31cb36d37636c 100644
--- a/clang/lib/Basic/Targets/M68k.cpp
+++ b/clang/lib/Basic/Targets/M68k.cpp
@@ -191,6 +191,30 @@ bool M68kTargetInfo::validateAsmConstraint(
   return false;
 }
 
+llvm::Optional<std::string>
+M68kTargetInfo::handleAsmEscapedChar(char EscChar) const {
+  char C;
+  switch (EscChar) {
+  case '.':
+  case '#':
+    C = EscChar;
+    break;
+  case '/':
+    C = '%';
+    break;
+  case '$':
+    C = 's';
+    break;
+  case '&':
+    C = 'd';
+    break;
+  default:
+    return llvm::None;
+  }
+
+  return std::string(1, C);
+}
+
 std::string M68kTargetInfo::convertConstraint(const char *&Constraint) const {
   if (*Constraint == 'C')
     // Two-character constraint; add "^" hint for later parsing

diff  --git a/clang/lib/Basic/Targets/M68k.h b/clang/lib/Basic/Targets/M68k.h
index be2462bbd7acd..a42ca674ef9cc 100644
--- a/clang/lib/Basic/Targets/M68k.h
+++ b/clang/lib/Basic/Targets/M68k.h
@@ -47,6 +47,7 @@ class LLVM_LIBRARY_VISIBILITY M68kTargetInfo : public TargetInfo {
   std::string convertConstraint(const char *&Constraint) const override;
   bool validateAsmConstraint(const char *&Name,
                              TargetInfo::ConstraintInfo &info) const override;
+  llvm::Optional<std::string> handleAsmEscapedChar(char EscChar) const override;
   const char *getClobbers() const override;
   BuiltinVaListKind getBuiltinVaListKind() const override;
   bool setCPU(const std::string &Name) override;

diff  --git a/clang/test/CodeGen/m68k-asm.c b/clang/test/CodeGen/m68k-asm.c
new file mode 100644
index 0000000000000..bfaf2d93ef2d2
--- /dev/null
+++ b/clang/test/CodeGen/m68k-asm.c
@@ -0,0 +1,21 @@
+// REQUIRES: m68k-registered-target
+// RUN: %clang -target m68k -S %s -o - | FileCheck %s
+
+// Test special escaped character in inline assembly
+void escaped() {
+  // '.' -> '.'
+  // CHECK: move.l #66, %d1
+  __asm__ ("move%.l #66, %%d1" ::);
+  // '#' -> '#'
+  // CHECK: move.l #66, %d1
+  __asm__ ("move.l %#66, %%d1" ::);
+  // '/' -> '%'
+  // CHECK: move.l #66, %d1
+  __asm__ ("move.l #66, %/d1" ::);
+  // '$' -> 's'
+  // CHECK: muls %d0, %d1
+  __asm__ ("mul%$ %%d0, %%d1" ::);
+  // '&' -> 'd'
+  // CHECK: move.l %d0, %d1
+  __asm__ ("move.l %%%&0, %%d1" ::);
+}


        


More information about the cfe-commits mailing list