Skip to content

Commit bf04885

Browse files
andreisfrgerekon
authored andcommitted
[Clang][Xtensa] Add Xtensa target.
1 parent 78c7024 commit bf04885

File tree

9 files changed

+643
-1
lines changed

9 files changed

+643
-1
lines changed

clang/include/clang/Basic/TargetInfo.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,10 @@ 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+
// Tensilica Xtensa
364+
XtensaABIBuiltinVaList
362365
};
363366

364367
protected:

clang/lib/AST/ASTContext.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9727,6 +9727,51 @@ static TypedefDecl *CreateHexagonBuiltinVaListDecl(const ASTContext *Context) {
97279727
return Context->buildImplicitTypedef(VaListTagArrayType, "__builtin_va_list");
97289728
}
97299729

9730+
static TypedefDecl *
9731+
CreateXtensaABIBuiltinVaListDecl(const ASTContext *Context) {
9732+
// typedef struct __va_list_tag {
9733+
RecordDecl *VaListTagDecl;
9734+
9735+
VaListTagDecl = Context->buildImplicitRecord("__va_list_tag");
9736+
VaListTagDecl->startDefinition();
9737+
9738+
const size_t NumFields = 3;
9739+
QualType FieldTypes[NumFields];
9740+
const char *FieldNames[NumFields];
9741+
9742+
// int* __va_stk;
9743+
FieldTypes[0] = Context->getPointerType(Context->IntTy);
9744+
FieldNames[0] = "__va_stk";
9745+
9746+
// int* __va_reg;
9747+
FieldTypes[1] = Context->getPointerType(Context->IntTy);
9748+
FieldNames[1] = "__va_reg";
9749+
9750+
// int __va_ndx;
9751+
FieldTypes[2] = Context->IntTy;
9752+
FieldNames[2] = "__va_ndx";
9753+
9754+
// Create fields
9755+
for (unsigned i = 0; i < NumFields; ++i) {
9756+
FieldDecl *Field = FieldDecl::Create(
9757+
*Context, VaListTagDecl, SourceLocation(), SourceLocation(),
9758+
&Context->Idents.get(FieldNames[i]), FieldTypes[i], /*TInfo=*/nullptr,
9759+
/*BitWidth=*/nullptr,
9760+
/*Mutable=*/false, ICIS_NoInit);
9761+
Field->setAccess(AS_public);
9762+
VaListTagDecl->addDecl(Field);
9763+
}
9764+
VaListTagDecl->completeDefinition();
9765+
Context->VaListTagDecl = VaListTagDecl;
9766+
QualType VaListTagType = Context->getRecordType(VaListTagDecl);
9767+
9768+
// } __va_list_tag;
9769+
TypedefDecl *VaListTagTypedefDecl =
9770+
Context->buildImplicitTypedef(VaListTagType, "__builtin_va_list");
9771+
9772+
return VaListTagTypedefDecl;
9773+
}
9774+
97309775
static TypedefDecl *CreateVaListDecl(const ASTContext *Context,
97319776
TargetInfo::BuiltinVaListKind Kind) {
97329777
switch (Kind) {
@@ -9748,6 +9793,8 @@ static TypedefDecl *CreateVaListDecl(const ASTContext *Context,
97489793
return CreateSystemZBuiltinVaListDecl(Context);
97499794
case TargetInfo::HexagonBuiltinVaList:
97509795
return CreateHexagonBuiltinVaListDecl(Context);
9796+
case TargetInfo::XtensaABIBuiltinVaList:
9797+
return CreateXtensaABIBuiltinVaListDecl(Context);
97519798
}
97529799

97539800
llvm_unreachable("Unhandled __builtin_va_list type kind");

clang/lib/Basic/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
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

Lines changed: 4 additions & 0 deletions
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"
@@ -737,6 +738,9 @@ std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple,
737738
default:
738739
return std::make_unique<LoongArch64TargetInfo>(Triple, Opts);
739740
}
741+
742+
case llvm::Triple::xtensa:
743+
return std::make_unique<XtensaTargetInfo>(Triple, Opts);
740744
}
741745
}
742746
} // namespace targets

