[clang] [llvm] [LLVM][Clang][AArch64] Implement AArch64 build attributes (PR #118771)

Oliver Stannard via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 15 04:35:36 PST 2025


================
@@ -148,13 +150,151 @@ class AArch64TargetAsmStreamer : public AArch64TargetStreamer {
     OS << "\t.seh_save_any_reg_px\tq" << Reg << ", " << Offset << "\n";
   }
 
+  void emitAttribute(StringRef VendorName, unsigned Tag, unsigned Value,
+                     std::string String, bool Override) override {
+
+    // AArch64 build attributes for assembly attribute form:
+    // .aeabi_attribute tag, value
+    if (unsigned(-1) == Value && "" == String) {
+      assert(0 && "Arguments error");
+      return;
+    }
+
+    unsigned VendorID = AArch64BuildAttributes::getVendorID(VendorName);
+
+    switch (VendorID) {
+    default:
+      assert(0 && "Subsection name error");
+      break;
+    case AArch64BuildAttributes::VENDOR_UNKNOWN:
+      if (unsigned(-1) != Value) {
+        OS << "\t.aeabi_attribute" << "\t" << Tag << ", " << Value;
+        AArch64TargetStreamer::emitAttribute(VendorName, Tag, Value, "",
+                                             Override);
+      }
+      if ("" != String) {
+        OS << "\t.aeabi_attribute" << "\t" << Tag << ", " << String;
+        AArch64TargetStreamer::emitAttribute(VendorName, Tag, unsigned(-1),
+                                             String, Override);
+      }
+      break;
+    // Note: AEABI_FEATURE_AND_BITS takes only unsigned values
+    case AArch64BuildAttributes::AEABI_FEATURE_AND_BITS:
+      switch (Tag) {
+      default: // allow emitting any attribute by number
+        OS << "\t.aeabi_attribute" << "\t" << Tag << ", " << Value;
+        // Keep the data structure consistent with the case of ELF emission
+        // (important for llvm-mc asm parsing)
+        AArch64TargetStreamer::emitAttribute(VendorName, Tag, Value, "",
+                                             Override);
+        break;
+      case AArch64BuildAttributes::TAG_FEATURE_BTI:
+        LLVM_FALLTHROUGH;
+      case AArch64BuildAttributes::TAG_FEATURE_GCS:
+        LLVM_FALLTHROUGH;
+      case AArch64BuildAttributes::TAG_FEATURE_PAC:
+        OS << "\t.aeabi_attribute" << "\t"
+           << AArch64BuildAttributes::getFeatureAndBitsTagsStr(Tag) << ", "
+           << Value;
+        AArch64TargetStreamer::emitAttribute(VendorName, Tag, Value, "",
+                                             Override);
+        break;
+      }
+      break;
+    // Note: AEABI_PAUTHABI takes only unsigned values
+    case AArch64BuildAttributes::AEABI_PAUTHABI:
+      switch (Tag) {
+      default: // allow emitting any attribute by number
+        OS << "\t.aeabi_attribute" << "\t" << Tag << ", " << Value;
+        // Keep the data structure consistent with the case of ELF emission
+        // (important for llvm-mc asm parsing)
+        AArch64TargetStreamer::emitAttribute(VendorName, Tag, Value, "",
+                                             Override);
+        break;
+      case AArch64BuildAttributes::TAG_PAUTH_PLATFORM:
+        LLVM_FALLTHROUGH;
+      case AArch64BuildAttributes::TAG_PAUTH_SCHEMA:
+        OS << "\t.aeabi_attribute" << "\t"
+           << AArch64BuildAttributes::getPauthABITagsStr(Tag) << ", " << Value;
+        AArch64TargetStreamer::emitAttribute(VendorName, Tag, Value, "",
+                                             Override);
+        break;
+      }
+      break;
+    }
+    OS << "\n";
+  }
+
+  void emitAtributesSubsection(
+      StringRef SubsectionName,
+      AArch64BuildAttributes::SubsectionOptional Optional,
+      AArch64BuildAttributes::SubsectionType ParameterType) override {
+    // The AArch64 build attributes assembly subsection header format:
+    // ".aeabi_subsection name, optional, parameter type"
+    // optional: required (0) optional (1)
+    // parameter type: uleb128 or ULEB128 (0) ntbs or NTBS (1)
+    unsigned SubsectionID = AArch64BuildAttributes::getVendorID(SubsectionName);
+
+    assert((0 == Optional || 1 == Optional) &&
+           AArch64BuildAttributes::getSubsectionOptionalUnknownError().data());
+    assert((0 == ParameterType || 1 == ParameterType) &&
+           AArch64BuildAttributes::getSubsectionTypeUnknownError().data());
+
+    std::string SubsectionTag = ".aeabi_subsection";
+    StringRef OptionalStr = getOptionalStr(Optional);
+    StringRef ParameterStr = getTypeStr(ParameterType);
+
+    switch (SubsectionID) {
+    default: {
+      assert(0 && "Subsection error");
+      break;
+    }
+    case AArch64BuildAttributes::VENDOR_UNKNOWN: {
+      // Keep the data structure consistent with the case of ELF emission
+      // (important for llvm-mc asm parsing)
+      OS << "\t" << SubsectionTag << "\t" << SubsectionName << ", "
----------------
ostannard wrote:

This is the same in each case, so can be moved outside the `switch`, leaving just the assertions here.

https://github.com/llvm/llvm-project/pull/118771


More information about the llvm-commits mailing list