forked from OSchip/llvm-project
315 lines
7.4 KiB
C++
315 lines
7.4 KiB
C++
//===--- CSKY.cpp - Implement CSKY target feature support -----------------===//
|
|
//
|
|
// 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 CSKY TargetInfo objects.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "CSKY.h"
|
|
|
|
using namespace clang;
|
|
using namespace clang::targets;
|
|
|
|
bool CSKYTargetInfo::isValidCPUName(StringRef Name) const {
|
|
return llvm::CSKY::parseCPUArch(Name) != llvm::CSKY::ArchKind::INVALID;
|
|
}
|
|
|
|
bool CSKYTargetInfo::setCPU(const std::string &Name) {
|
|
llvm::CSKY::ArchKind archKind = llvm::CSKY::parseCPUArch(Name);
|
|
bool isValid = (archKind != llvm::CSKY::ArchKind::INVALID);
|
|
|
|
if (isValid) {
|
|
CPU = Name;
|
|
Arch = archKind;
|
|
}
|
|
|
|
return isValid;
|
|
}
|
|
|
|
void CSKYTargetInfo::getTargetDefines(const LangOptions &Opts,
|
|
MacroBuilder &Builder) const {
|
|
Builder.defineMacro("__ELF__");
|
|
Builder.defineMacro("__csky__", "2");
|
|
Builder.defineMacro("__CSKY__", "2");
|
|
Builder.defineMacro("__ckcore__", "2");
|
|
Builder.defineMacro("__CKCORE__", "2");
|
|
|
|
Builder.defineMacro("__CSKYABI__", ABI == "abiv2" ? "2" : "1");
|
|
Builder.defineMacro("__cskyabi__", ABI == "abiv2" ? "2" : "1");
|
|
|
|
StringRef ArchName = "ck810";
|
|
StringRef CPUName = "ck810";
|
|
|
|
if (Arch != llvm::CSKY::ArchKind::INVALID) {
|
|
ArchName = llvm::CSKY::getArchName(Arch);
|
|
CPUName = CPU;
|
|
}
|
|
|
|
Builder.defineMacro("__" + ArchName.upper() + "__");
|
|
Builder.defineMacro("__" + ArchName.lower() + "__");
|
|
Builder.defineMacro("__" + CPUName.upper() + "__");
|
|
Builder.defineMacro("__" + CPUName.lower() + "__");
|
|
|
|
// TODO: Add support for BE if BE was supported later
|
|
StringRef endian = "__cskyLE__";
|
|
|
|
Builder.defineMacro(endian);
|
|
Builder.defineMacro(endian.upper());
|
|
Builder.defineMacro(endian.lower());
|
|
|
|
if (DSPV2) {
|
|
StringRef dspv2 = "__CSKY_DSPV2__";
|
|
Builder.defineMacro(dspv2);
|
|
Builder.defineMacro(dspv2.lower());
|
|
}
|
|
|
|
if (VDSPV2) {
|
|
StringRef vdspv2 = "__CSKY_VDSPV2__";
|
|
Builder.defineMacro(vdspv2);
|
|
Builder.defineMacro(vdspv2.lower());
|
|
|
|
if (HardFloat) {
|
|
StringRef vdspv2_f = "__CSKY_VDSPV2_F__";
|
|
Builder.defineMacro(vdspv2_f);
|
|
Builder.defineMacro(vdspv2_f.lower());
|
|
}
|
|
}
|
|
if (VDSPV1) {
|
|
StringRef vdspv1_64 = "__CSKY_VDSP64__";
|
|
StringRef vdspv1_128 = "__CSKY_VDSP128__";
|
|
|
|
Builder.defineMacro(vdspv1_64);
|
|
Builder.defineMacro(vdspv1_64.lower());
|
|
Builder.defineMacro(vdspv1_128);
|
|
Builder.defineMacro(vdspv1_128.lower());
|
|
}
|
|
if (is3E3R1) {
|
|
StringRef is3e3r1 = "__CSKY_3E3R1__";
|
|
Builder.defineMacro(is3e3r1);
|
|
Builder.defineMacro(is3e3r1.lower());
|
|
}
|
|
}
|
|
|
|
bool CSKYTargetInfo::hasFeature(StringRef Feature) const {
|
|
return llvm::StringSwitch<bool>(Feature)
|
|
.Case("hard-float", HardFloat)
|
|
.Case("hard-float-abi", HardFloatABI)
|
|
.Case("fpuv2_sf", FPUV2_SF)
|
|
.Case("fpuv2_df", FPUV2_DF)
|
|
.Case("fpuv3_sf", FPUV3_SF)
|
|
.Case("fpuv3_df", FPUV3_DF)
|
|
.Case("vdspv2", VDSPV2)
|
|
.Case("dspv2", DSPV2)
|
|
.Case("vdspv1", VDSPV1)
|
|
.Case("3e3r1", is3E3R1)
|
|
.Default(false);
|
|
}
|
|
|
|
bool CSKYTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
|
|
DiagnosticsEngine &Diags) {
|
|
for (const auto &Feature : Features) {
|
|
if (Feature == "+hard-float")
|
|
HardFloat = true;
|
|
if (Feature == "+hard-float-abi")
|
|
HardFloatABI = true;
|
|
if (Feature == "+fpuv2_sf")
|
|
FPUV2_SF = true;
|
|
if (Feature == "+fpuv2_df")
|
|
FPUV2_DF = true;
|
|
if (Feature == "+fpuv3_sf")
|
|
FPUV3_SF = true;
|
|
if (Feature == "+fpuv3_df")
|
|
FPUV3_DF = true;
|
|
if (Feature == "+vdspv2")
|
|
VDSPV2 = true;
|
|
if (Feature == "+dspv2")
|
|
DSPV2 = true;
|
|
if (Feature == "+vdspv1")
|
|
VDSPV1 = true;
|
|
if (Feature == "+3e3r1")
|
|
is3E3R1 = true;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
ArrayRef<Builtin::Info> CSKYTargetInfo::getTargetBuiltins() const {
|
|
return ArrayRef<Builtin::Info>();
|
|
}
|
|
|
|
ArrayRef<const char *> CSKYTargetInfo::getGCCRegNames() const {
|
|
static const char *const GCCRegNames[] = {
|
|
// Integer registers
|
|
"r0",
|
|
"r1",
|
|
"r2",
|
|
"r3",
|
|
"r4",
|
|
"r5",
|
|
"r6",
|
|
"r7",
|
|
"r8",
|
|
"r9",
|
|
"r10",
|
|
"r11",
|
|
"r12",
|
|
"r13",
|
|
"r14",
|
|
"r15",
|
|
"r16",
|
|
"r17",
|
|
"r18",
|
|
"r19",
|
|
"r20",
|
|
"r21",
|
|
"r22",
|
|
"r23",
|
|
"r24",
|
|
"r25",
|
|
"r26",
|
|
"r27",
|
|
"r28",
|
|
"r29",
|
|
"r30",
|
|
"r31",
|
|
|
|
// Floating point registers
|
|
"fr0",
|
|
"fr1",
|
|
"fr2",
|
|
"fr3",
|
|
"fr4",
|
|
"fr5",
|
|
"fr6",
|
|
"fr7",
|
|
"fr8",
|
|
"fr9",
|
|
"fr10",
|
|
"fr11",
|
|
"fr12",
|
|
"fr13",
|
|
"fr14",
|
|
"fr15",
|
|
"fr16",
|
|
"fr17",
|
|
"fr18",
|
|
"fr19",
|
|
"fr20",
|
|
"fr21",
|
|
"fr22",
|
|
"fr23",
|
|
"fr24",
|
|
"fr25",
|
|
"fr26",
|
|
"fr27",
|
|
"fr28",
|
|
"fr29",
|
|
"fr30",
|
|
"fr31",
|
|
|
|
};
|
|
return llvm::makeArrayRef(GCCRegNames);
|
|
}
|
|
|
|
ArrayRef<TargetInfo::GCCRegAlias> CSKYTargetInfo::getGCCRegAliases() const {
|
|
static const TargetInfo::GCCRegAlias GCCRegAliases[] = {
|
|
{{"a0"}, "r0"},
|
|
{{"a1"}, "r1"},
|
|
{{"a2"}, "r2"},
|
|
{{"a3"}, "r3"},
|
|
{{"l0"}, "r4"},
|
|
{{"l1"}, "r5"},
|
|
{{"l2"}, "r6"},
|
|
{{"l3"}, "r7"},
|
|
{{"l4"}, "r8"},
|
|
{{"l5"}, "r9"},
|
|
{{"l6"}, "r10"},
|
|
{{"l7"}, "r11"},
|
|
{{"t0"}, "r12"},
|
|
{{"t1"}, "r13"},
|
|
{{"sp"}, "r14"},
|
|
{{"lr"}, "r15"},
|
|
{{"l8"}, "r16"},
|
|
{{"l9"}, "r17"},
|
|
{{"t2"}, "r18"},
|
|
{{"t3"}, "r19"},
|
|
{{"t4"}, "r20"},
|
|
{{"t5"}, "r21"},
|
|
{{"t6"}, "r22"},
|
|
{{"t7", "fp"}, "r23"},
|
|
{{"t8", "top"}, "r24"},
|
|
{{"t9", "bsp"}, "r25"},
|
|
{{"r26"}, "r26"},
|
|
{{"r27"}, "r27"},
|
|
{{"gb", "rgb", "rdb"}, "r28"},
|
|
{{"tb", "rtb"}, "r29"},
|
|
{{"svbr"}, "r30"},
|
|
{{"tls"}, "r31"},
|
|
|
|
{{"vr0"}, "fr0"},
|
|
{{"vr1"}, "fr1"},
|
|
{{"vr2"}, "fr2"},
|
|
{{"vr3"}, "fr3"},
|
|
{{"vr4"}, "fr4"},
|
|
{{"vr5"}, "fr5"},
|
|
{{"vr6"}, "fr6"},
|
|
{{"vr7"}, "fr7"},
|
|
{{"vr8"}, "fr8"},
|
|
{{"vr9"}, "fr9"},
|
|
{{"vr10"}, "fr10"},
|
|
{{"vr11"}, "fr11"},
|
|
{{"vr12"}, "fr12"},
|
|
{{"vr13"}, "fr13"},
|
|
{{"vr14"}, "fr14"},
|
|
{{"vr15"}, "fr15"},
|
|
{{"vr16"}, "fr16"},
|
|
{{"vr17"}, "fr17"},
|
|
{{"vr18"}, "fr18"},
|
|
{{"vr19"}, "fr19"},
|
|
{{"vr20"}, "fr20"},
|
|
{{"vr21"}, "fr21"},
|
|
{{"vr22"}, "fr22"},
|
|
{{"vr23"}, "fr23"},
|
|
{{"vr24"}, "fr24"},
|
|
{{"vr25"}, "fr25"},
|
|
{{"vr26"}, "fr26"},
|
|
{{"vr27"}, "fr27"},
|
|
{{"vr28"}, "fr28"},
|
|
{{"vr29"}, "fr29"},
|
|
{{"vr30"}, "fr30"},
|
|
{{"vr31"}, "fr31"},
|
|
|
|
};
|
|
return llvm::makeArrayRef(GCCRegAliases);
|
|
}
|
|
|
|
bool CSKYTargetInfo::validateAsmConstraint(
|
|
const char *&Name, TargetInfo::ConstraintInfo &Info) const {
|
|
switch (*Name) {
|
|
default:
|
|
return false;
|
|
case 'a':
|
|
case 'b':
|
|
case 'c':
|
|
case 'y':
|
|
case 'l':
|
|
case 'h':
|
|
case 'w':
|
|
case 'v': // A floating-point and vector register.
|
|
case 'z':
|
|
Info.setAllowsRegister();
|
|
return true;
|
|
}
|
|
}
|
|
|
|
unsigned CSKYTargetInfo::getMinGlobalAlign(uint64_t Size) const {
|
|
if (Size >= 32)
|
|
return 32;
|
|
return 0;
|
|
}
|