13#ifndef LLVM_SUPPORT_ENDIAN_H
14#define LLVM_SUPPORT_ENDIAN_H
35template<
class T,
int alignment>
37 enum {
value = alignment == 0 ?
alignof(
T) : alignment };
48template <
typename value_type>
56template <
typename value_type, endianness endian>
62template <
typename value_type, std::
size_t alignment = unaligned>
70 return byte_swap<value_type>(ret,
endian);
73template <
typename value_type, endianness endian, std::
size_t alignment>
74[[nodiscard]]
inline value_type
read(
const void *memory) {
75 return read<value_type, alignment>(memory,
endian);
80template <
typename value_type, std::
size_t alignment,
typename CharT>
81[[nodiscard]]
inline value_type
readNext(
const CharT *&memory,
83 value_type ret = read<value_type, alignment>(memory,
endian);
84 memory +=
sizeof(value_type);
90[[nodiscard]]
inline value_type
readNext(
const CharT *&memory) {
91 return readNext<value_type, alignment, CharT>(memory,
endian);
95template <
typename value_type, std::
size_t alignment = unaligned>
100 &
value,
sizeof(value_type));
103template<
typename value_type,
105 std::size_t alignment>
107 write<value_type, alignment>(memory,
value,
endian);
110template <
typename value_type>
115template <
typename value_type, endianness endian, std::
size_t alignment>
120 return read<value_type, endian, alignment>(memory);
127 sizeof(value_type) * 2);
128 val[0] = byte_swap<value_type, endian>(val[0]);
129 val[1] = byte_swap<value_type, endian>(val[1]);
135 (
sizeof(value_type) * 8) - startBit;
142 upperVal <<= numBitsFirstVal;
144 return lowerVal | upperVal;
150template <
typename value_type, endianness endian, std::
size_t alignment>
155 write<value_type, endian, alignment>(memory,
value);
162 sizeof(value_type) * 2);
163 val[0] = byte_swap<value_type, endian>(val[0]);
164 val[1] = byte_swap<value_type, endian>(val[1]);
170 (
sizeof(value_type) * 8) - startBit;
178 lowerVal <<= startBit;
192 val[0] = byte_swap<value_type, endian>(val[0]);
193 val[1] = byte_swap<value_type, endian>(val[1]);
196 &val[0],
sizeof(value_type) * 2);
216 return endian::read<value_type, endian, alignment>(
217 (
const void*)
Value.buffer);
221 endian::write<value_type, endian, alignment>(
222 (
void*)
Value.buffer, newValue);
226 *
this = *
this + newValue;
231 *
this = *
this - newValue;
236 *
this = *
this | newValue;
241 *
this = *
this & newValue;
255 return endian::read<value_type, endian, alignment>(Ptr);
259 endian::write<value_type, endian, alignment>(Ptr, NewValue);
352template <
typename T, endianness E> [[nodiscard]]
inline T read(
const void *
P) {
357 return read<uint16_t>(
P,
E);
360 return read<uint32_t>(
P,
E);
363 return read<uint64_t>(
P,
E);
367 return read<uint16_t, E>(
P);
370 return read<uint32_t, E>(
P);
373 return read<uint64_t, E>(
P);
377 return read16<little>(
P);
380 return read32<little>(
P);
383 return read64<little>(
P);
389template <
typename T, endianness E>
inline void write(
void *
P,
T V) {
394 write<uint16_t>(
P, V,
E);
397 write<uint32_t>(
P, V,
E);
400 write<uint64_t>(
P, V,
E);
404 write<uint16_t, E>(
P, V);
407 write<uint32_t, E>(
P, V);
410 write<uint64_t, E>(
P, V);
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_ASSUME_ALIGNED(p, a)
\macro LLVM_ASSUME_ALIGNED Returns a pointer with an assumed alignment.
Given that RA is a live value
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
uint64_t read64le(const void *P)
value_type byte_swap(value_type value, endianness endian)
uint16_t read16le(const void *P)
uint32_t read32(const void *P, endianness E)
void write16be(void *P, uint16_t V)
void write64le(void *P, uint64_t V)
uint64_t read64be(const void *P)
void write32le(void *P, uint32_t V)
void write32(void *P, uint32_t V, endianness E)
void writeAtBitAlignment(void *memory, value_type value, uint64_t startBit)
Write a value to memory with a particular endianness, for a location that starts at the given bit off...
value_type readAtBitAlignment(const void *memory, uint64_t startBit)
Read a value of a particular endianness from memory, for a location that starts at the given bit offs...
void write32be(void *P, uint32_t V)
uint64_t read64(const void *P, endianness E)
uint32_t read32be(const void *P)
constexpr endianness system_endianness()
void write16(void *P, uint16_t V, endianness E)
void write16le(void *P, uint16_t V)
void write64be(void *P, uint64_t V)
value_type read(const void *memory, endianness endian)
Read a value of a particular endianness from memory.
void write64(void *P, uint64_t V, endianness E)
uint16_t read16be(const void *P)
void write(void *memory, value_type value, endianness endian)
Write a value to memory with a particular endianness.
value_type readNext(const CharT *&memory, endianness endian)
Read a value of a particular endianness from a buffer, and increment the buffer past that value.
uint32_t read32le(const void *P)
uint16_t read16(const void *P, endianness E)
std::make_unsigned_t< value_type > make_unsigned_t
constexpr bool IsBigEndianHost
void swapByteOrder(T &Value)
This is an optimization pass for GlobalISel generic memory operations.
PointerUnion< const Value *, const PseudoSourceValue * > ValueType
value is either alignment, or alignof(T) if alignment is 0.
void operator=(value_type NewValue)
packed_endian_specific_integral(value_type val)
packed_endian_specific_integral()=default
packed_endian_specific_integral & operator+=(value_type newValue)
packed_endian_specific_integral & operator&=(value_type newValue)
char buffer[sizeof(value_type)]
void operator=(value_type newValue)
static constexpr std::size_t alignment
packed_endian_specific_integral & operator|=(value_type newValue)
packed_endian_specific_integral & operator-=(value_type newValue)