Hsiangkai Wang 766ee1096f [Clang][RISCV] Define RISC-V V builtin types
Add the types for the RISC-V V extension builtins.

These types will be used by the RISC-V V intrinsics which require
types of the form <vscale x 1 x i64>(LMUL=1 element size=64) or
<vscale x 4 x i32>(LMUL=2 element size=32), etc. The vector_size
attribute does not work for us as it doesn't create a scalable
vector type. We want these types to be opaque and have no operators
defined for them. We want them to be sizeless. This makes them
similar to the ARM SVE builtin types. But we will have quite a bit
more types. This patch adds around 60. Later patches will add
another 230 or so types representing tuples of these types similar
to the x2/x3/x4 types in ARM SVE. But with extra complexity that
these types are combined with the LMUL concept that is unique to
RISCV.

For more background see this RFC
http://lists.llvm.org/pipermail/llvm-dev/2020-October/145850.html

Authored-by: Roger Ferrer Ibanez <roger.ferrer@bsc.es>
Co-Authored-by: Hsiangkai Wang <kai.wang@sifive.com>

Differential Revision: https://reviews.llvm.org/D92715
2021-02-18 10:17:31 +08:00

167 lines
4.7 KiB
C++

//===--- RISCV.h - Declare RISCV target feature support ---------*- C++ -*-===//
//
// 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 RISCV TargetInfo objects.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_RISCV_H
#define LLVM_CLANG_LIB_BASIC_TARGETS_RISCV_H
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/Compiler.h"
namespace clang {
namespace targets {
// RISC-V Target
class RISCVTargetInfo : public TargetInfo {
protected:
std::string ABI, CPU;
bool HasM = false;
bool HasA = false;
bool HasF = false;
bool HasD = false;
bool HasC = false;
bool HasB = false;
bool HasV = false;
bool HasZba = false;
bool HasZbb = false;
bool HasZbc = false;
bool HasZbe = false;
bool HasZbf = false;
bool HasZbm = false;
bool HasZbp = false;
bool HasZbproposedc = false;
bool HasZbr = false;
bool HasZbs = false;
bool HasZbt = false;
bool HasZfh = false;
bool HasZvamo = false;
bool HasZvlsseg = false;
public:
RISCVTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
: TargetInfo(Triple) {
LongDoubleWidth = 128;
LongDoubleAlign = 128;
LongDoubleFormat = &llvm::APFloat::IEEEquad();
SuitableAlign = 128;
WCharType = SignedInt;
WIntType = UnsignedInt;
HasRISCVVTypes = true;
}
bool setCPU(const std::string &Name) override {
if (!isValidCPUName(Name))
return false;
CPU = Name;
return true;
}
StringRef getABI() const override { return ABI; }
void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override;
ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; }
BuiltinVaListKind getBuiltinVaListKind() const override {
return TargetInfo::VoidPtrBuiltinVaList;
}
const char *getClobbers() const override { return ""; }
ArrayRef<const char *> getGCCRegNames() const override;
int getEHDataRegisterNumber(unsigned RegNo) const override {
if (RegNo == 0)
return 10;
else if (RegNo == 1)
return 11;
else
return -1;
}
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
bool validateAsmConstraint(const char *&Name,
TargetInfo::ConstraintInfo &Info) const override;
bool hasFeature(StringRef Feature) const override;
bool handleTargetFeatures(std::vector<std::string> &Features,
DiagnosticsEngine &Diags) override;
bool hasExtIntType() const override { return true; }
};
class LLVM_LIBRARY_VISIBILITY RISCV32TargetInfo : public RISCVTargetInfo {
public:
RISCV32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
: RISCVTargetInfo(Triple, Opts) {
IntPtrType = SignedInt;
PtrDiffType = SignedInt;
SizeType = UnsignedInt;
resetDataLayout("e-m:e-p:32:32-i64:64-n32-S128");
}
bool setABI(const std::string &Name) override {
if (Name == "ilp32" || Name == "ilp32f" || Name == "ilp32d") {
ABI = Name;
return true;
}
return false;
}
bool isValidCPUName(StringRef Name) const override;
void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
bool isValidTuneCPUName(StringRef Name) const override;
void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const override;
void setMaxAtomicWidth() override {
MaxAtomicPromoteWidth = 128;
if (HasA)
MaxAtomicInlineWidth = 32;
}
};
class LLVM_LIBRARY_VISIBILITY RISCV64TargetInfo : public RISCVTargetInfo {
public:
RISCV64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
: RISCVTargetInfo(Triple, Opts) {
LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
IntMaxType = Int64Type = SignedLong;
resetDataLayout("e-m:e-p:64:64-i64:64-i128:128-n64-S128");
}
bool setABI(const std::string &Name) override {
if (Name == "lp64" || Name == "lp64f" || Name == "lp64d") {
ABI = Name;
return true;
}
return false;
}
bool isValidCPUName(StringRef Name) const override;
void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
bool isValidTuneCPUName(StringRef Name) const override;
void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const override;
void setMaxAtomicWidth() override {
MaxAtomicPromoteWidth = 128;
if (HasA)
MaxAtomicInlineWidth = 64;
}
};
} // namespace targets
} // namespace clang
#endif // LLVM_CLANG_LIB_BASIC_TARGETS_RISCV_H