diff --git a/llvm/include/llvm/CodeGen/ValueTypes.h b/llvm/include/llvm/CodeGen/ValueTypes.h index 2a91cdc3ab134..6c9d272f3f2c8 100644 --- a/llvm/include/llvm/CodeGen/ValueTypes.h +++ b/llvm/include/llvm/CodeGen/ValueTypes.h @@ -228,6 +228,11 @@ namespace llvm { return isSimple() ? V.is2048BitVector() : isExtended2048BitVector(); } + /// Return true if this is a capability type. + bool isCheriCapability() const { + return isSimple() ? V.isCheriCapability() : false; + } + /// Return true if this is an overloaded type for TableGen. bool isOverloaded() const { return (V == MVT::iAny || V == MVT::fAny || V == MVT::vAny || diff --git a/llvm/include/llvm/CodeGen/ValueTypes.td b/llvm/include/llvm/CodeGen/ValueTypes.td index b06158d85f510..44edec98d20f3 100644 --- a/llvm/include/llvm/CodeGen/ValueTypes.td +++ b/llvm/include/llvm/CodeGen/ValueTypes.td @@ -28,6 +28,7 @@ class ValueType { // Indicates this VT should be included in the // [FIRST_VALUETYPE,LAST_VALUETYPE] range. bit isNormalValueType = true; + bit isCheriCapability = false; } class VTAny : ValueType<0, value> { @@ -65,6 +66,10 @@ class VTVecTup let isRISCVVecTuple = true; } +class VTCheriCapability : ValueType { + let isCheriCapability = true; +} + defset list ValueTypes = { def OtherVT : ValueType<0, 1> { // "Other" value @@ -357,6 +362,11 @@ def amdgpuBufferStridedPointer : ValueType<192, 252>; def aarch64mfp8 : ValueType<8, 253>; // 8-bit value in FPR (AArch64) +// CHERI capabilities. Pointer-like values that carry additional metadata +// for enforcing safety guarantees on CHERI-enabled targets. +def c64 : VTCheriCapability<64, 254>; // 64-bit CHERI capability value +def c128 : VTCheriCapability<128, 255>; // 128-bit CHERI capability value + let isNormalValueType = false in { def token : ValueType<0, 504>; // TokenTy def MetadataVT : ValueType<0, 505> { // Metadata diff --git a/llvm/include/llvm/CodeGenTypes/MachineValueType.h b/llvm/include/llvm/CodeGenTypes/MachineValueType.h index b8e91a022ec5e..aaf16a65dd685 100644 --- a/llvm/include/llvm/CodeGenTypes/MachineValueType.h +++ b/llvm/include/llvm/CodeGenTypes/MachineValueType.h @@ -178,6 +178,12 @@ namespace llvm { return (isFixedLengthVector() && getFixedSizeInBits() == 2048); } + /// Return true if this is a CHERI capability type. + bool isCheriCapability() const { + return (SimpleTy >= MVT::FIRST_CHERI_CAPABILITY_VALUETYPE) && + (SimpleTy <= MVT::LAST_CHERI_CAPABILITY_VALUETYPE); + } + /// Return true if this is an overloaded type for TableGen. bool isOverloaded() const { switch (SimpleTy) { diff --git a/llvm/lib/CodeGen/ValueTypes.cpp b/llvm/lib/CodeGen/ValueTypes.cpp index 10970b719fcae..0743c92c5b95b 100644 --- a/llvm/lib/CodeGen/ValueTypes.cpp +++ b/llvm/lib/CodeGen/ValueTypes.cpp @@ -176,6 +176,8 @@ std::string EVT::getEVTString() const { return "i" + utostr(getSizeInBits()); if (isFloatingPoint()) return "f" + utostr(getSizeInBits()); + if (isCheriCapability()) + return "c" + utostr(getSizeInBits()); llvm_unreachable("Invalid EVT!"); case MVT::bf16: return "bf16"; case MVT::ppcf128: return "ppcf128"; diff --git a/llvm/utils/TableGen/Basic/VTEmitter.cpp b/llvm/utils/TableGen/Basic/VTEmitter.cpp index 040f37c3a5e1e..c6b4d0b56c02b 100644 --- a/llvm/utils/TableGen/Basic/VTEmitter.cpp +++ b/llvm/utils/TableGen/Basic/VTEmitter.cpp @@ -132,6 +132,7 @@ void VTEmitter::run(raw_ostream &OS) { bool IsVector = VT->getValueAsBit("isVector"); bool IsScalable = VT->getValueAsBit("isScalable"); bool IsRISCVVecTuple = VT->getValueAsBit("isRISCVVecTuple"); + bool IsCheriCapability = VT->getValueAsBit("isCheriCapability"); int64_t NF = VT->getValueAsInt("NF"); bool IsNormalValueType = VT->getValueAsBit("isNormalValueType"); int64_t NElem = IsVector ? VT->getValueAsInt("nElem") : 0; @@ -152,6 +153,7 @@ void VTEmitter::run(raw_ostream &OS) { UpdateVTRange("INTEGER_VALUETYPE", Name, IsInteger && !IsVector); UpdateVTRange("FP_VALUETYPE", Name, IsFP && !IsVector); UpdateVTRange("VALUETYPE", Name, IsNormalValueType); + UpdateVTRange("CHERI_CAPABILITY_VALUETYPE", Name, IsCheriCapability); // clang-format off OS << " GET_VT_ATTR("