[clang] Add AVR specific inline assembly escaped characters

Fixes https://github.com/llvm/llvm-project/issues/60204

Reviewed By: jacquesguan

Differential Revision: https://reviews.llvm.org/D145659
This commit is contained in:
Ben Shi 2023-03-09 16:08:22 +08:00
parent 7258317bad
commit 96cc2d07e1
3 changed files with 44 additions and 1 deletions

View File

@ -428,6 +428,23 @@ bool AVRTargetInfo::setCPU(const std::string &Name) {
return false;
}
std::optional<std::string>
AVRTargetInfo::handleAsmEscapedChar(char EscChar) const {
switch (EscChar) {
// "%~" represents for 'r' depends on the device has long jump/call.
case '~':
return ArchHasJMPCALL(Arch) ? std::string("") : std::string(1, 'r');
// "%!" represents for 'e' depends on the PC register size.
case '!':
return ArchHas3BytePC(Arch) ? std::string(1, 'e') : std::string("");
// This is an invalid escape character for AVR.
default:
return std::nullopt;
}
}
void AVRTargetInfo::getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
Builder.defineMacro("AVR");

View File

@ -170,6 +170,7 @@ public:
bool isValidCPUName(StringRef Name) const override;
void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
bool setCPU(const std::string &Name) override;
std::optional<std::string> handleAsmEscapedChar(char EscChar) const override;
StringRef getABI() const override { return ABI; }
protected:

View File

@ -1,5 +1,10 @@
// REQUIRES: avr-registered-target
// RUN: %clang_cc1 -triple avr-unknown-unknown -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -x c -triple avr -target-cpu at90s8515 -emit-llvm -o - %s \
// RUN: | FileCheck --check-prefixes=CHECK,AVR25 %s
// RUN: %clang_cc1 -x c -triple avr -target-cpu atmega328 -emit-llvm -o - %s \
// RUN: | FileCheck --check-prefixes=CHECK,AVR51 %s
// RUN: %clang_cc1 -x c -triple avr -target-cpu atmega2560 -emit-llvm -o - %s \
// RUN: | FileCheck --check-prefixes=CHECK,AVR6 %s
int data;
@ -122,3 +127,23 @@ void ora() {
// CHECK: call addrspace(0) i16 asm "subi r30, $0", "=ra"()
asm("subi r30, %0" : "=ra"(data));
}
void escapeChar(void) {
asm("_foo:");
// AVR25: call addrspace(0) void asm sideeffect "rcall _foo"
// AVR51: call addrspace(0) void asm sideeffect "call _foo"
// AVR6: call addrspace(0) void asm sideeffect "call _foo"
asm("%~call _foo" ::);
// AVR25: call addrspace(0) void asm sideeffect "rjmp _foo"
// AVR51: call addrspace(0) void asm sideeffect "jmp _foo"
// AVR6: call addrspace(0) void asm sideeffect "jmp _foo"
asm("%~jmp _foo" ::);
// AVR25: call addrspace(0) void asm sideeffect "icall"
// AVR51: call addrspace(0) void asm sideeffect "icall"
// AVR6: call addrspace(0) void asm sideeffect "eicall"
asm("%!icall" ::);
// AVR25: call addrspace(0) void asm sideeffect "ijmp"
// AVR51: call addrspace(0) void asm sideeffect "ijmp"
// AVR6: call addrspace(0) void asm sideeffect "eijmp"
asm("%!ijmp" ::);
}