aboutsummaryrefslogtreecommitdiff
path: root/lib/ExecutionEngine/ExecutionEngine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ExecutionEngine/ExecutionEngine.cpp')
-rw-r--r--lib/ExecutionEngine/ExecutionEngine.cpp71
1 files changed, 47 insertions, 24 deletions
diff --git a/lib/ExecutionEngine/ExecutionEngine.cpp b/lib/ExecutionEngine/ExecutionEngine.cpp
index 02b94cc1fd..2c7a7dd144 100644
--- a/lib/ExecutionEngine/ExecutionEngine.cpp
+++ b/lib/ExecutionEngine/ExecutionEngine.cpp
@@ -633,20 +633,27 @@ void ExecutionEngine::StoreValueToMemory(const GenericValue &Val, GenericValue *
switch (Ty->getTypeID()) {
case Type::IntegerTyID: {
unsigned BitWidth = cast<IntegerType>(Ty)->getBitWidth();
- GenericValue TmpVal = Val;
- if (BitWidth <= 8)
- *((uint8_t*)Ptr) = uint8_t(Val.IntVal.getZExtValue());
- else if (BitWidth <= 16) {
- *((uint16_t*)Ptr) = uint16_t(Val.IntVal.getZExtValue());
- } else if (BitWidth <= 32) {
- *((uint32_t*)Ptr) = uint32_t(Val.IntVal.getZExtValue());
- } else if (BitWidth <= 64) {
- *((uint64_t*)Ptr) = uint64_t(Val.IntVal.getZExtValue());
- } else {
- uint64_t *Dest = (uint64_t*)Ptr;
- const uint64_t *Src = Val.IntVal.getRawData();
- for (uint32_t i = 0; i < Val.IntVal.getNumWords(); ++i)
- Dest[i] = Src[i];
+ unsigned StoreBytes = (BitWidth + 7)/8;
+ uint8_t *Src = (uint8_t *)Val.IntVal.getRawData();
+ uint8_t *Dst = (uint8_t *)Ptr;
+
+ if (getTargetData()->hostIsLittleEndian())
+ // 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);
}
break;
}
@@ -683,16 +690,32 @@ void ExecutionEngine::LoadValueFromMemory(GenericValue &Result,
switch (Ty->getTypeID()) {
case Type::IntegerTyID: {
unsigned BitWidth = cast<IntegerType>(Ty)->getBitWidth();
- if (BitWidth <= 8)
- Result.IntVal = APInt(BitWidth, *((uint8_t*)Ptr));
- else if (BitWidth <= 16) {
- Result.IntVal = APInt(BitWidth, *((uint16_t*)Ptr));
- } else if (BitWidth <= 32) {
- Result.IntVal = APInt(BitWidth, *((uint32_t*)Ptr));
- } else if (BitWidth <= 64) {
- Result.IntVal = APInt(BitWidth, *((uint64_t*)Ptr));
- } else
- Result.IntVal = APInt(BitWidth, (BitWidth+63)/64, (uint64_t*)Ptr);
+ unsigned LoadBytes = (BitWidth + 7)/8;
+
+ // An APInt with all words initially zero.
+ Result.IntVal = APInt(BitWidth, 0);
+
+ uint8_t *Src = (uint8_t *)Ptr;
+ uint8_t *Dst = (uint8_t *)Result.IntVal.getRawData();
+
+ if (getTargetData()->hostIsLittleEndian())
+ // 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);
+ }
break;
}
case Type::FloatTyID: