diff options
author | Erik Pilkington <erik.pilkington@gmail.com> | 2019-07-02 18:28:13 +0000 |
---|---|---|
committer | Erik Pilkington <erik.pilkington@gmail.com> | 2019-07-02 18:28:13 +0000 |
commit | eee944e7f9e60df44714eb547d0b876ee5dc7290 (patch) | |
tree | bfbb77d0b88de0f45c22ce3747d8d214d0f5a0d7 /llvm/lib | |
parent | 5613874947462fd4ceb4f66926c879269609463f (diff) | |
download | bcm5719-llvm-eee944e7f9e60df44714eb547d0b876ee5dc7290.tar.gz bcm5719-llvm-eee944e7f9e60df44714eb547d0b876ee5dc7290.zip |
[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
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/ExecutionEngine/ExecutionEngine.cpp | 53 | ||||
-rw-r--r-- | llvm/lib/Support/APInt.cpp | 53 |
2 files changed, 53 insertions, 53 deletions
diff --git a/llvm/lib/ExecutionEngine/ExecutionEngine.cpp b/llvm/lib/ExecutionEngine/ExecutionEngine.cpp index c2ea0f07f85..1c6c0406d04 100644 --- a/llvm/lib/ExecutionEngine/ExecutionEngine.cpp +++ b/llvm/lib/ExecutionEngine/ExecutionEngine.cpp @@ -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, diff --git a/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp index 3b40d9bd734..43173311cd8 100644 --- a/llvm/lib/Support/APInt.cpp +++ b/llvm/lib/Support/APInt.cpp @@ -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); + } +} |