Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Clang][Xtensa] Add Xtensa target. #118008

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

gerekon
Copy link

@gerekon gerekon commented Nov 28, 2024

This PR implements support for generic Xtensa target in CLang.

Copy link

Thank you for submitting a Pull Request (PR) to the LLVM Project!

This PR will be automatically labeled and the relevant teams will be notified.

If you wish to, you can add reviewers by using the "Reviewers" section on this page.

If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using @ followed by their GitHub username.

If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers.

If you have further questions, they may be answered by the LLVM GitHub User Guide.

You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums.

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Nov 28, 2024
@llvmbot
Copy link
Member

llvmbot commented Nov 28, 2024

@llvm/pr-subscribers-backend-xtensa

@llvm/pr-subscribers-clang

Author: Alexey Gerenkov (gerekon)

Changes

This PR implements support for generic Xtensa target in CLang.


Patch is 28.35 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/118008.diff

9 Files Affected:

  • (modified) clang/include/clang/Basic/TargetInfo.h (+4-1)
  • (modified) clang/lib/AST/ASTContext.cpp (+47)
  • (modified) clang/lib/Basic/CMakeLists.txt (+1)
  • (modified) clang/lib/Basic/Targets.cpp (+4)
  • (added) clang/lib/Basic/Targets/Xtensa.cpp (+62)
  • (added) clang/lib/Basic/Targets/Xtensa.h (+141)
  • (modified) clang/lib/Driver/ToolChains/CommonArgs.cpp (+5)
  • (modified) clang/test/Preprocessor/init.c (+272)
  • (modified) clang/test/Preprocessor/stdint.c (+107)
diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h
index 9cd23d123f2bac..97444ef28a66d8 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -358,7 +358,10 @@ class TargetInfo : public TransferrableTargetInfo,
     //    void *__saved_reg_area_end_pointer;
     //    void *__overflow_area_pointer;
     //} va_list;
-    HexagonBuiltinVaList
+    HexagonBuiltinVaList,
+
+    // Tensilica Xtensa
+    XtensaABIBuiltinVaList
   };
 
 protected:
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 80e8c5b9df58e7..0f2df53d07e086 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -9727,6 +9727,51 @@ static TypedefDecl *CreateHexagonBuiltinVaListDecl(const ASTContext *Context) {
   return Context->buildImplicitTypedef(VaListTagArrayType, "__builtin_va_list");
 }
 
+static TypedefDecl *
+CreateXtensaABIBuiltinVaListDecl(const ASTContext *Context) {
+  // typedef struct __va_list_tag {
+  RecordDecl *VaListTagDecl;
+
+  VaListTagDecl = Context->buildImplicitRecord("__va_list_tag");
+  VaListTagDecl->startDefinition();
+
+  const size_t NumFields = 3;
+  QualType FieldTypes[NumFields];
+  const char *FieldNames[NumFields];
+
+  // int* __va_stk;
+  FieldTypes[0] = Context->getPointerType(Context->IntTy);
+  FieldNames[0] = "__va_stk";
+
+  // int* __va_reg;
+  FieldTypes[1] = Context->getPointerType(Context->IntTy);
+  FieldNames[1] = "__va_reg";
+
+  // int __va_ndx;
+  FieldTypes[2] = Context->IntTy;
+  FieldNames[2] = "__va_ndx";
+
+  // Create fields
+  for (unsigned i = 0; i < NumFields; ++i) {
+    FieldDecl *Field = FieldDecl::Create(
+        *Context, VaListTagDecl, SourceLocation(), SourceLocation(),
+        &Context->Idents.get(FieldNames[i]), FieldTypes[i], /*TInfo=*/nullptr,
+        /*BitWidth=*/nullptr,
+        /*Mutable=*/false, ICIS_NoInit);
+    Field->setAccess(AS_public);
+    VaListTagDecl->addDecl(Field);
+  }
+  VaListTagDecl->completeDefinition();
+  Context->VaListTagDecl = VaListTagDecl;
+  QualType VaListTagType = Context->getRecordType(VaListTagDecl);
+
+  // } __va_list_tag;
+  TypedefDecl *VaListTagTypedefDecl =
+      Context->buildImplicitTypedef(VaListTagType, "__builtin_va_list");
+
+  return VaListTagTypedefDecl;
+}
+
 static TypedefDecl *CreateVaListDecl(const ASTContext *Context,
                                      TargetInfo::BuiltinVaListKind Kind) {
   switch (Kind) {
@@ -9748,6 +9793,8 @@ static TypedefDecl *CreateVaListDecl(const ASTContext *Context,
     return CreateSystemZBuiltinVaListDecl(Context);
   case TargetInfo::HexagonBuiltinVaList:
     return CreateHexagonBuiltinVaListDecl(Context);
+  case TargetInfo::XtensaABIBuiltinVaList:
+    return CreateXtensaABIBuiltinVaListDecl(Context);
   }
 
   llvm_unreachable("Unhandled __builtin_va_list type kind");
diff --git a/clang/lib/Basic/CMakeLists.txt b/clang/lib/Basic/CMakeLists.txt
index e11e1ac4a6fa63..331dfbb3f4b67e 100644
--- a/clang/lib/Basic/CMakeLists.txt
+++ b/clang/lib/Basic/CMakeLists.txt
@@ -120,6 +120,7 @@ add_clang_library(clangBasic
   Targets/WebAssembly.cpp
   Targets/X86.cpp
   Targets/XCore.cpp
+  Targets/Xtensa.cpp
   TokenKinds.cpp
   TypeTraits.cpp
   Version.cpp
diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp
index 0021d33c45d7c9..3ef99acdc2e323 100644
--- a/clang/lib/Basic/Targets.cpp
+++ b/clang/lib/Basic/Targets.cpp
@@ -40,6 +40,7 @@
 #include "Targets/WebAssembly.h"
 #include "Targets/X86.h"
 #include "Targets/XCore.h"
+#include "Targets/Xtensa.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/DiagnosticFrontend.h"
 #include "llvm/ADT/StringExtras.h"
@@ -737,6 +738,9 @@ std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple,
     default:
         return std::make_unique<LoongArch64TargetInfo>(Triple, Opts);
     }
+
+  case llvm::Triple::xtensa:
+    return std::make_unique<XtensaTargetInfo>(Triple, Opts);
   }
 }
 } // namespace targets
