Skip to content

Commit 48da848

Browse files
authored
[Xtensa] Add esp32/esp8266 cpus implementation. (#152409)
Add Xtensa esp32 and esp8266 cpus. Implement target parser to recognise Xtensa hardware features.
1 parent c3bf73b commit 48da848

File tree

10 files changed

+319
-3
lines changed

10 files changed

+319
-3
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
//===- XtensaTargetParser.def - Xtensa target parsing defines ---*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file provides defines to build up the Xtensa target parser's logic.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef XTENSA_FEATURE
14+
#define XTENSA_FEATURE(ID, STR)
15+
#endif
16+
17+
XTENSA_FEATURE(XF_DENSITY, "density")
18+
XTENSA_FEATURE(XF_FP, "fp")
19+
XTENSA_FEATURE(XF_WINDOWED, "windowed")
20+
XTENSA_FEATURE(XF_BOOLEAN, "bool")
21+
XTENSA_FEATURE(XF_LOOP, "loop")
22+
XTENSA_FEATURE(XF_SEXT, "sext")
23+
XTENSA_FEATURE(XF_NSA, "nsa")
24+
XTENSA_FEATURE(XF_CLAMPS, "clamps")
25+
XTENSA_FEATURE(XF_MINMAX, "minmax")
26+
XTENSA_FEATURE(XF_MAC16, "mac16")
27+
XTENSA_FEATURE(XF_MUL32, "mul32")
28+
XTENSA_FEATURE(XF_MUL32HIGH, "mul32high")
29+
XTENSA_FEATURE(XF_DIV32, "div32")
30+
XTENSA_FEATURE(XF_MUL16, "mul16")
31+
XTENSA_FEATURE(XF_DFPACCEL, "dfpaccel")
32+
XTENSA_FEATURE(XF_S32C1I, "s32c1i")
33+
XTENSA_FEATURE(XF_THREADPTR, "threadptr")
34+
XTENSA_FEATURE(XF_EXTENDEDL32R, "extendedl32r")
35+
XTENSA_FEATURE(XF_DATACACHE, "dcache")
36+
XTENSA_FEATURE(XF_DEBUG, "debug")
37+
XTENSA_FEATURE(XF_EXCEPTION, "exception")
38+
XTENSA_FEATURE(XF_HIGHPRIINTERRUPTS, "highpriinterrupts")
39+
XTENSA_FEATURE(XF_HIGHPRIINTERRUPTSLEVEL3, "highpriinterruptslevel3")
40+
XTENSA_FEATURE(XF_HIGHPRIINTERRUPTSLEVEL4, "highpriinterruptslevel4")
41+
XTENSA_FEATURE(XF_HIGHPRIINTERRUPTSLEVEL5, "highpriinterruptslevel5")
42+
XTENSA_FEATURE(XF_HIGHPRIINTERRUPTSLEVEL6, "highpriinterruptslevel6")
43+
XTENSA_FEATURE(XF_HIGHPRIINTERRUPTSLEVEL7, "highpriinterruptslevel7")
44+
XTENSA_FEATURE(XF_COPROCESSOR, "coprocessor")
45+
XTENSA_FEATURE(XF_INTERRUPT, "interrupt")
46+
XTENSA_FEATURE(XF_RVECTOR, "rvector")
47+
XTENSA_FEATURE(XF_TIMERS1, "timers1")
48+
XTENSA_FEATURE(XF_TIMERS2, "timers2")
49+
XTENSA_FEATURE(XF_TIMERS3, "timers3")
50+
XTENSA_FEATURE(XF_PRID, "prid")
51+
XTENSA_FEATURE(XF_REGPROTECT, "regprotect")
52+
XTENSA_FEATURE(XF_MISCSR, "miscsr")
53+
54+
#undef XTENSA_FEATURE
55+
56+
#ifndef XTENSA_CPU
57+
#define XTENSA_CPU(ENUM, NAME, FEATURES)
58+
#endif
59+
60+
XTENSA_CPU(INVALID, {"invalid"}, XF_INVALID)
61+
XTENSA_CPU(GENERIC, {"generic"}, XF_NONE)
62+
XTENSA_CPU(ESP8266, {"esp8266"},
63+
(XF_DENSITY | XF_NSA | XF_MUL16 | XF_MUL32 | XF_EXTENDEDL32R | XF_DEBUG | XF_EXCEPTION |
64+
XF_HIGHPRIINTERRUPTS | XF_HIGHPRIINTERRUPTSLEVEL3 | XF_INTERRUPT | XF_RVECTOR | XF_TIMERS1 |
65+
XF_REGPROTECT | XF_PRID))
66+
XTENSA_CPU(ESP32, {"esp32"},
67+
(XF_DENSITY | XF_FP | XF_LOOP | XF_MAC16 | XF_WINDOWED | XF_BOOLEAN | XF_SEXT | XF_NSA |
68+
XF_CLAMPS | XF_MINMAX | XF_MUL32 | XF_MUL32HIGH | XF_MUL16 | XF_DFPACCEL | XF_S32C1I |
69+
XF_THREADPTR | XF_DIV32 | XF_DATACACHE | XF_DEBUG | XF_EXCEPTION | XF_HIGHPRIINTERRUPTS |
70+
XF_HIGHPRIINTERRUPTSLEVEL7 | XF_COPROCESSOR | XF_INTERRUPT | XF_RVECTOR | XF_TIMERS3 | XF_PRID |
71+
XF_REGPROTECT | XF_MISCSR))
72+
73+
#undef XTENSA_CPU
74+
75+
#ifndef XTENSA_CPU_ALIAS
76+
#define XTENSA_CPU_ALIAS(NAME, ALTNMAME)
77+
#endif
78+
79+
#undef XTENSA_CPU_ALIAS
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
///
9+
/// \file
10+
/// This file implements a target parser to recognise Xtensa hardware features.
11+
///
12+
//===----------------------------------------------------------------------===//
13+
14+
#ifndef LLVM_TARGETPARSER_XTENSATARGETPARSER_H
15+
#define LLVM_TARGETPARSER_XTENSATARGETPARSER_H
16+
17+
#include "llvm/TargetParser/Triple.h"
18+
#include <vector>
19+
20+
namespace llvm {
21+
class StringRef;
22+
23+
namespace Xtensa {
24+
25+
enum CPUKind : unsigned {
26+
#define XTENSA_CPU(ENUM, NAME, FEATURES) CK_##ENUM,
27+
#include "XtensaTargetParser.def"
28+
};
29+
30+
enum XtensaFeatureKind : uint64_t {
31+
XF_INVALID = 0,
32+
XF_NONE = 1,
33+
XF_FP = 1 << 1,
34+
XF_WINDOWED = 1 << 2,
35+
XF_BOOLEAN = 1 << 3,
36+
XF_DENSITY = 1 << 4,
37+
XF_LOOP = 1 << 5,
38+
XF_SEXT = 1 << 6,
39+
XF_NSA = 1 << 7,
40+
XF_CLAMPS = 1 << 8,
41+
XF_MINMAX = 1 << 9,
42+
XF_MAC16 = 1 << 10,
43+
XF_MUL32 = 1 << 11,
44+
XF_MUL32HIGH = 1 << 12,
45+
XF_DIV32 = 1 << 13,
46+
XF_MUL16 = 1 << 14,
47+
XF_DFPACCEL = 1 << 15,
48+
XF_S32C1I = 1 << 16,
49+
XF_THREADPTR = 1 << 17,
50+
XF_EXTENDEDL32R = 1 << 18,
51+
XF_DATACACHE = 1 << 19,
52+
XF_DEBUG = 1 << 20,
53+
XF_EXCEPTION = 1 << 21,
54+
XF_HIGHPRIINTERRUPTS = 1 << 22,
55+
XF_HIGHPRIINTERRUPTSLEVEL3 = 1 << 23,
56+
XF_HIGHPRIINTERRUPTSLEVEL4 = 1 << 24,
57+
XF_HIGHPRIINTERRUPTSLEVEL5 = 1 << 25,
58+
XF_HIGHPRIINTERRUPTSLEVEL6 = 1 << 26,
59+
XF_HIGHPRIINTERRUPTSLEVEL7 = 1 << 27,
60+
XF_COPROCESSOR = 1 << 28,
61+
XF_INTERRUPT = 1 << 29,
62+
XF_RVECTOR = 1 << 30,
63+
XF_TIMERS1 = 1ULL << 31,
64+
XF_TIMERS2 = 1ULL << 32,
65+
XF_TIMERS3 = 1ULL << 33,
66+
XF_PRID = 1ULL << 34,
67+
XF_REGPROTECT = 1ULL << 35,
68+
XF_MISCSR = 1ULL << 36
69+
};
70+
71+
CPUKind parseCPUKind(StringRef CPU);
72+
StringRef getBaseName(StringRef CPU);
73+
void getCPUFeatures(StringRef CPU, SmallVectorImpl<StringRef> &Features);
74+
void fillValidCPUList(SmallVectorImpl<StringRef> &Values);
75+
76+
} // namespace Xtensa
77+
} // namespace llvm
78+
79+
#endif // LLVM_SUPPORT_XTENSATARGETPARSER_H

llvm/include/module.modulemap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,7 @@ module LLVM_Utils {
415415
textual header "llvm/TargetParser/X86TargetParser.def"
416416
textual header "llvm/TargetParser/LoongArchTargetParser.def"
417417
textual header "llvm/TargetParser/PPCTargetParser.def"
418+
textual header "llvm/TargetParser/XtensaTargetParser.def"
418419
}
419420

420421
// This part of the module is usable from both C and C++ code.

llvm/lib/Target/Xtensa/Xtensa.td

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,8 @@ include "XtensaFeatures.td"
2323
//===----------------------------------------------------------------------===//
2424
// Xtensa supported processors.
2525
//===----------------------------------------------------------------------===//
26-
class Proc<string Name, list<SubtargetFeature> Features>
27-
: Processor<Name, NoItineraries, Features>;
2826

29-
def : Proc<"generic", []>;
27+
include "XtensaProcessors.td"
3028

3129
//===----------------------------------------------------------------------===//
3230
// Register File Description
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//===- XtensaProcessors.td - Xtensa Processors -------------*- tablegen -*-===//
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+
//===----------------------------------------------------------------------===//
12+
// Xtensa supported processors.
13+
//===----------------------------------------------------------------------===//
14+
class Proc<string Name, list<SubtargetFeature> Features>
15+
: Processor<Name, NoItineraries, Features>;
16+
17+
def : Proc<"generic", []>;
18+
19+
def : Proc<"esp32", [FeatureDensity, FeatureSingleFloat, FeatureLoop, FeatureMAC16, FeatureWindowed, FeatureBoolean, FeatureSEXT,
20+
FeatureNSA, FeatureMul16, FeatureMul32, FeatureMul32High, FeatureDFPAccel, FeatureS32C1I, FeatureTHREADPTR, FeatureDiv32,
21+
FeatureDebug, FeatureException, FeatureHighPriInterrupts, FeatureHighPriInterruptsLevel7, FeatureCoprocessor,
22+
FeatureInterrupt, FeatureDataCache, FeatureRelocatableVector, FeatureTimers3, FeaturePRID, FeatureRegionProtection, FeatureMiscSR,
23+
FeatureMINMAX, FeatureCLAMPS]>;
24+
25+
def : Proc<"esp8266", [FeatureDensity, FeatureNSA, FeatureMul16, FeatureMul32, FeatureExtendedL32R, FeatureDebug, FeatureException,
26+
FeatureHighPriInterrupts, FeatureHighPriInterruptsLevel3, FeatureInterrupt, FeatureRelocatableVector, FeatureTimers1,
27+
FeatureRegionProtection, FeaturePRID]>;

llvm/lib/TargetParser/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ add_llvm_component_library(LLVMTargetParser
2727
TargetParser.cpp
2828
Triple.cpp
2929
X86TargetParser.cpp
30+
XtensaTargetParser.cpp
3031

3132
ADDITIONAL_HEADER_DIRS
3233
Unix
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
//==-- XtensaTargetParser - Parser for Xtensa features ------------*- C++ -*-=//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file implements a target parser to recognise Xtensa hardware features
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "llvm/TargetParser/XtensaTargetParser.h"
14+
#include "llvm/ADT/STLExtras.h"
15+
#include "llvm/ADT/StringSwitch.h"
16+
17+
namespace llvm {
18+
19+
namespace Xtensa {
20+
struct CPUInfo {
21+
StringLiteral Name;
22+
CPUKind Kind;
23+
uint64_t Features;
24+
};
25+
26+
struct FeatureName {
27+
uint64_t ID;
28+
const char *NameCStr;
29+
size_t NameLength;
30+
31+
StringRef getName() const { return StringRef(NameCStr, NameLength); }
32+
};
33+
34+
const FeatureName XtensaFeatureNames[] = {
35+
#define XTENSA_FEATURE(ID, NAME) {ID, "+" NAME, sizeof(NAME)},
36+
#include "llvm/TargetParser/XtensaTargetParser.def"
37+
};
38+
39+
constexpr CPUInfo XtensaCPUInfo[] = {
40+
#define XTENSA_CPU(ENUM, NAME, FEATURES) {NAME, CK_##ENUM, FEATURES},
41+
#include "llvm/TargetParser/XtensaTargetParser.def"
42+
};
43+
44+
StringRef getBaseName(StringRef CPU) {
45+
return llvm::StringSwitch<StringRef>(CPU)
46+
#define XTENSA_CPU_ALIAS(NAME, ANAME) .Case(ANAME, NAME)
47+
#include "llvm/TargetParser/XtensaTargetParser.def"
48+
.Default(CPU);
49+
}
50+
51+
StringRef getAliasName(StringRef CPU) {
52+
return llvm::StringSwitch<StringRef>(CPU)
53+
#define XTENSA_CPU_ALIAS(NAME, ANAME) .Case(NAME, ANAME)
54+
#include "llvm/TargetParser/XtensaTargetParser.def"
55+
.Default(CPU);
56+
}
57+
58+
CPUKind parseCPUKind(StringRef CPU) {
59+
CPU = getBaseName(CPU);
60+
return llvm::StringSwitch<CPUKind>(CPU)
61+
#define XTENSA_CPU(ENUM, NAME, FEATURES) .Case(NAME, CK_##ENUM)
62+
#include "llvm/TargetParser/XtensaTargetParser.def"
63+
.Default(CK_INVALID);
64+
}
65+
66+
// Get all features for the CPU
67+
void getCPUFeatures(StringRef CPU, std::vector<StringRef> &Features) {
68+
CPU = getBaseName(CPU);
69+
auto I = llvm::find_if(XtensaCPUInfo,
70+
[&](const CPUInfo &CI) { return CI.Name == CPU; });
71+
assert(I != std::end(XtensaCPUInfo) && "CPU not found!");
72+
uint64_t Bits = I->Features;
73+
74+
for (const auto &F : XtensaFeatureNames) {
75+
if ((Bits & F.ID) == F.ID)
76+
Features.push_back(F.getName());
77+
}
78+
}
79+
80+
// Find all valid CPUs
81+
void fillValidCPUList(std::vector<StringRef> &Values) {
82+
for (const auto &C : XtensaCPUInfo) {
83+
if (C.Kind != CK_INVALID) {
84+
Values.emplace_back(C.Name);
85+
StringRef Name = getAliasName(C.Name);
86+
if (Name != C.Name)
87+
Values.emplace_back(Name);
88+
}
89+
}
90+
}
91+
92+
} // namespace Xtensa
93+
} // namespace llvm
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
; RUN: llc < %s --mtriple=xtensa --mcpu=invalid 2>&1 | FileCheck %s
2+
3+
; CHECK: {{.*}} is not a recognized processor for this target
4+
5+
define void @f() {
6+
ret void
7+
}
8+

llvm/test/CodeGen/Xtensa/cpus.ll

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
2+
; This tests that llc accepts all valid Xtensa CPUs
3+
4+
; RUN: llc < %s --mtriple=xtensa --mcpu=esp8266 2>&1 | FileCheck -check-prefix=XTENSA-ESP8266 %s
5+
; RUN: llc < %s --mtriple=xtensa --mcpu=esp32 2>&1 | FileCheck -check-prefix=XTENSA-ESP32 %s
6+
; RUN: llc < %s --mtriple=xtensa --mcpu=generic 2>&1 | FileCheck -check-prefix=XTENSA-GENERIC %s
7+
8+
define i32 @f(i32 %z) {
9+
; XTENSA-ESP8266-LABEL: f:
10+
; XTENSA-ESP8266: .cfi_startproc
11+
; XTENSA-ESP8266-NEXT: # %bb.0:
12+
; XTENSA-ESP8266-NEXT: movi a2, 0
13+
; XTENSA-ESP8266-NEXT: ret
14+
;
15+
; XTENSA-ESP32-LABEL: f:
16+
; XTENSA-ESP32: .cfi_startproc
17+
; XTENSA-ESP32-NEXT: # %bb.0:
18+
; XTENSA-ESP32-NEXT: entry a1, 32
19+
; XTENSA-ESP32-NEXT: .cfi_def_cfa_offset 32
20+
; XTENSA-ESP32-NEXT: movi a2, 0
21+
; XTENSA-ESP32-NEXT: retw.n
22+
;
23+
; XTENSA-GENERIC-LABEL: f:
24+
; XTENSA-GENERIC: .cfi_startproc
25+
; XTENSA-GENERIC-NEXT: # %bb.0:
26+
; XTENSA-GENERIC-NEXT: movi a2, 0
27+
; XTENSA-GENERIC-NEXT: ret
28+
ret i32 0
29+
}

llvm/utils/gn/secondary/llvm/lib/TargetParser/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,6 @@ static_library("TargetParser") {
2020
"TargetParser.cpp",
2121
"Triple.cpp",
2222
"X86TargetParser.cpp",
23+
"XtensaTargetParser.cpp",
2324
]
2425
}

0 commit comments

Comments
 (0)