Skip to content

Commit 55b08ec

Browse files
andreisfrgerekon
authored andcommitted
[Clang][Xtensa] Add Xtensa target.
1 parent 0d6cb0a commit 55b08ec

File tree

9 files changed

+559
-1
lines changed

9 files changed

+559
-1
lines changed

clang/include/clang/Basic/TargetInfo.h

+8-1
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,14 @@ class TargetInfo : public TransferrableTargetInfo,
358358
// void *__saved_reg_area_end_pointer;
359359
// void *__overflow_area_pointer;
360360
//} va_list;
361-
HexagonBuiltinVaList
361+
HexagonBuiltinVaList,
362+
363+
// typedef struct __va_list_tag {
364+
// int* __va_stk;
365+
// int* __va_reg;
366+
// int __va_ndx;
367+
//} va_list;
368+
XtensaABIBuiltinVaList
362369
};
363370

364371
protected:

clang/lib/AST/ASTContext.cpp

+39
Original file line numberDiff line numberDiff line change
@@ -9751,6 +9751,43 @@ static TypedefDecl *CreateHexagonBuiltinVaListDecl(const ASTContext *Context) {
97519751
return Context->buildImplicitTypedef(VaListTagArrayType, "__builtin_va_list");
97529752
}
97539753

9754+
static TypedefDecl *
9755+
CreateXtensaABIBuiltinVaListDecl(const ASTContext *Context) {
9756+
// typedef struct __va_list_tag {
9757+
RecordDecl *VaListTagDecl = Context->buildImplicitRecord("__va_list_tag");
9758+
9759+
VaListTagDecl->startDefinition();
9760+
9761+
// int* __va_stk;
9762+
// int* __va_reg;
9763+
// int __va_ndx;
9764+
constexpr size_t NumFields = 3;
9765+
QualType FieldTypes[NumFields] = {Context->getPointerType(Context->IntTy),
9766+
Context->getPointerType(Context->IntTy),
9767+
Context->IntTy};
9768+
const char *FieldNames[NumFields] = {"__va_stk", "__va_reg", "__va_ndx"};
9769+
9770+
// Create fields
9771+
for (unsigned i = 0; i < NumFields; ++i) {
9772+
FieldDecl *Field = FieldDecl::Create(
9773+
*Context, VaListTagDecl, SourceLocation(), SourceLocation(),
9774+
&Context->Idents.get(FieldNames[i]), FieldTypes[i], /*TInfo=*/nullptr,
9775+
/*BitWidth=*/nullptr,
9776+
/*Mutable=*/false, ICIS_NoInit);
9777+
Field->setAccess(AS_public);
9778+
VaListTagDecl->addDecl(Field);
9779+
}
9780+
VaListTagDecl->completeDefinition();
9781+
Context->VaListTagDecl = VaListTagDecl;
9782+
QualType VaListTagType = Context->getRecordType(VaListTagDecl);
9783+
9784+
// } __va_list_tag;
9785+
TypedefDecl *VaListTagTypedefDecl =
9786+
Context->buildImplicitTypedef(VaListTagType, "__builtin_va_list");
9787+
9788+
return VaListTagTypedefDecl;
9789+
}
9790+
97549791
static TypedefDecl *CreateVaListDecl(const ASTContext *Context,
97559792
TargetInfo::BuiltinVaListKind Kind) {
97569793
switch (Kind) {
@@ -9772,6 +9809,8 @@ static TypedefDecl *CreateVaListDecl(const ASTContext *Context,
97729809
return CreateSystemZBuiltinVaListDecl(Context);
97739810
case TargetInfo::HexagonBuiltinVaList:
97749811
return CreateHexagonBuiltinVaListDecl(Context);
9812+
case TargetInfo::XtensaABIBuiltinVaList:
9813+
return CreateXtensaABIBuiltinVaListDecl(Context);
97759814
}
97769815

97779816
llvm_unreachable("Unhandled __builtin_va_list type kind");

clang/lib/Basic/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ add_clang_library(clangBasic
120120
Targets/WebAssembly.cpp
121121
Targets/X86.cpp
122122
Targets/XCore.cpp
123+
Targets/Xtensa.cpp
123124
TokenKinds.cpp
124125
TypeTraits.cpp
125126
Version.cpp

clang/lib/Basic/Targets.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "Targets/WebAssembly.h"
4141
#include "Targets/X86.h"
4242
#include "Targets/XCore.h"
43+
#include "Targets/Xtensa.h"
4344
#include "clang/Basic/Diagnostic.h"
4445
#include "clang/Basic/DiagnosticFrontend.h"
4546
#include "llvm/ADT/StringExtras.h"
@@ -743,6 +744,9 @@ std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple,
743744
default:
744745
return std::make_unique<LoongArch64TargetInfo>(Triple, Opts);
745746
}
747+
748+
case llvm::Triple::xtensa:
749+
return std::make_unique<XtensaTargetInfo>(Triple, Opts);
746750
}
747751
}
748752
} // namespace targets