clang/lib/Basic/Targets/Xtensa.cpp

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
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+
if (HasWindowed)
32+
Builder.defineMacro("__XTENSA_WINDOWED_ABI__");
33+
else
34+
Builder.defineMacro("__XTENSA_CALL0_ABI__");
35+
if (!HasFP)
36+
Builder.defineMacro("__XTENSA_SOFT_FLOAT__");
37+
Builder.defineMacro("__XCHAL_HAVE_BE", BigEndian ? "1" : "0");
38+
Builder.defineMacro("__XCHAL_HAVE_DENSITY", HasDensity ? "1" : "0");
39+
Builder.defineMacro("__XCHAL_HAVE_MAC16", HasMAC16 ? "1" : "0");
40+
Builder.defineMacro("__XCHAL_HAVE_MUL16", HasMul16 ? "1" : "0");
41+
Builder.defineMacro("__XCHAL_HAVE_MUL32", HasMul32 ? "1" : "0");
42+
Builder.defineMacro("__XCHAL_HAVE_MUL32_HIGH", HasMul32High ? "1" : "0");
43+
Builder.defineMacro("__XCHAL_HAVE_DIV32", HasDiv32 ? "1" : "0");
44+
Builder.defineMacro("__XCHAL_HAVE_NSA", HasNSA ? "1" : "0");
45+
Builder.defineMacro("__XCHAL_HAVE_MINMAX", HasMINMAX ? "1" : "0");
46+
Builder.defineMacro("__XCHAL_HAVE_SEXT", HasSEXT ? "1" : "0");
47+
Builder.defineMacro("__XCHAL_HAVE_LOOPS", HasLoop ? "1" : "0");
48+
Builder.defineMacro("__XCHAL_HAVE_THREADPTR", HasTHREADPTR ? "1" : "0");
49+
Builder.defineMacro("__XCHAL_HAVE_S32C1I", HasS32C1I ? "1" : "0");
50+
Builder.defineMacro("__XCHAL_HAVE_BOOLEANS", HasBoolean ? "1" : "0");
51+
Builder.defineMacro("__XCHAL_HAVE_FP", HasFP ? "1" : "0");
52+
Builder.defineMacro("__XCHAL_HAVE_FP_DIV", HasFP ? "1" : "0");
53+
Builder.defineMacro("__XCHAL_HAVE_FP_RECIP", HasFP ? "1" : "0");
54+
Builder.defineMacro("__XCHAL_HAVE_FP_SQRT", HasFP ? "1" : "0");
55+
Builder.defineMacro("__XCHAL_HAVE_FP_RSQRT", HasFP ? "1" : "0");
56+
Builder.defineMacro("__XCHAL_HAVE_FP_POSTINC", HasFP ? "1" : "0");
57+
Builder.defineMacro("__XCHAL_HAVE_WINDOWED", HasWindowed ? "1" : "0");
58+
Builder.defineMacro("__XCHAL_HAVE_DEBUG", HasDebug ? "1" : "0");
59+
Builder.defineMacro("__XCHAL_HAVE_ABS"); // core arch
60+
Builder.defineMacro("__XCHAL_HAVE_ADDX"); // core arch
61+
Builder.defineMacro("__XCHAL_HAVE_L32R"); // core arch
62+
}

