aykevl updated this revision to Diff 475419.
aykevl added a comment.

- Fix ArchHas3BytePC to remove arch 107 (of which no chips have more than 128kB 
flash)
- Fix ArchHasELPM/ArchHasELPMX to add arch 102 (it does support elpm even 
though avr-gcc claims it doesn't).
- Add notes where the provided macros may not be correct in all cases. It's 
still better than avr-gcc though.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D137572/new/

https://reviews.llvm.org/D137572

Files:
  clang/lib/Basic/Targets/AVR.cpp
  clang/test/Preprocessor/avr-atmega328p.c
  clang/test/Preprocessor/avr-attiny104.c

Index: clang/test/Preprocessor/avr-attiny104.c
===================================================================
--- clang/test/Preprocessor/avr-attiny104.c
+++ clang/test/Preprocessor/avr-attiny104.c
@@ -4,5 +4,6 @@
 // CHECK: #define __AVR 1
 // CHECK: #define __AVR_ARCH__ 100
 // CHECK: #define __AVR_ATtiny104__ 1
+// CHECK-NOT: #define __AVR_HAVE_MUL__ 1
 // CHECK: #define __AVR__ 1
 // CHECK: #define __ELF__ 1
Index: clang/test/Preprocessor/avr-atmega328p.c
===================================================================
--- clang/test/Preprocessor/avr-atmega328p.c
+++ clang/test/Preprocessor/avr-atmega328p.c
@@ -4,5 +4,9 @@
 // CHECK: #define __AVR 1
 // CHECK: #define __AVR_ARCH__ 5
 // CHECK: #define __AVR_ATmega328P__ 1
+// CHECK-NOT: #define __AVR_HAVE_EIJMP_EICALL__
+// CHECK: #define __AVR_HAVE_LPMX__ 1
+// CHECK: #define __AVR_HAVE_MOVW__ 1
+// CHECK: #define __AVR_HAVE_MUL__ 1
 // CHECK: #define __AVR__ 1
 // CHECK: #define __ELF__ 1
Index: clang/lib/Basic/Targets/AVR.cpp
===================================================================
--- clang/lib/Basic/Targets/AVR.cpp
+++ clang/lib/Basic/Targets/AVR.cpp
@@ -12,6 +12,7 @@
 
 #include "AVR.h"
 #include "clang/Basic/MacroBuilder.h"
+#include "llvm/ADT/StringSwitch.h"
 
 using namespace clang;
 using namespace clang::targets;
@@ -348,6 +349,58 @@
 } // namespace targets
 } // namespace clang
 
+static bool ArchHasELPM(StringRef Arch) {
+  return llvm::StringSwitch<bool>(Arch)
+    .Cases("31", "51", "6", true)
+    .Cases("102", "104", "105", "106", "107", true)
+    .Default(false);
+}
+
+static bool ArchHasELPMX(StringRef Arch) {
+  return llvm::StringSwitch<bool>(Arch)
+    .Cases("51", "6", true)
+    .Cases("102", "104", "105", "106", "107", true)
+    .Default(false);
+}
+
+static bool ArchHasMOVW(StringRef Arch) {
+  return llvm::StringSwitch<bool>(Arch)
+    .Cases("25", "35", "4", "5", "51", "6", true)
+    .Cases("102", "103", "104", "105", "106", "107", true)
+    .Default(false);
+}
+
+static bool ArchHasLPMX(StringRef Arch) {
+  return ArchHasMOVW(Arch); // same architectures
+}
+
+static bool ArchHasMUL(StringRef Arch) {
+  return llvm::StringSwitch<bool>(Arch)
+    .Cases("4", "5", "51", "6", true)
+    .Cases("102", "103", "104", "105", "106", "107", true)
+    .Default(false);
+}
+
+static bool ArchHasJMPCALL(StringRef Arch) {
+  return llvm::StringSwitch<bool>(Arch)
+    .Cases("3", "31", "35", "5", "51", "6", true)
+    .Cases("102", "103", "104", "105", "106", "107", true)
+    .Default(false);
+}
+
+static bool ArchHas3BytePC(StringRef Arch) {
+  // These devices have more than 128kB of program memory.
+  // Note:
+  //   - Not fully correct for arch 106: only about half the chips have more
+  //     than 128kB program memory and therefore a 3 byte PC.
+  //   - Doesn't match GCC entirely: avr-gcc thinks arch 107 goes beyond 128kB
+  //     but in fact it doesn't.
+  return llvm::StringSwitch<bool>(Arch)
+    .Case("6", true)
+    .Case("106", true)
+    .Default(false);
+}
+
 bool AVRTargetInfo::isValidCPUName(StringRef Name) const {
   return llvm::any_of(
       AVRMcus, [&](const MCUInfo &Info) { return Info.Name == Name; });
@@ -390,6 +443,30 @@
 
   Builder.defineMacro("__AVR_ARCH__", Arch);
 
+  // TODO: perhaps we should use the information from AVRDevices.td instead?
+  if (ArchHasELPM(Arch))
+    Builder.defineMacro("__AVR_HAVE_ELPM__");
+  if (ArchHasELPMX(Arch))
+    Builder.defineMacro("__AVR_HAVE_ELPMX__");
+  if (ArchHasMOVW(Arch))
+    Builder.defineMacro("__AVR_HAVE_MOVW__");
+  if (ArchHasLPMX(Arch))
+    Builder.defineMacro("__AVR_HAVE_LPMX__");
+  if (ArchHasMUL(Arch))
+    Builder.defineMacro("__AVR_HAVE_MUL__");
+  if (ArchHasJMPCALL(Arch))
+    Builder.defineMacro("__AVR_HAVE_JMP_CALL__");
+  if (ArchHas3BytePC(Arch)) {
+    // Note: some devices do support eijmp/eicall even though this macro isn't
+    // set. This is the case if they have less than 128kB flash and so
+    // eijmp/eicall isn't very useful anyway. (This matches gcc, although it's
+    // debatable whether we should be bug-compatible in this case).
+    Builder.defineMacro("__AVR_HAVE_EIJMP_EICALL__");
+    Builder.defineMacro("__AVR_3_BYTE_PC__");
+  } else {
+    Builder.defineMacro("__AVR_2_BYTE_PC__");
+  }
+
   if (NumFlashBanks >= 1)
     Builder.defineMacro("__flash", "__attribute__((address_space(1)))");
   if (NumFlashBanks >= 2)
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to