diff --git a/clang/lib/Basic/Targets/Xtensa.cpp b/clang/lib/Basic/Targets/Xtensa.cpp
new file mode 100644
index 00000000000000..b46db6bfbd67ac
--- /dev/null
+++ b/clang/lib/Basic/Targets/Xtensa.cpp
@@ -0,0 +1,62 @@
+//===--- Xtensa.cpp - Implement Xtensa target feature support -------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements Xtensa TargetInfo objects.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Xtensa.h"
+#include "clang/Basic/Builtins.h"
+#include "clang/Basic/MacroBuilder.h"
+#include "clang/Basic/TargetBuiltins.h"
+
+using namespace clang;
+using namespace clang::targets;
+
+void XtensaTargetInfo::getTargetDefines(const LangOptions &Opts,
+                                        MacroBuilder &Builder) const {
+  Builder.defineMacro("__xtensa__");
+  Builder.defineMacro("__XTENSA__");
+  if (BigEndian)
+    Builder.defineMacro("__XTENSA_EB__");
+  else
+    Builder.defineMacro("__XTENSA_EL__");
+  if (HasWindowed)
+    Builder.defineMacro("__XTENSA_WINDOWED_ABI__");
+  else
+    Builder.defineMacro("__XTENSA_CALL0_ABI__");
+  if (!HasFP)
+    Builder.defineMacro("__XTENSA_SOFT_FLOAT__");
+  Builder.defineMacro("__XCHAL_HAVE_BE", BigEndian ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_DENSITY", HasDensity ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_MAC16", HasMAC16 ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_MUL16", HasMul16 ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_MUL32", HasMul32 ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_MUL32_HIGH", HasMul32High ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_DIV32", HasDiv32 ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_NSA", HasNSA ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_MINMAX", HasMINMAX ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_SEXT", HasSEXT ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_LOOPS", HasLoop ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_THREADPTR", HasTHREADPTR ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_S32C1I", HasS32C1I ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_BOOLEANS", HasBoolean ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_FP", HasFP ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_FP_DIV", HasFP ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_FP_RECIP", HasFP ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_FP_SQRT", HasFP ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_FP_RSQRT", HasFP ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_FP_POSTINC", HasFP ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_WINDOWED", HasWindowed ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_DEBUG", HasDebug ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_ABS");  // core arch
+  Builder.defineMacro("__XCHAL_HAVE_ADDX"); // core arch
+  Builder.defineMacro("__XCHAL_HAVE_L32R"); // core arch
+}
diff --git a/clang/lib/Basic/Targets/Xtensa.h b/clang/lib/Basic/Targets/Xtensa.h
new file mode 100644
index 00000000000000..d850980bfc33e1
--- /dev/null
+++ b/clang/lib/Basic/Targets/Xtensa.h
@@ -0,0 +1,141 @@
+//===--- Xtensa.h - Declare Xtensa target feature support -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares Xtensa TargetInfo objects.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_XTENSA_H
+#define LLVM_CLANG_LIB_BASIC_TARGETS_XTENSA_H
+
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/TargetOptions.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/TargetParser/Triple.h"
+
+#include "clang/Basic/Builtins.h"
+#include "clang/Basic/MacroBuilder.h"
+#include "clang/Basic/TargetBuiltins.h"
+
+namespace clang {
+namespace targets {
+
+class LLVM_LIBRARY_VISIBILITY XtensaTargetInfo : public TargetInfo {
+  static const Builtin::Info BuiltinInfo[];
+
+protected:
+  std::string CPU;
+  bool HasFP = false;
+  bool HasWindowed = false;
+  bool HasBoolean = false;
+  bool HasHIFI3 = false;
+  bool HasDensity = false;
+  bool HasLoop = false;
+  bool HasSEXT = false;
+  bool HasNSA = false;
+  bool HasCLAPMS = false;
+  bool HasMINMAX = false;
+  bool HasMul16 = false;
+  bool HasMul32 = false;
+  bool HasMul32High = false;
+  bool HasDiv32 = false;
+  bool HasMAC16 = false;
+  bool HasS32C1I = false;
+  bool HasTHREADPTR = false;
+  bool HasExtendedL32R = false;
+  bool HasATOMCTL = false;
+  bool HasMEMCTL = false;
+  bool HasDebug = false;
+  bool HasException = false;
+  bool HasHighPriInterrupts = false;
+  bool HasCoprocessor = false;
+  bool HasInterrupt = false;
+  bool HasRelocatableVector = false;
+  bool HasTimerInt = false;
+  bool HasPRID = false;
+  bool HasRegionProtection = false;
+  bool HasMiscSR = false;
+
+public:
+  XtensaTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
+      : TargetInfo(Triple) {
+    BigEndian = false;
+    NoAsmVariants = true;
+    LongLongAlign = 64;
+    SuitableAlign = 32;
+    DoubleAlign = LongDoubleAlign = 64;
+    SizeType = UnsignedInt;
+    PtrDiffType = SignedInt;
+    IntPtrType = SignedInt;
+    WCharType = SignedInt;
+    WIntType = UnsignedInt;
+    UseZeroLengthBitfieldAlignment = true;
+    MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32;
+    resetDataLayout("e-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-n32");
+  }
+
+  void getTargetDefines(const LangOptions &Opts,
+                        MacroBuilder &Builder) const override;
+
+  ArrayRef<Builtin::Info> getTargetBuiltins() const override {
+    return std::nullopt;
+  }
+
+  BuiltinVaListKind getBuiltinVaListKind() const override {
+
+    return TargetInfo::XtensaABIBuiltinVaList;
+  }
+
+  std::string_view getClobbers() const override { return ""; }
+
+  ArrayRef<const char *> getGCCRegNames() const override {
+    static const char *const GCCRegNames[] = {
+        // General register name
+        "a0", "sp", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "a10",
+        "a11", "a12", "a13", "a14", "a15",
+        // Special register name
+        "sar"};
+    return llvm::ArrayRef(GCCRegNames);
+  }
+
+  ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
+    return std::nullopt;
+  }
+
+  bool validateAsmConstraint(const char *&Name,
+                             TargetInfo::ConstraintInfo &Info) const override {
+    switch (*Name) {
+    default:
+      return false;
+    case 'a':
+      Info.setAllowsRegister();
+      return true;
+    }
+    return false;
+  }
+
+  int getEHDataRegisterNumber(unsigned RegNo) const override {
+    return (RegNo < 2) ? RegNo : -1;
+  }
+
+  bool isValidCPUName(StringRef Name) const override {
+    return llvm::StringSwitch<bool>(Name).Case("generic", true).Default(false);
+  }
+
+  bool setCPU(const std::string &Name) override {
+    CPU = Name;
+    return isValidCPUName(Name);
+  }
+};
+
+} // namespace targets
+} // namespace clang
+#endif // LLVM_CLANG_LIB_BASIC_TARGETS_XTENSA_H
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 8d977149e62485..49298c5c6cb8fb 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -671,6 +671,11 @@ std::string tools::getCPUName(const Driver &D, const ArgList &Args,
   case llvm::Triple::loongarch32:
   case llvm::Triple::loongarch64:
     return loongarch::getLoongArchTargetCPU(Args, T);
+
+  case llvm::Triple::xtensa:
+    if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
+      return A->getValue();
+    return "";
   }
 }
 
diff --git a/clang/test/Preprocessor/init.c b/clang/test/Preprocessor/init.c
index 05225c120b13de..ead349dec3cf18 100644
--- a/clang/test/Preprocessor/init.c
+++ b/clang/test/Preprocessor/init.c
@@ -2742,3 +2742,275 @@
 // RISCV64-LINUX: #define __unix__ 1
 // RISCV64-LINUX: #define linux 1
 // RISCV64-LINUX: #define unix 1
