mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
[C++2a] Add __builtin_bit_cast, used to implement std::bit_cast
This commit adds a new builtin, __builtin_bit_cast(T, v), which performs a bit_cast from a value v to a type T. This expression can be evaluated at compile time under specific circumstances. The compile time evaluation currently doesn't support bit-fields, but I'm planning on fixing this in a follow up (some of the logic for figuring this out is in CodeGen). I'm also planning follow-ups for supporting some more esoteric types that the constexpr evaluator supports, as well as extending __builtin_memcpy constexpr evaluation to use the same infrastructure. rdar://44987528 Differential revision: https://reviews.llvm.org/D62825 llvm-svn: 364954
This commit is contained in:
parent
d6fe99fc94
commit
29c3a3c9ec
@ -2212,6 +2212,15 @@ Optional<APInt> SolveQuadraticEquationWrap(APInt A, APInt B, APInt C,
|
||||
// See friend declaration above. This additional declaration is required in
|
||||
// order to compile LLVM with IBM xlC compiler.
|
||||
hash_code hash_value(const APInt &Arg);
|
||||
} // End of llvm namespace
|
||||
|
||||
/// StoreIntToMemory - Fills the StoreBytes bytes of memory starting from Dst
|
||||
/// with the integer held in IntVal.
|
||||
void StoreIntToMemory(const APInt &IntVal, uint8_t *Dst, unsigned StoreBytes);
|
||||
|
||||
/// LoadIntFromMemory - Loads the integer stored in the LoadBytes bytes starting
|
||||
/// from Src into IntVal, which is assumed to be wide enough and to hold zero.
|
||||
void LoadIntFromMemory(APInt &IntVal, uint8_t *Src, unsigned LoadBytes);
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
#endif
|
||||
|
@ -1019,32 +1019,6 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) {
|
||||
return Result;
|
||||
}
|
||||
|
||||
/// StoreIntToMemory - Fills the StoreBytes bytes of memory starting from Dst
|
||||
/// with the integer held in IntVal.
|
||||
static void StoreIntToMemory(const APInt &IntVal, uint8_t *Dst,
|
||||
unsigned StoreBytes) {
|
||||
assert((IntVal.getBitWidth()+7)/8 >= StoreBytes && "Integer too small!");
|
||||
const uint8_t *Src = (const uint8_t *)IntVal.getRawData();
|
||||
|
||||
if (sys::IsLittleEndianHost) {
|
||||
// Little-endian host - the source is ordered from LSB to MSB. Order the
|
||||
// destination from LSB to MSB: Do a straight copy.
|
||||
memcpy(Dst, Src, StoreBytes);
|
||||
} else {
|
||||
// Big-endian host - the source is an array of 64 bit words ordered from
|
||||
// LSW to MSW. Each word is ordered from MSB to LSB. Order the destination
|
||||
// from MSB to LSB: Reverse the word order, but not the bytes in a word.
|
||||
while (StoreBytes > sizeof(uint64_t)) {
|
||||
StoreBytes -= sizeof(uint64_t);
|
||||
// May not be aligned so use memcpy.
|
||||
memcpy(Dst + StoreBytes, Src, sizeof(uint64_t));
|
||||
Src += sizeof(uint64_t);
|
||||
}
|
||||
|
||||
memcpy(Dst, Src + sizeof(uint64_t) - StoreBytes, StoreBytes);
|
||||
}
|
||||
}
|
||||
|
||||
void ExecutionEngine::StoreValueToMemory(const GenericValue &Val,
|
||||
GenericValue *Ptr, Type *Ty) {
|
||||
const unsigned StoreBytes = getDataLayout().getTypeStoreSize(Ty);
|
||||
@ -1092,33 +1066,6 @@ void ExecutionEngine::StoreValueToMemory(const GenericValue &Val,
|
||||
std::reverse((uint8_t*)Ptr, StoreBytes + (uint8_t*)Ptr);
|
||||
}
|
||||
|
||||
/// LoadIntFromMemory - Loads the integer stored in the LoadBytes bytes starting
|
||||
/// from Src into IntVal, which is assumed to be wide enough and to hold zero.
|
||||
static void LoadIntFromMemory(APInt &IntVal, uint8_t *Src, unsigned LoadBytes) {
|
||||
assert((IntVal.getBitWidth()+7)/8 >= LoadBytes && "Integer too small!");
|
||||
uint8_t *Dst = reinterpret_cast<uint8_t *>(
|
||||
const_cast<uint64_t *>(IntVal.getRawData()));
|
||||
|
||||
if (sys::IsLittleEndianHost)
|
||||
// Little-endian host - the destination must be ordered from LSB to MSB.
|
||||
// The source is ordered from LSB to MSB: Do a straight copy.
|
||||
memcpy(Dst, Src, LoadBytes);
|
||||
else {
|
||||
// Big-endian - the destination is an array of 64 bit words ordered from
|
||||
// LSW to MSW. Each word must be ordered from MSB to LSB. The source is
|
||||
// ordered from MSB to LSB: Reverse the word order, but not the bytes in
|
||||
// a word.
|
||||
while (LoadBytes > sizeof(uint64_t)) {
|
||||
LoadBytes -= sizeof(uint64_t);
|
||||
// May not be aligned so use memcpy.
|
||||
memcpy(Dst, Src + LoadBytes, sizeof(uint64_t));
|
||||
Dst += sizeof(uint64_t);
|
||||
}
|
||||
|
||||
memcpy(Dst + sizeof(uint64_t) - LoadBytes, Src, LoadBytes);
|
||||
}
|
||||
}
|
||||
|
||||
/// FIXME: document
|
||||
///
|
||||
void ExecutionEngine::LoadValueFromMemory(GenericValue &Result,
|
||||
|
@ -2934,3 +2934,56 @@ llvm::APIntOps::SolveQuadraticEquationWrap(APInt A, APInt B, APInt C,
|
||||
LLVM_DEBUG(dbgs() << __func__ << ": solution (wrap): " << X << '\n');
|
||||
return X;
|
||||
}
|
||||
|
||||
/// StoreIntToMemory - Fills the StoreBytes bytes of memory starting from Dst
|
||||
/// with the integer held in IntVal.
|
||||
void llvm::StoreIntToMemory(const APInt &IntVal, uint8_t *Dst,
|
||||
unsigned StoreBytes) {
|
||||
assert((IntVal.getBitWidth()+7)/8 >= StoreBytes && "Integer too small!");
|
||||
const uint8_t *Src = (const uint8_t *)IntVal.getRawData();
|
||||
|
||||
if (sys::IsLittleEndianHost) {
|
||||
// Little-endian host - the source is ordered from LSB to MSB. Order the
|
||||
// destination from LSB to MSB: Do a straight copy.
|
||||
memcpy(Dst, Src, StoreBytes);
|
||||
} else {
|
||||
// Big-endian host - the source is an array of 64 bit words ordered from
|
||||
// LSW to MSW. Each word is ordered from MSB to LSB. Order the destination
|
||||
// from MSB to LSB: Reverse the word order, but not the bytes in a word.
|
||||
while (StoreBytes > sizeof(uint64_t)) {
|
||||
StoreBytes -= sizeof(uint64_t);
|
||||
// May not be aligned so use memcpy.
|
||||
memcpy(Dst + StoreBytes, Src, sizeof(uint64_t));
|
||||
Src += sizeof(uint64_t);
|
||||
}
|
||||
|
||||
memcpy(Dst, Src + sizeof(uint64_t) - StoreBytes, StoreBytes);
|
||||
}
|
||||
}
|
||||
|
||||
/// LoadIntFromMemory - Loads the integer stored in the LoadBytes bytes starting
|
||||
/// from Src into IntVal, which is assumed to be wide enough and to hold zero.
|
||||
void llvm::LoadIntFromMemory(APInt &IntVal, uint8_t *Src, unsigned LoadBytes) {
|
||||
assert((IntVal.getBitWidth()+7)/8 >= LoadBytes && "Integer too small!");
|
||||
uint8_t *Dst = reinterpret_cast<uint8_t *>(
|
||||
const_cast<uint64_t *>(IntVal.getRawData()));
|
||||
|
||||
if (sys::IsLittleEndianHost)
|
||||
// Little-endian host - the destination must be ordered from LSB to MSB.
|
||||
// The source is ordered from LSB to MSB: Do a straight copy.
|
||||
memcpy(Dst, Src, LoadBytes);
|
||||
else {
|
||||
// Big-endian - the destination is an array of 64 bit words ordered from
|
||||
// LSW to MSW. Each word must be ordered from MSB to LSB. The source is
|
||||
// ordered from MSB to LSB: Reverse the word order, but not the bytes in
|
||||
// a word.
|
||||
while (LoadBytes > sizeof(uint64_t)) {
|
||||
LoadBytes -= sizeof(uint64_t);
|
||||
// May not be aligned so use memcpy.
|
||||
memcpy(Dst, Src + LoadBytes, sizeof(uint64_t));
|
||||
Dst += sizeof(uint64_t);
|
||||
}
|
||||
|
||||
memcpy(Dst + sizeof(uint64_t) - LoadBytes, Src, LoadBytes);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user