Skip to content

Commit

Permalink
[Clang][Xtensa] Add Xtensa target.
Browse files Browse the repository at this point in the history
  • Loading branch information
andreisfr authored and gerekon committed Dec 24, 2024
1 parent 0d6cb0a commit 55b08ec
Show file tree
Hide file tree
Showing 9 changed files with 559 additions and 1 deletion.
9 changes: 8 additions & 1 deletion clang/include/clang/Basic/TargetInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,14 @@ class TargetInfo : public TransferrableTargetInfo,
// void *__saved_reg_area_end_pointer;
// void *__overflow_area_pointer;
//} va_list;
HexagonBuiltinVaList
HexagonBuiltinVaList,

// typedef struct __va_list_tag {
// int* __va_stk;
// int* __va_reg;
// int __va_ndx;
//} va_list;
XtensaABIBuiltinVaList
};

protected:
Expand Down
39 changes: 39 additions & 0 deletions clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9751,6 +9751,43 @@ 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 = Context->buildImplicitRecord("__va_list_tag");

VaListTagDecl->startDefinition();

// int* __va_stk;
// int* __va_reg;
// int __va_ndx;
constexpr size_t NumFields = 3;
QualType FieldTypes[NumFields] = {Context->getPointerType(Context->IntTy),
Context->getPointerType(Context->IntTy),
Context->IntTy};
const char *FieldNames[NumFields] = {"__va_stk", "__va_reg", "__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) {
Expand All @@ -9772,6 +9809,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");
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Basic/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/Basic/Targets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -743,6 +744,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
Expand Down
35 changes: 35 additions & 0 deletions clang/lib/Basic/Targets/Xtensa.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//===--- 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__");
Builder.defineMacro("__XCHAL_HAVE_BE", BigEndian ? "1" : "0");
Builder.defineMacro("__XCHAL_HAVE_ABS"); // core arch
Builder.defineMacro("__XCHAL_HAVE_ADDX"); // core arch
Builder.defineMacro("__XCHAL_HAVE_L32R"); // core arch
}
111 changes: 111 additions & 0 deletions clang/lib/Basic/Targets/Xtensa.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
//===--- 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;

public:
XtensaTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
: TargetInfo(Triple) {
// no big-endianess support yet
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
5 changes: 5 additions & 0 deletions clang/lib/Driver/ToolChains/CommonArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,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 "";
}
}

Expand Down
Loading

0 comments on commit 55b08ec

Please sign in to comment.