clang/lib/Basic/Targets/Xtensa.h

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
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+
bool HasFP = false;
37+
bool HasWindowed = false;
38+
bool HasBoolean = false;
39+
bool HasHIFI3 = false;
40+
bool HasDensity = false;
41+
bool HasLoop = false;
42+
bool HasSEXT = false;
43+
bool HasNSA = false;
44+
bool HasCLAPMS = false;
45+
bool HasMINMAX = false;
46+
bool HasMul16 = false;
47+
bool HasMul32 = false;
48+
bool HasMul32High = false;
49+
bool HasDiv32 = false;
50+
bool HasMAC16 = false;
51+
bool HasS32C1I = false;
52+
bool HasTHREADPTR = false;
53+
bool HasExtendedL32R = false;
54+
bool HasATOMCTL = false;
55+
bool HasMEMCTL = false;
56+
bool HasDebug = false;
57+
bool HasException = false;
58+
bool HasHighPriInterrupts = false;
59+
bool HasCoprocessor = false;
60+
bool HasInterrupt = false;
61+
bool HasRelocatableVector = false;
62+
bool HasTimerInt = false;
63+
bool HasPRID = false;
64+
bool HasRegionProtection = false;
65+
bool HasMiscSR = false;
66+
67+
public:
68+
XtensaTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
69+
: TargetInfo(Triple) {
70+
BigEndian = false;
71+
NoAsmVariants = true;
72+
LongLongAlign = 64;
73+
SuitableAlign = 32;
74+
DoubleAlign = LongDoubleAlign = 64;
75+
SizeType = UnsignedInt;
76+
PtrDiffType = SignedInt;
77+
IntPtrType = SignedInt;
78+
WCharType = SignedInt;
79+
WIntType = UnsignedInt;
80+
UseZeroLengthBitfieldAlignment = true;
81+
MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32;
82+
resetDataLayout("e-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-n32");
83+
}
84+
85+
void getTargetDefines(const LangOptions &Opts,
86+
MacroBuilder &Builder) const override;
87+
88+
ArrayRef<Builtin::Info> getTargetBuiltins() const override {
89+
return std::nullopt;
90+
}
91+
92+
BuiltinVaListKind getBuiltinVaListKind() const override {
93+
94+
return TargetInfo::XtensaABIBuiltinVaList;
95+
}
96+
97+
std::string_view getClobbers() const override { return ""; }
98+
99+
ArrayRef<const char *> getGCCRegNames() const override {
100+
static const char *const GCCRegNames[] = {
101+
// General register name
102+
"a0", "sp", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "a10",
103+
"a11", "a12", "a13", "a14", "a15",
104+
// Special register name
105+
"sar"};
106+
return llvm::ArrayRef(GCCRegNames);
107+
}
108+
109+
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
110+
return std::nullopt;
111+
}
112+
113+
bool validateAsmConstraint(const char *&Name,
114+
TargetInfo::ConstraintInfo &Info) const override {
115+
switch (*Name) {
116+
default:
117+
return false;
118+
case 'a':
119+
Info.setAllowsRegister();
120+
return true;
121+
}
122+
return false;
123+
}
124+
125+
int getEHDataRegisterNumber(unsigned RegNo) const override {
126+
return (RegNo < 2) ? RegNo : -1;
127+
}
128+
129+
bool isValidCPUName(StringRef Name) const override {
130+
return llvm::StringSwitch<bool>(Name).Case("generic", true).Default(false);
131+
}
132+
133+
bool setCPU(const std::string &Name) override {
134+
CPU = Name;
135+
return isValidCPUName(Name);
136+
}
137+
};
138+
139+
} // namespace targets
140+
} // namespace clang
141+
#endif // LLVM_CLANG_LIB_BASIC_TARGETS_XTENSA_H

clang/lib/Driver/ToolChains/CommonArgs.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,11 @@ std::string tools::getCPUName(const Driver &D, const ArgList &Args,
671671
case llvm::Triple::loongarch32:
672672
case llvm::Triple::loongarch64:
673673
return loongarch::getLoongArchTargetCPU(Args, T);
674+
675+
case llvm::Triple::xtensa:
676+
if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
677+
return A->getValue();
678+
return "";
674679
}
675680
}
676681

0 commit comments

Comments
 (0)