+
+// RUN: %clang_cc1 -E -dM -ffreestanding -fgnuc-version=4.2.1 -triple=xtensa  < /dev/null \
+// RUN:   | FileCheck -match-full-lines -check-prefix=XTENSA %s
+// XTENSA: #define _ILP32 1
+// XTENSA: #define __ATOMIC_ACQUIRE 2
+// XTENSA: #define __ATOMIC_ACQ_REL 4
+// XTENSA: #define __ATOMIC_CONSUME 1
+// XTENSA: #define __ATOMIC_RELAXED 0
+// XTENSA: #define __ATOMIC_RELEASE 3
+// XTENSA: #define __ATOMIC_SEQ_CST 5
+// XTENSA: #define __BIGGEST_ALIGNMENT__ 4
+// XTENSA: #define __BITINT_MAXWIDTH__ 128
+// XTENSA: #define __BOOL_WIDTH__ 1
+// XTENSA: #define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
+// XTENSA: #define __CHAR16_TYPE__ unsigned short
+// XTENSA: #define __CHAR32_TYPE__ unsigned int
+// XTENSA: #define __CHAR_BIT__ 8
+// XTENSA: #define __CLANG_ATOMIC_BOOL_LOCK_FREE 2
+// XTENSA: #define __CLANG_ATOMIC_CHAR16_T_LOCK_FREE 2
+// XTENSA: #define __CLANG_ATOMIC_CHAR32_T_LOCK_FREE 2
+// XTENSA: #define __CLANG_ATOMIC_CHAR_LOCK_FREE 2
+// XTENSA: #define __CLANG_ATOMIC_INT_LOCK_FREE 2
+// XTENSA: #define __CLANG_ATOMIC_LLONG_LOCK_FREE 1
+// XTENSA: #define __CLANG_ATOMIC_LONG_LOCK_FREE 2
+// XTENSA: #define __CLANG_ATOMIC_POINTER_LOCK_FREE 2
+// XTENSA: #define __CLANG_ATOMIC_SHORT_LOCK_FREE 2
+// XTENSA: #define __CLANG_ATOMIC_WCHAR_T_LOCK_FREE 2
+// XTENSA: #define __CONSTANT_CFSTRINGS__ 1
+// XTENSA: #define __DBL_DECIMAL_DIG__ 17
+// XTENSA: #define __DBL_DENORM_MIN__ 4.9406564584124654e-324
+// XTENSA: #define __DBL_DIG__ 15
+// XTENSA: #define __DBL_EPSILON__ 2.2204460492503131e-16
+// XTENSA: #define __DBL_HAS_DENORM__ 1
+// XTENSA: #define __DBL_HAS_INFINITY__ 1
+// XTENSA: #define __DBL_HAS_QUIET_NAN__ 1
+// XTENSA: #define __DBL_MANT_DIG__ 53
+// XTENSA: #define __DBL_MAX_10_EXP__ 308
+// XTENSA: #define __DBL_MAX_EXP__ 1024
+// XTENSA: #define __DBL_MAX__ 1.7976931348623157e+308
+// XTENSA: #define __DBL_MIN_10_EXP__ (-307)
+// XTENSA: #define __DBL_MIN_EXP__ (-1021)
+// XTENSA: #define __DBL_MIN__ 2.2250738585072014e-308
+// XTENSA: #define __DBL_NORM_MAX__ 1.7976931348623157e+308
+// XTENSA: #define __DECIMAL_DIG__ __LDBL_DECIMAL_DIG__
+// XTENSA: #define __ELF__ 1
+// XTENSA: #define __FINITE_MATH_ONLY__ 0
+// XTENSA: #define __FLT_DECIMAL_DIG__ 9
+// XTENSA: #define __FLT_DENORM_MIN__ 1.40129846e-45F
+// XTENSA: #define __FLT_DIG__ 6
+// XTENSA: #define __FLT_EPSILON__ 1.19209290e-7F
+// XTENSA: #define __FLT_HAS_DENORM__ 1
+// XTENSA: #define __FLT_HAS_INFINITY__ 1
+// XTENSA: #define __FLT_HAS_QUIET_NAN__ 1
+// XTENSA: #define __FLT_MANT_DIG__ 24
+// XTENSA: #define __FLT_MAX_10_EXP__ 38
+// XTENSA: #define __FLT_MAX_EXP__ 128
+// XTENSA: #define __FLT_MAX__ 3.40282347e+38F
+// XTENSA: #define __FLT_MIN_10_EXP__ (-37)
+// XTENSA: #define __FLT_MIN_EXP__ (-125)
+// XTENSA: #define __FLT_MIN__ 1.17549435e-38F
+// XTENSA: #define __FLT_NORM_MAX__ 3.40282347e+38F
+// XTENSA: #define __FLT_RADIX__ 2
+// XTENSA: #define __FPCLASS_NEGINF 0x0004
+// XTENSA: #define __FPCLASS_NEGNORMAL 0x0008
+// XTENSA: #define __FPCLASS_NEGSUBNORMAL 0x0010
+// XTENSA: #define __FPCLASS_NEGZERO 0x0020
+// XTENSA: #define __FPCLASS_POSINF 0x0200
+// XTENSA: #define __FPCLASS_POSNORMAL 0x0100
+// XTENSA: #define __FPCLASS_POSSUBNORMAL 0x0080
+// XTENSA: #define __FPCLASS_POSZERO 0x0040
+// XTENSA: #define __FPCLASS_QNAN 0x0002
+// XTENSA: #define __FPCLASS_SNAN 0x0001
+// XTENSA: #define __GCC_ATOMIC_BOOL_LOCK_FREE 2
+// XTENSA: #define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2
+// XTENSA: #define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2
+// XTENSA: #define __GCC_ATOMIC_CHAR_LOCK_FREE 2
+// XTENSA: #define __GCC_ATOMIC_INT_LOCK_FREE 2
+// XTENSA: #define __GCC_ATOMIC_LLONG_LOCK_FREE 1
+// XTENSA: #define __GCC_ATOMIC_LONG_LOCK_FREE 2
+// XTENSA: #define __GCC_ATOMIC_POINTER_LOCK_FREE 2
+// XTENSA: #define __GCC_ATOMIC_SHORT_LOCK_FREE 2
+// XTENSA: #define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1
+// XTENSA: #define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2
+// XTENSA: #define __GCC_CONSTRUCTIVE_SIZE 64
+// XTENSA: #define __GCC_DESTRUCTIVE_SIZE 64
+// XTENSA: #define __GNUC_MINOR__ {{.*}}
+// XTENSA: #define __GNUC_PATCHLEVEL__ {{.*}}
+// XTENSA: #define __GNUC_STDC_INLINE__ 1
+// XTENSA: #define __GNUC__ {{.*}}
+// XTENSA: #define __GXX_ABI_VERSION {{.*}}
+// XTENSA: #define __ILP32__ 1
+// XTENSA: #define __INT16_C_SUFFIX__ 
+// XTENSA: #define __INT16_MAX__ 32767
+// XTENSA: #define __INT16_TYPE__ short
+// XTENSA: #define __INT32_C_SUFFIX__ 
+// XTENSA: #define __INT32_MAX__ 2147483647
+// XTENSA: #define __INT32_TYPE__ int
+// XTENSA: #define __INT64_C_SUFFIX__ LL
+// XTENSA: #define __INT64_MAX__ 9223372036854775807LL
+// XTENSA: #define __INT64_TYPE__ long long int
+// XTENSA: #define __INT8_C_SUFFIX__ 
+// XTENSA: #define __INT8_MAX__ 127
+// XTENSA: #define __INT8_TYPE__ signed char
+// XTENSA: #define __INTMAX_C_SUFFIX__ LL
+// XTENSA: #define __INTMAX_MAX__ 9223372036854775807LL
+// XTENSA: #define __INTMAX_TYPE__ long long int
+// XTENSA: #define __INTMAX_WIDTH__ 64
+// XTENSA: #define __INTPTR_MAX__ 2147483647
+// XTENSA: #define __INTPTR_TYPE__ int
+// XTENSA: #define __INTPTR_WIDTH__ 32
+// TODO: Xtensa GCC defines INT_FAST16 as int
+// XTENSA: #define __INT_FAST16_MAX__ 32767
+// XTENSA: #define __INT_FAST16_TYPE__ short
+// XTENSA: #define __INT_FAST16_WIDTH__ 16
+// XTENSA: #define __INT_FAST32_MAX__ 2147483647
+// XTENSA: #define __INT_FAST32_TYPE__ int
+// XTENSA: #define __INT_FAST32_WIDTH__ 32
+// XTENSA: #define __INT_FAST64_MAX__ 9223372036854775807LL
+// XTENSA: #define __INT_FAST64_TYPE__ long long int
+// XTENSA: #define __INT_FAST64_WIDTH__ 64
+// TODO: Xtensa GCC defines INT_FAST8 as int
+// XTENSA: #define __INT_FAST8_MAX__ 127
+// XTENSA: #define __INT_FAST8_TYPE__ signed char
+// XTENSA: #define __INT_FAST8_WIDTH__ 8
+// XTENSA: #define __INT_LEAST16_MAX__ 32767
+// XTENSA: #define __INT_LEAST16_TYPE__ short
+// XTENSA: #define __INT_LEAST16_WIDTH__ 16
+// XTENSA: #define __INT_LEAST32_MAX__ 2147483647
+// XTENSA: #define __INT_LEAST32_TYPE__ int
+// XTENSA: #define __INT_LEAST32_WIDTH__ 32
+// XTENSA: #define __INT_LEAST64_MAX__ 9223372036854775807LL
+// XTENSA: #define __INT_LEAST64_TYPE__ long long int
+// XTENSA: #define __INT_LEAST64_WIDTH__ 64
+// XTENSA: #define __INT_LEAST8_MAX__ 127
+// XTENSA: #define __INT_LEAST8_TYPE__ signed char
+// XTENSA: #define __INT_LEAST8_WIDTH__ 8
+// XTENSA: #define __INT_MAX__ 2147483647
+// XTENSA: #define __INT_WIDTH__ 32
+// XTENSA: #define __LDBL_DECIMAL_DIG__ 17
+// XTENSA: #define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L
+// XTENSA: #define __LDBL_DIG__ 15
+// XTENSA: #define __LDBL_EPSILON__ 2.2204460492503131e-16L
+// XTENSA: #define __LDBL_HAS_DENORM__ 1
+// XTENSA: #define __LDBL_HAS_INFINITY__ 1
+// XTENSA: #define __LDBL_HAS_QUIET_NAN__ 1
+// XTENSA: #define __LDBL_MANT_DIG__ 53
+// XTENSA: #define __LDBL_MAX_10_EXP__ 308
+// XTENSA: #define __LDBL_MAX_EXP__ 1024
+// XTENSA: #define __LDBL_MAX__ 1.7976931348623157e+308L
+// XTENSA: #define __LDBL_MIN_10_EXP__ (-307)
+// XTENSA: #define __LDBL_MIN_EXP__ (-1021)
+// XTENSA: #define __LDBL_MIN__ 2.2250738585072014e-308L
+// XTENSA: #define __LDBL_NORM_MAX__ 1.7976931348623157e+308L
+// XTENSA: #define __LITTLE_ENDIAN__ 1
+// XTENSA: #define __LLONG_WIDTH__ 64
+// XTENSA: #define __LONG_LONG_MAX__ 9223372036854775807LL
+// XTENSA: #define __LONG_MAX__ 2147483647L
+// XTENSA: #define __LONG_WIDTH__ 32
+// XTENSA: #define __MEMORY_SCOPE_DEVICE 1
+// XTENSA: #define __MEMORY_SCOPE_SINGLE 4
+// XTENSA: #define __MEMORY_SCOPE_SYSTEM 0
+// XTENSA: #define __MEMORY_SCOPE_WRKGRP 2
+// XTENSA: #define __MEMORY_SCOPE_WVFRNT 3
+// XTENSA: #define __NO_INLINE__ 1
+// XTENSA: #define __NO_MATH_ERRNO__ 1
+// XTENSA: #define __OBJC_BOOL_IS_BOOL 0
+// XTENSA: #define __POINTER_WIDTH__ 32
+// XTENSA: #define __PRAGMA_REDEFINE_EXTNAME 1
+// XTENSA: #define __PTRDIFF_MAX__ 2147483647
+// XTENSA: #define __PTRDIFF_TYPE__ int
+// XTENSA: #define __PTRDIFF_WIDT...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented Nov 28, 2024

@llvm/pr-subscribers-clang-driver

Author: Alexey Gerenkov (gerekon)

Changes

This PR implements support for generic Xtensa target in CLang.


Patch is 28.35 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/118008.diff

9 Files Affected:

  • (modified) clang/include/clang/Basic/TargetInfo.h (+4-1)
  • (modified) clang/lib/AST/ASTContext.cpp (+47)
  • (modified) clang/lib/Basic/CMakeLists.txt (+1)
  • (modified) clang/lib/Basic/Targets.cpp (+4)
  • (added) clang/lib/Basic/Targets/Xtensa.cpp (+62)
  • (added) clang/lib/Basic/Targets/Xtensa.h (+141)
  • (modified) clang/lib/Driver/ToolChains/CommonArgs.cpp (+5)
  • (modified) clang/test/Preprocessor/init.c (+272)
  • (modified) clang/test/Preprocessor/stdint.c (+107)
diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h
index 9cd23d123f2bac..97444ef28a66d8 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -358,7 +358,10 @@ class TargetInfo : public TransferrableTargetInfo,
     //    void *__saved_reg_area_end_pointer;
     //    void *__overflow_area_pointer;
     //} va_list;
-    HexagonBuiltinVaList
+    HexagonBuiltinVaList,
+
+    // Tensilica Xtensa
+    XtensaABIBuiltinVaList
   };
 
 protected:
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 80e8c5b9df58e7..0f2df53d07e086 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -9727,6 +9727,51 @@ static TypedefDecl *CreateHexagonBuiltinVaListDecl(const ASTContext *Context) {
   return Context->buildImplicitTypedef(VaListTagArrayType, "__builtin_va_list");
 }
 
