LLVM 23.0.0git
CHERICapabilityFormat.cpp
Go to the documentation of this file.
1//===- CHERICapabilityFormat.cpp ------------------------------------------===//
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
10#include "llvm/ADT/bit.h"
11
12namespace llvm {
13
14template <typename Derived, typename AddressType>
16 AddressType Length) {
17 return Align((~Derived::getAlignmentMask(Length) + 1) & AddressMask);
18}
19
20template <typename Derived, typename AddressType>
21AddressType
23 AddressType Length) {
24 AddressType Mask = Derived::getAlignmentMask(Length);
25 return (Length + ~Mask) & Mask;
26}
27
28template <typename AddressType, unsigned MW, unsigned MAX_E>
29AddressType
31 static constexpr unsigned int IE_TAKE_BITS = 3;
32
33 if (Length == 0)
35
36 // Extract bits that overflow the uncompressed mantissa window.
37 uint64_t Slice = static_cast<uint64_t>(Length) >> (MW - 1);
38 unsigned int E = 64 - llvm::countl_zero(Slice);
39 // We use internal exponent if length overflows OR the denormal boundary
40 // bit is set.
41 bool IE = (E != 0) || ((static_cast<uint64_t>(Length) >> (MW - 2)) & 1);
42 // Include bits used by the internal exponent for the shift value.
43 unsigned int Eprime = IE ? (E + IE_TAKE_BITS) : 0;
44
45 assert(E <= MAX_E && "Raw exponent exceeds architecture maximum");
46 assert(Eprime <= sizeof(AddressType) * 8 &&
47 "Shift amount exceeds integer width");
48
49 // Left-shift ~0 to mask out the lost precision bits
50 return RVYCapabilityFormat::AddressMask << Eprime;
51}
52
54 uint32_t>;
56 uint64_t>;
59
61 // Per section 7.13.4 and table 7.4 in the v1.0 CHERIoT specification.
62 constexpr uint32_t NINE_SET_BITS = 511;
63 uint32_t E;
64 if (Length > NINE_SET_BITS << 14)
65 E = 24;
66 else {
67 E = Length > NINE_SET_BITS ? 32 - llvm::countl_zero(Length) - 9 : 0;
68 if (Length > NINE_SET_BITS << E)
69 ++E;
70 assert(E <= 14 && "CHERIoT capabilities cannot encode E between 14 and 24");
71 }
73}
74
76
77} // namespace llvm
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file implements the C++20 <bit> header.
This is an optimization pass for GlobalISel generic memory operations.
@ Length
Definition DWP.cpp:558
int countl_zero(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
Definition bit.h:263
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
static LLVM_ABI Align getRequiredAlignment(AddressType Length)
Returns the required alignment for an allocation of size Length.
static LLVM_ABI AddressType getRepresentableLength(AddressType Length)
Returns Length rounded up to the nearest representable allocation length.
static constexpr AddressType AddressMask
static LLVM_ABI uint32_t getAlignmentMask(uint32_t Length)
static LLVM_ABI AddressType getAlignmentMask(uint64_t Length)