aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--autoconf/configure.ac5
-rwxr-xr-xconfigure70
-rw-r--r--include/llvm/Config/config.h.in6
-rw-r--r--include/llvm/Target/TargetData.h11
-rw-r--r--lib/ExecutionEngine/ExecutionEngine.cpp71
-rw-r--r--test/ExecutionEngine/2007-12-10-APIntLoadStore.ll19
6 files changed, 129 insertions, 53 deletions
diff --git a/autoconf/configure.ac b/autoconf/configure.ac
index 979e3a8986..fe16b5073e 100644
--- a/autoconf/configure.ac
+++ b/autoconf/configure.ac
@@ -227,7 +227,10 @@ dnl Define a substitution, ARCH, for the target architecture
AC_SUBST(ARCH,$llvm_cv_target_arch)
dnl Check for the endianness of the target
-AC_C_BIGENDIAN(AC_SUBST([ENDIAN],[big]),AC_SUBST([ENDIAN],[little]))
+AC_C_BIGENDIAN([AC_SUBST([ENDIAN],[big]),
+ AC_DEFINE([MSB_FIRST], [1], [Define if this target is big endian])],
+ [AC_SUBST([ENDIAN],[little]),
+ AC_DEFINE([LSB_FIRST], [1], [Define if this target is little endian])])
dnl Check for build platform executable suffix if we're crosscompiling
if test "$cross_compiling" = yes; then
diff --git a/configure b/configure
index 4b65605d5b..b1fa7c09f7 100755
--- a/configure
+++ b/configure
@@ -828,7 +828,6 @@ NOLINKALL
LLVM_ON_UNIX
LLVM_ON_WIN32
ARCH
-ENDIAN
CC
CFLAGS
LDFLAGS
@@ -839,6 +838,7 @@ OBJEXT
CPP
GREP
EGREP
+ENDIAN
LLVM_CROSS_COMPILING
BUILD_CC
BUILD_EXEEXT
@@ -4183,9 +4183,19 @@ echo "${ECHO_T}$ac_cv_c_bigendian" >&6; }
case $ac_cv_c_bigendian in
yes)
ENDIAN=big
+,
+
+cat >>confdefs.h <<\_ACEOF
+#define MSB_FIRST 1
+_ACEOF
;;
no)
ENDIAN=little
+,
+
+cat >>confdefs.h <<\_ACEOF
+#define LSB_FIRST 1
+_ACEOF
;;
*)
{ { echo "$as_me:$LINENO: error: unknown endianness
@@ -8220,7 +8230,9 @@ if test "${enable_ltdl_install+set}" = set; then
fi
- if test x"${enable_ltdl_install-no}" != xno; then
+
+
+if test x"${enable_ltdl_install-no}" != xno; then
INSTALL_LTDL_TRUE=
INSTALL_LTDL_FALSE='#'
else
@@ -8228,7 +8240,9 @@ else
INSTALL_LTDL_FALSE=
fi
- if test x"${enable_ltdl_convenience-no}" != xno; then
+
+
+if test x"${enable_ltdl_convenience-no}" != xno; then
CONVENIENCE_LTDL_TRUE=
CONVENIENCE_LTDL_FALSE='#'
else
@@ -9867,7 +9881,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 9870 "configure"
+#line 9884 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11802,7 +11816,7 @@ ia64-*-hpux*)
;;
*-*-irix6*)
# Find out which ABI we are using.
- echo '#line 11805 "configure"' > conftest.$ac_ext
+ echo '#line 11819 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
@@ -13442,11 +13456,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:13445: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:13459: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:13449: \$? = $ac_status" >&5
+ echo "$as_me:13463: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -13710,11 +13724,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:13713: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:13727: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:13717: \$? = $ac_status" >&5
+ echo "$as_me:13731: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -13814,11 +13828,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:13817: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:13831: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:13821: \$? = $ac_status" >&5
+ echo "$as_me:13835: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -16122,7 +16136,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 16125 "configure"
+#line 16139 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -16222,7 +16236,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 16225 "configure"
+#line 16239 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -18558,11 +18572,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:18561: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:18575: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:18565: \$? = $ac_status" >&5
+ echo "$as_me:18579: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -18662,11 +18676,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:18665: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:18679: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:18669: \$? = $ac_status" >&5
+ echo "$as_me:18683: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -20232,11 +20246,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:20235: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:20249: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:20239: \$? = $ac_status" >&5
+ echo "$as_me:20253: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -20336,11 +20350,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:20339: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:20353: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:20343: \$? = $ac_status" >&5
+ echo "$as_me:20357: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -22539,11 +22553,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:22542: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:22556: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:22546: \$? = $ac_status" >&5
+ echo "$as_me:22560: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -22807,11 +22821,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:22810: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:22824: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:22814: \$? = $ac_status" >&5
+ echo "$as_me:22828: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -22911,11 +22925,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:22914: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:22928: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:22918: \$? = $ac_status" >&5
+ echo "$as_me:22932: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -32755,7 +32769,6 @@ NOLINKALL!$NOLINKALL$ac_delim
LLVM_ON_UNIX!$LLVM_ON_UNIX$ac_delim
LLVM_ON_WIN32!$LLVM_ON_WIN32$ac_delim
ARCH!$ARCH$ac_delim
-ENDIAN!$ENDIAN$ac_delim
CC!$CC$ac_delim
CFLAGS!$CFLAGS$ac_delim
LDFLAGS!$LDFLAGS$ac_delim
@@ -32766,6 +32779,7 @@ OBJEXT!$OBJEXT$ac_delim
CPP!$CPP$ac_delim
GREP!$GREP$ac_delim
EGREP!$EGREP$ac_delim
+ENDIAN!$ENDIAN$ac_delim
LLVM_CROSS_COMPILING!$LLVM_CROSS_COMPILING$ac_delim
BUILD_CC!$BUILD_CC$ac_delim
BUILD_EXEEXT!$BUILD_EXEEXT$ac_delim
diff --git a/include/llvm/Config/config.h.in b/include/llvm/Config/config.h.in
index 32e154a695..64858f26b9 100644
--- a/include/llvm/Config/config.h.in
+++ b/include/llvm/Config/config.h.in
@@ -494,6 +494,9 @@
/* Installation prefix directory */
#undef LLVM_PREFIX
+/* Define if this target is little endian */
+#undef LSB_FIRST
+
/* Define if the OS needs help to load dependent libraries for dlopen(). */
#undef LTDL_DLOPEN_DEPLIBS
@@ -511,6 +514,9 @@
/* Define to the system default library search path. */
#undef LTDL_SYSSEARCHPATH
+/* Define if this target is big endian */
+#undef MSB_FIRST
+
/* Define if /dev/zero should be used when mapping RWX memory, or undefine if
its not necessary */
#undef NEED_DEV_ZERO_FOR_MMAP
diff --git a/include/llvm/Target/TargetData.h b/include/llvm/Target/TargetData.h
index 3136a38ac0..fd52ef380a 100644
--- a/include/llvm/Target/TargetData.h
+++ b/include/llvm/Target/TargetData.h
@@ -23,6 +23,7 @@
#include "llvm/Pass.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/Config/config.h"
#include <string>
namespace llvm {
@@ -142,6 +143,16 @@ public:
bool isLittleEndian() const { return LittleEndian; }
bool isBigEndian() const { return !LittleEndian; }
+ /// Host endianness...
+ bool hostIsLittleEndian() const {
+#ifdef LSB_FIRST
+ return true;
+#else
+ return false;
+#endif
+ }
+ bool hostIsBigEndian() const { return !hostIsLittleEndian(); }
+
/// getStringRepresentation - Return the string representation of the
/// TargetData. This representation is in the same format accepted by the
/// string constructor above.
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:
diff --git a/test/ExecutionEngine/2007-12-10-APIntLoadStore.ll b/test/ExecutionEngine/2007-12-10-APIntLoadStore.ll
new file mode 100644
index 0000000000..7a337f90cb
--- /dev/null
+++ b/test/ExecutionEngine/2007-12-10-APIntLoadStore.ll
@@ -0,0 +1,19 @@
+; RUN: llvm-as < %s -o - | lli -force-interpreter
+; PR1836
+
+define i32 @main() {
+entry:
+ %retval = alloca i32 ; <i32*> [#uses=2]
+ %tmp = alloca i32 ; <i32*> [#uses=2]
+ %x = alloca i75, align 16 ; <i75*> [#uses=1]
+ %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
+ store i75 999, i75* %x, align 16
+ store i32 0, i32* %tmp, align 4
+ %tmp1 = load i32* %tmp, align 4 ; <i32> [#uses=1]
+ store i32 %tmp1, i32* %retval, align 4
+ br label %return
+
+return: ; preds = %entry
+ %retval2 = load i32* %retval ; <i32> [#uses=1]
+ ret i32 %retval2
+}