+static TypedefDecl *
+CreateXtensaABIBuiltinVaListDecl(const ASTContext *Context) {
+  // typedef struct __va_list_tag {
+  RecordDecl *VaListTagDecl;
+
+  VaListTagDecl = Context->buildImplicitRecord("__va_list_tag");
+  VaListTagDecl->startDefinition();
+
+  const size_t NumFields = 3;
+  QualType FieldTypes[NumFields];
+  const char *FieldNames[NumFields];
+
+  // int* __va_stk;
+  FieldTypes[0] = Context->getPointerType(Context->IntTy);
+  FieldNames[0] = "__va_stk";
+
+  // int* __va_reg;
+  FieldTypes[1] = Context->getPointerType(Context->IntTy);
+  FieldNames[1] = "__va_reg";
+
+  // int __va_ndx;
+  FieldTypes[2] = Context->IntTy;
+  FieldNames[2] = "__va_ndx";
+
+  // Create fields
+  for (unsigned i = 0; i < NumFields; ++i) {
+    FieldDecl *Field = FieldDecl::Create(
+        *Context, VaListTagDecl, SourceLocation(), SourceLocation(),
+        &Context->Idents.get(FieldNames[i]), FieldTypes[i], /*TInfo=*/nullptr,
+        /*BitWidth=*/nullptr,
+        /*Mutable=*/false, ICIS_NoInit);
+    Field->setAccess(AS_public);
+    VaListTagDecl->addDecl(Field);
+  }
+  VaListTagDecl->completeDefinition();
+  Context->VaListTagDecl = VaListTagDecl;
+  QualType VaListTagType = Context->getRecordType(VaListTagDecl);
+
+  // } __va_list_tag;
+  TypedefDecl *VaListTagTypedefDecl =
+      Context->buildImplicitTypedef(VaListTagType, "__builtin_va_list");
+
+  return VaListTagTypedefDecl;
+}
+
 static TypedefDecl *CreateVaListDecl(const ASTContext *Context,
                                      TargetInfo::BuiltinVaListKind Kind) {
   switch (Kind) {
@@ -9748,6 +9793,8 @@ static TypedefDecl *CreateVaListDecl(const ASTContext *Context,
     return CreateSystemZBuiltinVaListDecl(Context);
   case TargetInfo::HexagonBuiltinVaList:
     return CreateHexagonBuiltinVaListDecl(Context);
+  case TargetInfo::XtensaABIBuiltinVaList:
+    return CreateXtensaABIBuiltinVaListDecl(Context);
   }
 
   llvm_unreachable("Unhandled __builtin_va_list type kind");
diff --git a/clang/lib/Basic/CMakeLists.txt b/clang/lib/Basic/CMakeLists.txt
index e11e1ac4a6fa63..331dfbb3f4b67e 100644
--- a/clang/lib/Basic/CMakeLists.txt
+++ b/clang/lib/Basic/CMakeLists.txt
@@ -120,6 +120,7 @@ add_clang_library(clangBasic
   Targets/WebAssembly.cpp
   Targets/X86.cpp
   Targets/XCore.cpp
+  Targets/Xtensa.cpp
   TokenKinds.cpp
   TypeTraits.cpp
   Version.cpp
diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp
index 0021d33c45d7c9..3ef99acdc2e323 100644
--- a/clang/lib/Basic/Targets.cpp
+++ b/clang/lib/Basic/Targets.cpp
@@ -40,6 +40,7 @@
 #include "Targets/WebAssembly.h"
 #include "Targets/X86.h"
 #include "Targets/XCore.h"
+#include "Targets/Xtensa.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/DiagnosticFrontend.h"
 #include "llvm/ADT/StringExtras.h"
@@ -737,6 +738,9 @@ std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple,
     default:
         return std::make_unique<LoongArch64TargetInfo>(Triple, Opts);
     }
+
+  case llvm::Triple::xtensa:
+    return std::make_unique<XtensaTargetInfo>(Triple, Opts);
   }
 }
 } // namespace targets
diff --git a/clang/lib/Basic/Targets/Xtensa.cpp b/clang/lib/Basic/Targets/Xtensa.cpp
new file mode 100644
index 00000000000000..b46db6bfbd67ac
--- /dev/null
+++ b/clang/lib/Basic/Targets/Xtensa.cpp
@@ -0,0 +1,62 @@
+//===--- Xtensa.cpp - Implement Xtensa target feature support -------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements Xtensa TargetInfo objects.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Xtensa.h"
+#include "clang/Basic/Builtins.h"
+#include "clang/Basic/MacroBuilder.h"
+#include "clang/Basic/TargetBuiltins.h"
+
+using namespace clang;
+using namespace clang::targets;
+
+void XtensaTargetInfo::getTargetDefines(const LangOptions &Opts,
+                                        MacroBuilder &Builder) const {
+  Builder.defineMacro("__xtensa__");
+  Builder.defineMacro("__XTENSA__");
+  if (BigEndian)
+    Builder.defineMacro("__XTENSA_EB__");
+  else
+    Builder.defineMacro("__XTENSA_EL__");
+  if (HasWindowed)
+    Builder.defineMacro("__XTENSA_WINDOWED_ABI__");
+  else
+    Builder.defineMacro("__XTENSA_CALL0_ABI__");
+  if (!HasFP)
+    Builder.defineMacro("__XTENSA_SOFT_FLOAT__");
+  Builder.defineMacro("__XCHAL_HAVE_BE", BigEndian ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_DENSITY", HasDensity ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_MAC16", HasMAC16 ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_MUL16", HasMul16 ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_MUL32", HasMul32 ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_MUL32_HIGH", HasMul32High ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_DIV32", HasDiv32 ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_NSA", HasNSA ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_MINMAX", HasMINMAX ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_SEXT", HasSEXT ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_LOOPS", HasLoop ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_THREADPTR", HasTHREADPTR ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_S32C1I", HasS32C1I ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_BOOLEANS", HasBoolean ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_FP", HasFP ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_FP_DIV", HasFP ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_FP_RECIP", HasFP ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_FP_SQRT", HasFP ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_FP_RSQRT", HasFP ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_FP_POSTINC", HasFP ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_WINDOWED", HasWindowed ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_DEBUG", HasDebug ? "1" : "0");
+  Builder.defineMacro("__XCHAL_HAVE_ABS");  // core arch
+  Builder.defineMacro("__XCHAL_HAVE_ADDX"); // core arch
+  Builder.defineMacro("__XCHAL_HAVE_L32R"); // core arch
+}
diff --git a/clang/lib/Basic/Targets/Xtensa.h b/clang/lib/Basic/Targets/Xtensa.h
new file mode 100644
index 00000000000000..d850980bfc33e1
--- /dev/null
+++ b/clang/lib/Basic/Targets/Xtensa.h
@@ -0,0 +1,141 @@
+//===--- Xtensa.h - Declare Xtensa target feature support -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares Xtensa TargetInfo objects.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_XTENSA_H
+#define LLVM_CLANG_LIB_BASIC_TARGETS_XTENSA_H
+
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/TargetOptions.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/TargetParser/Triple.h"
+
+#include "clang/Basic/Builtins.h"
+#include "clang/Basic/MacroBuilder.h"
+#include "clang/Basic/TargetBuiltins.h"
+
+namespace clang {
+namespace targets {
+
+class LLVM_LIBRARY_VISIBILITY XtensaTargetInfo : public TargetInfo {
+  static const Builtin::Info BuiltinInfo[];
+
+protected:
+  std::string CPU;
+  bool HasFP = false;
+  bool HasWindowed = false;
+  bool HasBoolean = false;
+  bool HasHIFI3 = false;
+  bool HasDensity = false;
+  bool HasLoop = false;
+  bool HasSEXT = false;
+  bool HasNSA = false;
+  bool HasCLAPMS = false;
+  bool HasMINMAX = false;
+  bool HasMul16 = false;
+  bool HasMul32 = false;
+  bool HasMul32High = false;
+  bool HasDiv32 = false;
+  bool HasMAC16 = false;
+  bool HasS32C1I = false;
+  bool HasTHREADPTR = false;
+  bool HasExtendedL32R = false;
+  bool HasATOMCTL = false;
+  bool HasMEMCTL = false;
+  bool HasDebug = false;
+  bool HasException = false;
+  bool HasHighPriInterrupts = false;
+  bool HasCoprocessor = false;
+  bool HasInterrupt = false;
+  bool HasRelocatableVector = false;
+  bool HasTimerInt = false;
+  bool HasPRID = false;
+  bool HasRegionProtection = false;
+  bool HasMiscSR = false;
+
+public:
+  XtensaTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
+      : TargetInfo(Triple) {
+    BigEndian = false;
+    NoAsmVariants = true;
+    LongLongAlign = 64;
+    SuitableAlign = 32;
+    DoubleAlign = LongDoubleAlign = 64;
+    SizeType = UnsignedInt;
+    PtrDiffType = SignedInt;
+    IntPtrType = SignedInt;
+    WCharType = SignedInt;
+    WIntType = UnsignedInt;
+    UseZeroLengthBitfieldAlignment = true;
+    MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32;
+    resetDataLayout("e-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-n32");
+  }
+
+  void getTargetDefines(const LangOptions &Opts,
+                        MacroBuilder &Builder) const override;
+
+  ArrayRef<Builtin::Info> getTargetBuiltins() const override {
+    return std::nullopt;
+  }
+
+  BuiltinVaListKind getBuiltinVaListKind() const override {
+
+    return TargetInfo::XtensaABIBuiltinVaList;
+  }
+
+  std::string_view getClobbers() const override { return ""; }
+
+  ArrayRef<const char *> getGCCRegNames() const override {
+    static const char *const GCCRegNames[] = {
+        // General register name
+        "a0", "sp", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "a10",
+        "a11", "a12", "a13", "a14", "a15",
+        // Special register name
+        "sar"};
+    return llvm::ArrayRef(GCCRegNames);
+  }
+
+  ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
+    return std::nullopt;
+  }
+
+  bool validateAsmConstraint(const char *&Name,
+                             TargetInfo::ConstraintInfo &Info) const override {
+    switch (*Name) {
+    default:
+      return false;
+    case 'a':
+      Info.setAllowsRegister();
+      return true;
+    }
+    return false;
+  }
+
+  int getEHDataRegisterNumber(unsigned RegNo) const override {
+    return (RegNo < 2) ? RegNo : -1;
+  }
+
+  bool isValidCPUName(StringRef Name) const override {
+    return llvm::StringSwitch<bool>(Name).Case("generic", true).Default(false);
+  }
+
+  bool setCPU(const std::string &Name) override {
+    CPU = Name;
+    return isValidCPUName(Name);
+  }
+};
+
+} // namespace targets
+} // namespace clang
+#endif // LLVM_CLANG_LIB_BASIC_TARGETS_XTENSA_H
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 8d977149e62485..49298c5c6cb8fb 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -671,6 +671,11 @@ std::string tools::getCPUName(const Driver &D, const ArgList &Args,
   case llvm::Triple::loongarch32:
   case llvm::Triple::loongarch64:
     return loongarch::getLoongArchTargetCPU(Args, T);
+
+  case llvm::Triple::xtensa:
+    if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
+      return A->getValue();
+    return "";
   }
 }
 
