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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@364954
91177308-0d34-0410-b5e6-
96231b3b80d8
// 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
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);
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,
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);
+ }
+}