[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