diff --git a/clang/test/Preprocessor/init.c b/clang/test/Preprocessor/init.c
index 05225c120b13de..ead349dec3cf18 100644
--- a/clang/test/Preprocessor/init.c
+++ b/clang/test/Preprocessor/init.c
@@ -2742,3 +2742,275 @@
 // RISCV64-LINUX: #define __unix__ 1
 // RISCV64-LINUX: #define linux 1
 // RISCV64-LINUX: #define unix 1
+
+// RUN: %clang_cc1 -E -dM -ffreestanding -fgnuc-version=4.2.1 -triple=xtensa  < /dev/null \
+// RUN:   | FileCheck -match-full-lines -check-prefix=XTENSA %s
+// XTENSA: #define _ILP32 1
+// XTENSA: #define __ATOMIC_ACQUIRE 2
+// XTENSA: #define __ATOMIC_ACQ_REL 4
+// XTENSA: #define __ATOMIC_CONSUME 1
+// XTENSA: #define __ATOMIC_RELAXED 0
+// XTENSA: #define __ATOMIC_RELEASE 3
+// XTENSA: #define __ATOMIC_SEQ_CST 5
+// XTENSA: #define __BIGGEST_ALIGNMENT__ 4
+// XTENSA: #define __BITINT_MAXWIDTH__ 128
+// XTENSA: #define __BOOL_WIDTH__ 1
+// XTENSA: #define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
+// XTENSA: #define __CHAR16_TYPE__ unsigned short
+// XTENSA: #define __CHAR32_TYPE__ unsigned int
+// XTENSA: #define __CHAR_BIT__ 8
+// XTENSA: #define __CLANG_ATOMIC_BOOL_LOCK_FREE 2
+// XTENSA: #define __CLANG_ATOMIC_CHAR16_T_LOCK_FREE 2
+// XTENSA: #define __CLANG_ATOMIC_CHAR32_T_LOCK_FREE 2
+// XTENSA: #define __CLANG_ATOMIC_CHAR_LOCK_FREE 2
+// XTENSA: #define __CLANG_ATOMIC_INT_LOCK_FREE 2
+// XTENSA: #define __CLANG_ATOMIC_LLONG_LOCK_FREE 1
+// XTENSA: #define __CLANG_ATOMIC_LONG_LOCK_FREE 2
+// XTENSA: #define __CLANG_ATOMIC_POINTER_LOCK_FREE 2
+// XTENSA: #define __CLANG_ATOMIC_SHORT_LOCK_FREE 2
+// XTENSA: #define __CLANG_ATOMIC_WCHAR_T_LOCK_FREE 2
+// XTENSA: #define __CONSTANT_CFSTRINGS__ 1
+// XTENSA: #define __DBL_DECIMAL_DIG__ 17
+// XTENSA: #define __DBL_DENORM_MIN__ 4.9406564584124654e-324
+// XTENSA: #define __DBL_DIG__ 15
+// XTENSA: #define __DBL_EPSILON__ 2.2204460492503131e-16
+// XTENSA: #define __DBL_HAS_DENORM__ 1
+// XTENSA: #define __DBL_HAS_INFINITY__ 1
+// XTENSA: #define __DBL_HAS_QUIET_NAN__ 1
+// XTENSA: #define __DBL_MANT_DIG__ 53
+// XTENSA: #define __DBL_MAX_10_EXP__ 308
+// XTENSA: #define __DBL_MAX_EXP__ 1024
+// XTENSA: #define __DBL_MAX__ 1.7976931348623157e+308
+// XTENSA: #define __DBL_MIN_10_EXP__ (-307)
+// XTENSA: #define __DBL_MIN_EXP__ (-1021)
+// XTENSA: #define __DBL_MIN__ 2.2250738585072014e-308
+// XTENSA: #define __DBL_NORM_MAX__ 1.7976931348623157e+308
+// XTENSA: #define __DECIMAL_DIG__ __LDBL_DECIMAL_DIG__
+// XTENSA: #define __ELF__ 1
+// XTENSA: #define __FINITE_MATH_ONLY__ 0
+// XTENSA: #define __FLT_DECIMAL_DIG__ 9
+// XTENSA: #define __FLT_DENORM_MIN__ 1.40129846e-45F
+// XTENSA: #define __FLT_DIG__ 6
+// XTENSA: #define __FLT_EPSILON__ 1.19209290e-7F
+// XTENSA: #define __FLT_HAS_DENORM__ 1
+// XTENSA: #define __FLT_HAS_INFINITY__ 1
+// XTENSA: #define __FLT_HAS_QUIET_NAN__ 1
+// XTENSA: #define __FLT_MANT_DIG__ 24
+// XTENSA: #define __FLT_MAX_10_EXP__ 38
+// XTENSA: #define __FLT_MAX_EXP__ 128
+// XTENSA: #define __FLT_MAX__ 3.40282347e+38F
+// XTENSA: #define __FLT_MIN_10_EXP__ (-37)
+// XTENSA: #define __FLT_MIN_EXP__ (-125)
+// XTENSA: #define __FLT_MIN__ 1.17549435e-38F
+// XTENSA: #define __FLT_NORM_MAX__ 3.40282347e+38F
+// XTENSA: #define __FLT_RADIX__ 2
+// XTENSA: #define __FPCLASS_NEGINF 0x0004
+// XTENSA: #define __FPCLASS_NEGNORMAL 0x0008
+// XTENSA: #define __FPCLASS_NEGSUBNORMAL 0x0010
+// XTENSA: #define __FPCLASS_NEGZERO 0x0020
+// XTENSA: #define __FPCLASS_POSINF 0x0200
+// XTENSA: #define __FPCLASS_POSNORMAL 0x0100
+// XTENSA: #define __FPCLASS_POSSUBNORMAL 0x0080
+// XTENSA: #define __FPCLASS_POSZERO 0x0040
+// XTENSA: #define __FPCLASS_QNAN 0x0002
+// XTENSA: #define __FPCLASS_SNAN 0x0001
+// XTENSA: #define __GCC_ATOMIC_BOOL_LOCK_FREE 2
+// XTENSA: #define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2
+// XTENSA: #define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2
+// XTENSA: #define __GCC_ATOMIC_CHAR_LOCK_FREE 2
+// XTENSA: #define __GCC_ATOMIC_INT_LOCK_FREE 2
+// XTENSA: #define __GCC_ATOMIC_LLONG_LOCK_FREE 1
+// XTENSA: #define __GCC_ATOMIC_LONG_LOCK_FREE 2
+// XTENSA: #define __GCC_ATOMIC_POINTER_LOCK_FREE 2
+// XTENSA: #define __GCC_ATOMIC_SHORT_LOCK_FREE 2
+// XTENSA: #define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1
+// XTENSA: #define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2
+// XTENSA: #define __GCC_CONSTRUCTIVE_SIZE 64
+// XTENSA: #define __GCC_DESTRUCTIVE_SIZE 64
+// XTENSA: #define __GNUC_MINOR__ {{.*}}
+// XTENSA: #define __GNUC_PATCHLEVEL__ {{.*}}
+// XTENSA: #define __GNUC_STDC_INLINE__ 1
+// XTENSA: #define __GNUC__ {{.*}}
+// XTENSA: #define __GXX_ABI_VERSION {{.*}}
+// XTENSA: #define __ILP32__ 1
+// XTENSA: #define __INT16_C_SUFFIX__ 
+// XTENSA: #define __INT16_MAX__ 32767
+// XTENSA: #define __INT16_TYPE__ short
+// XTENSA: #define __INT32_C_SUFFIX__ 
+// XTENSA: #define __INT32_MAX__ 2147483647
+// XTENSA: #define __INT32_TYPE__ int
+// XTENSA: #define __INT64_C_SUFFIX__ LL
+// XTENSA: #define __INT64_MAX__ 9223372036854775807LL
+// XTENSA: #define __INT64_TYPE__ long long int
+// XTENSA: #define __INT8_C_SUFFIX__ 
+// XTENSA: #define __INT8_MAX__ 127
+// XTENSA: #define __INT8_TYPE__ signed char
+// XTENSA: #define __INTMAX_C_SUFFIX__ LL
+// XTENSA: #define __INTMAX_MAX__ 9223372036854775807LL
+// XTENSA: #define __INTMAX_TYPE__ long long int
+// XTENSA: #define __INTMAX_WIDTH__ 64
+// XTENSA: #define __INTPTR_MAX__ 2147483647
+// XTENSA: #define __INTPTR_TYPE__ int
+// XTENSA: #define __INTPTR_WIDTH__ 32
+// TODO: Xtensa GCC defines INT_FAST16 as int
+// XTENSA: #define __INT_FAST16_MAX__ 32767
+// XTENSA: #define __INT_FAST16_TYPE__ short
+// XTENSA: #define __INT_FAST16_WIDTH__ 16
+// XTENSA: #define __INT_FAST32_MAX__ 2147483647
+// XTENSA: #define __INT_FAST32_TYPE__ int
+// XTENSA: #define __INT_FAST32_WIDTH__ 32
+// XTENSA: #define __INT_FAST64_MAX__ 9223372036854775807LL
+// XTENSA: #define __INT_FAST64_TYPE__ long long int
+// XTENSA: #define __INT_FAST64_WIDTH__ 64
+// TODO: Xtensa GCC defines INT_FAST8 as int
+// XTENSA: #define __INT_FAST8_MAX__ 127
+// XTENSA: #define __INT_FAST8_TYPE__ signed char
+// XTENSA: #define __INT_FAST8_WIDTH__ 8
+// XTENSA: #define __INT_LEAST16_MAX__ 32767
+// XTENSA: #define __INT_LEAST16_TYPE__ short
+// XTENSA: #define __INT_LEAST16_WIDTH__ 16
+// XTENSA: #define __INT_LEAST32_MAX__ 2147483647
+// XTENSA: #define __INT_LEAST32_TYPE__ int
+// XTENSA: #define __INT_LEAST32_WIDTH__ 32
+// XTENSA: #define __INT_LEAST64_MAX__ 9223372036854775807LL
+// XTENSA: #define __INT_LEAST64_TYPE__ long long int
+// XTENSA: #define __INT_LEAST64_WIDTH__ 64
+// XTENSA: #define __INT_LEAST8_MAX__ 127
+// XTENSA: #define __INT_LEAST8_TYPE__ signed char
+// XTENSA: #define __INT_LEAST8_WIDTH__ 8
+// XTENSA: #define __INT_MAX__ 2147483647
+// XTENSA: #define __INT_WIDTH__ 32
+// XTENSA: #define __LDBL_DECIMAL_DIG__ 17
+// XTENSA: #define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L
+// XTENSA: #define __LDBL_DIG__ 15
+// XTENSA: #define __LDBL_EPSILON__ 2.2204460492503131e-16L
+// XTENSA: #define __LDBL_HAS_DENORM__ 1
+// XTENSA: #define __LDBL_HAS_INFINITY__ 1
+// XTENSA: #define __LDBL_HAS_QUIET_NAN__ 1
+// XTENSA: #define __LDBL_MANT_DIG__ 53
+// XTENSA: #define __LDBL_MAX_10_EXP__ 308
+// XTENSA: #define __LDBL_MAX_EXP__ 1024
+// XTENSA: #define __LDBL_MAX__ 1.7976931348623157e+308L
+// XTENSA: #define __LDBL_MIN_10_EXP__ (-307)
+// XTENSA: #define __LDBL_MIN_EXP__ (-1021)
+// XTENSA: #define __LDBL_MIN__ 2.2250738585072014e-308L
+// XTENSA: #define __LDBL_NORM_MAX__ 1.7976931348623157e+308L
+// XTENSA: #define __LITTLE_ENDIAN__ 1
+// XTENSA: #define __LLONG_WIDTH__ 64
+// XTENSA: #define __LONG_LONG_MAX__ 9223372036854775807LL
+// XTENSA: #define __LONG_MAX__ 2147483647L
+// XTENSA: #define __LONG_WIDTH__ 32
+// XTENSA: #define __MEMORY_SCOPE_DEVICE 1
+// XTENSA: #define __MEMORY_SCOPE_SINGLE 4
+// XTENSA: #define __MEMORY_SCOPE_SYSTEM 0
+// XTENSA: #define __MEMORY_SCOPE_WRKGRP 2
+// XTENSA: #define __MEMORY_SCOPE_WVFRNT 3
+// XTENSA: #define __NO_INLINE__ 1
+// XTENSA: #define __NO_MATH_ERRNO__ 1
+// XTENSA: #define __OBJC_BOOL_IS_BOOL 0
+// XTENSA: #define __POINTER_WIDTH__ 32
+// XTENSA: #define __PRAGMA_REDEFINE_EXTNAME 1
+// XTENSA: #define __PTRDIFF_MAX__ 2147483647
+// XTENSA: #define __PTRDIFF_TYPE__ int
+// XTENSA: #define __PTRDIFF_WIDT...
[truncated]