clang/lib/Basic/Targets/Xtensa.cpp

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//===--- Xtensa.cpp - Implement Xtensa target feature support -------------===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
6+
// See https://llvm.org/LICENSE.txt for license information.
7+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8+
//
9+
//===----------------------------------------------------------------------===//
10+
//
11+
// This file implements Xtensa TargetInfo objects.
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
#include "Xtensa.h"
16+
#include "clang/Basic/Builtins.h"
17+
#include "clang/Basic/MacroBuilder.h"
18+
#include "clang/Basic/TargetBuiltins.h"
19+
20+
using namespace clang;
21+
using namespace clang::targets;
22+
23+
void XtensaTargetInfo::getTargetDefines(const LangOptions &Opts,
24+
MacroBuilder &Builder) const {
25+
Builder.defineMacro("__xtensa__");
26+
Builder.defineMacro("__XTENSA__");
27+
if (BigEndian)
28+
Builder.defineMacro("__XTENSA_EB__");
29+
else
30+
Builder.defineMacro("__XTENSA_EL__");
31+
Builder.defineMacro("__XCHAL_HAVE_BE", BigEndian ? "1" : "0");
32+
Builder.defineMacro("__XCHAL_HAVE_ABS"); // core arch
33+
Builder.defineMacro("__XCHAL_HAVE_ADDX"); // core arch
34+
Builder.defineMacro("__XCHAL_HAVE_L32R"); // core arch
35+
}

clang/lib/Basic/Targets/Xtensa.h

+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
//===--- Xtensa.h - Declare Xtensa target feature support -------*- C++ -*-===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
6+
// See https://llvm.org/LICENSE.txt for license information.
7+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8+
//
9+
//===----------------------------------------------------------------------===//
10+
//
11+
// This file declares Xtensa TargetInfo objects.
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_XTENSA_H
16+
#define LLVM_CLANG_LIB_BASIC_TARGETS_XTENSA_H
17+
18+
#include "clang/Basic/TargetInfo.h"
19+
#include "clang/Basic/TargetOptions.h"
20+
#include "llvm/ADT/StringSwitch.h"
21+
#include "llvm/Support/Compiler.h"
22+
#include "llvm/TargetParser/Triple.h"
23+
24+
#include "clang/Basic/Builtins.h"
25+
#include "clang/Basic/MacroBuilder.h"
26+
#include "clang/Basic/TargetBuiltins.h"
27+
28+
namespace clang {
29+
namespace targets {
30+
31+
class LLVM_LIBRARY_VISIBILITY XtensaTargetInfo : public TargetInfo {
32+
static const Builtin::Info BuiltinInfo[];
33+
34+
protected:
35+
std::string CPU;
36+
37+
public:
38+
XtensaTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
39+
: TargetInfo(Triple) {
40+
// no big-endianess support yet
41+
BigEndian = false;
42+
NoAsmVariants = true;
43+
LongLongAlign = 64;
44+
SuitableAlign = 32;
45+
DoubleAlign = LongDoubleAlign = 64;
46+
SizeType = UnsignedInt;
47+
PtrDiffType = SignedInt;
48+
IntPtrType = SignedInt;
49+
WCharType = SignedInt;
50+
WIntType = UnsignedInt;
51+
UseZeroLengthBitfieldAlignment = true;
52+
MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32;
53+
resetDataLayout("e-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-n32");
54+
}
55+
56+
void getTargetDefines(const LangOptions &Opts,
57+
MacroBuilder &Builder) const override;
58+
59+
ArrayRef<Builtin::Info> getTargetBuiltins() const override {
60+
return std::nullopt;
61+
}
62+
63+
BuiltinVaListKind getBuiltinVaListKind() const override {
64+
return TargetInfo::XtensaABIBuiltinVaList;
65+
}
66+
67+
std::string_view getClobbers() const override { return ""; }
68+
69+
ArrayRef<const char *> getGCCRegNames() const override {
70+
static const char *const GCCRegNames[] = {
71+
// General register name
72+
"a0", "sp", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "a10",
73+
"a11", "a12", "a13", "a14", "a15",
74+
// Special register name
75+
"sar"};
76+
return llvm::ArrayRef(GCCRegNames);
77+
}
78+
79+
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
80+
return std::nullopt;
81+
}
82+
83+
bool validateAsmConstraint(const char *&Name,
84+
TargetInfo::ConstraintInfo &Info) const override {
85+
switch (*Name) {
86+
default:
87+
return false;
88+
case 'a':
89+
Info.setAllowsRegister();
90+
return true;
91+
}
92+
return false;
93+
}
94+
95+
int getEHDataRegisterNumber(unsigned RegNo) const override {
96+
return (RegNo < 2) ? RegNo : -1;
97+
}
98+
99+
bool isValidCPUName(StringRef Name) const override {
100+
return llvm::StringSwitch<bool>(Name).Case("generic", true).Default(false);
101+
}
102+
103+
bool setCPU(const std::string &Name) override {
104+
CPU = Name;
105+
return isValidCPUName(Name);
106+
}
107+
};
108+
109+
} // namespace targets
110+
} // namespace clang
111+
#endif // LLVM_CLANG_LIB_BASIC_TARGETS_XTENSA_H

clang/lib/Driver/ToolChains/CommonArgs.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,11 @@ std::string tools::getCPUName(const Driver &D, const ArgList &Args,
708708
case llvm::Triple::loongarch32:
709709
case llvm::Triple::loongarch64:
710710
return loongarch::getLoongArchTargetCPU(Args, T);
711+
712+
case llvm::Triple::xtensa:
713+
if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
714+
return A->getValue();
715+
return "";
711716
}
712717
}
713718

0 commit comments

Comments
 (0)