@gerekon
Copy link
Author

gerekon commented Nov 28, 2024

@sstefan1 @andreisfr PTAL

@gerekon
Copy link
Author

gerekon commented Dec 5, 2024

ping

@banach-space
Copy link
Contributor

I'm not active in this area, so removed myself from the list of reviewers.

Copy link
Collaborator

@erichkeane erichkeane left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know what this target IS, did we have an RFC to approve this in Clang as a target? Do we have sufficient interest in the project to maintain it/keep it?

@gerekon
Copy link
Author

gerekon commented Dec 6, 2024

I don't know what this target IS, did we have an RFC to approve this in Clang as a target? Do we have sufficient interest in the project to maintain it/keep it?

@erichkeane
This is a part of our work for upstreaming Xtensa target support espressif#4.
We finished with base functionality in LLVM backend. It is upstreamed. And now we are preparing PRs with Xtensa architecture features and would like to support it in Clang.
This patch adds support for Xtensa target in Clang.

@efriedma-quic
Copy link
Collaborator

For reference, the RFC for the LLVM backend was https://discourse.llvm.org/t/rfc-request-for-upstream-tensilica-xtensa-esp32-backend/65355 . Given there's an LLVM backend, I don't think we need a separate clang RFC? Assuming the target doesn't require any exotic frontend features, we'd inevitably reach the same conclusion as the LLVM backend RFC.

That said, I am a little concerned that progress on the upstreaming is moving excessively slowly; it's been over two years since the original RFC. New backends don't normally take that long... what exactly has been happening?

@erichkeane
Copy link
Collaborator

For reference, the RFC for the LLVM backend was https://discourse.llvm.org/t/rfc-request-for-upstream-tensilica-xtensa-esp32-backend/65355 . Given there's an LLVM backend, I don't think we need a separate clang RFC? Assuming the target doesn't require any exotic frontend features, we'd inevitably reach the same conclusion as the LLVM backend RFC.

That said, I am a little concerned that progress on the upstreaming is moving excessively slowly; it's been over two years since the original RFC. New backends don't normally take that long... what exactly has been happening?

I wasn't asking for a separate clang RFC, just I wasn't aware of the previous one! As you mentioned, it was significantly in the past, so I'd not heard of it/remembered it, and my quick grepping didn't show the backend.

Given the time/progress so far, I wouldn't mind some sort of re-assertion from the community at large that we are a: still interested in this, b: have a dedicated someone willing/able to do the work, which is a criteria for our RFCs

clang/include/clang/Basic/TargetInfo.h Show resolved Hide resolved
clang/lib/AST/ASTContext.cpp Outdated Show resolved Hide resolved
clang/lib/AST/ASTContext.cpp Outdated Show resolved Hide resolved
clang/lib/Basic/Targets/Xtensa.cpp Outdated Show resolved Hide resolved
clang/lib/Basic/Targets/Xtensa.cpp Show resolved Hide resolved
clang/lib/Basic/Targets/Xtensa.h Outdated Show resolved Hide resolved
Copy link
Collaborator

@AaronBallman AaronBallman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know that we need reaffirmation; the target is already in the backend, so unless there's a call to remove the target, I think Clang's fine to expose it.

That said, if there are signs that the target is only sporadically maintained, reaffirming that's not the case would be a good thing, so I think Eli's question is still a good one to get an answer for.

clang/lib/AST/ASTContext.cpp Outdated Show resolved Hide resolved
clang/test/Preprocessor/init.c Outdated Show resolved Hide resolved
@gerekon
Copy link
Author

gerekon commented Dec 10, 2024

Hi guys,

Thanks for you comments.

I am a little concerned that progress on the upstreaming is moving excessively slowly. what exactly has been happening?

That said, if there are signs that the target is only sporadically maintained, reaffirming that's not the case would be a good thing, so I think Eli's question is still a good one to get an answer for.

We are maintaining our own fork of LLVM with Xtensa support for several years and release Clang-based toolchain at least for every major LLVM release.
I agree that our past upstreaming activity looks like sporadic. There are several reasons for this:

  1. At the very first step it was difficult to find people who could review Xtensa arch related part without architecture specification in public. We had to prepare our own version of Xtensa specification basing on the GCC and binutils source code available in public. And finally we have planted the first base patch set.
  2. Lack of enough resources to cover our own internal development needs and keep upstreaming process at a good pace.

Now after extending our LLVM team and some sort of "pushing" from our Rust team and Swift community we have special assignment in the team for upstreaming process. This year we have submitted 13 patches (not including this one):

We have a plan for our upstreaming activity and from this point we can do some patch work in parallel. The main upstreaming activity is done by @andreisfr. I created this PR and plan to create others especially ones related to Xtensa baremetal toolchain support.

So keeping in mind our Rust team (esp-rs/rust#89) and Swift community (https://forums.swift.org/t/is-there-support-for-xtensa-lx7-cores/72458) demands and HIFI3 related contribution from @maciej-czekaj it looks like there people exist who are interested in having Xtensa support in LLVM. And we are going to maintain it.

Copy link
Collaborator

@efriedma-quic efriedma-quic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with one very minor comment

clang/lib/Basic/Targets/Xtensa.h Outdated Show resolved Hide resolved
@gerekon gerekon force-pushed the clang_xtensa_target branch from 271c945 to 55b08ec Compare December 24, 2024 17:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:Xtensa clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants