llvm.org GIT mirror llvm / 1eff704
Fix PR1836: in the interpreter, read and write apints using the minimum possible number of bytes. For little endian targets run on little endian machines, apints are stored in memory from LSB to MSB as before. For big endian targets on big endian machines they are stored from MSB to LSB which wasn't always the case before (if the target and host endianness doesn't match values are stored according to the host's endianness). Doing this requires knowing the endianness of the host, which is determined when configuring - thanks go to Anton for this. Only having access to little endian machines I was unable to properly test the big endian part, which is also the most complicated... git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44796 91177308-0d34-0410-b5e6-96231b3b80d8 Duncan Sands 11 years ago
6 changed file(s) with 129 addition(s) and 53 deletion(s). Raw diff Collapse all Expand all
226226 AC_SUBST(ARCH,$llvm_cv_target_arch)
227227
228228 dnl Check for the endianness of the target
229 AC_C_BIGENDIAN(AC_SUBST([ENDIAN],[big]),AC_SUBST([ENDIAN],[little]))
229 AC_C_BIGENDIAN([AC_SUBST([ENDIAN],[big]),
230 AC_DEFINE([MSB_FIRST], [1], [Define if this target is big endian])],
231 [AC_SUBST([ENDIAN],[little]),
232 AC_DEFINE([LSB_FIRST], [1], [Define if this target is little endian])])
230233
231234 dnl Check for build platform executable suffix if we're crosscompiling
232235 if test "$cross_compiling" = yes; then
827827 LLVM_ON_UNIX
828828 LLVM_ON_WIN32
829829 ARCH
830 ENDIAN
831830 CC
832831 CFLAGS
833832 LDFLAGS
838837 CPP
839838 GREP
840839 EGREP
840 ENDIAN
841841 LLVM_CROSS_COMPILING
842842 BUILD_CC
843843 BUILD_EXEEXT
41824182 case $ac_cv_c_bigendian in
41834183 yes)
41844184 ENDIAN=big
4185 ,
4186
4187 cat >>confdefs.h <<\_ACEOF
4188 #define MSB_FIRST 1
4189 _ACEOF
41854190 ;;
41864191 no)
41874192 ENDIAN=little
4193 ,
4194
4195 cat >>confdefs.h <<\_ACEOF
4196 #define LSB_FIRST 1
4197 _ACEOF
41884198 ;;
41894199 *)
41904200 { { echo "$as_me:$LINENO: error: unknown endianness
82198229 fi
82208230
82218231
8222 if test x"${enable_ltdl_install-no}" != xno; then
8232
8233
8234 if test x"${enable_ltdl_install-no}" != xno; then
82238235 INSTALL_LTDL_TRUE=
82248236 INSTALL_LTDL_FALSE='#'
82258237 else
82278239 INSTALL_LTDL_FALSE=
82288240 fi
82298241
8230 if test x"${enable_ltdl_convenience-no}" != xno; then
8242
8243
8244 if test x"${enable_ltdl_convenience-no}" != xno; then
82318245 CONVENIENCE_LTDL_TRUE=
82328246 CONVENIENCE_LTDL_FALSE='#'
82338247 else
98669880 lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
98679881 lt_status=$lt_dlunknown
98689882 cat > conftest.$ac_ext <
9869 #line 9870 "configure"
9883 #line 9884 "configure"
98709884 #include "confdefs.h"
98719885
98729886 #if HAVE_DLFCN_H
1180111815 ;;
1180211816 *-*-irix6*)
1180311817 # Find out which ABI we are using.
11804 echo '#line 11805 "configure"' > conftest.$ac_ext
11818 echo '#line 11819 "configure"' > conftest.$ac_ext
1180511819 if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
1180611820 (eval $ac_compile) 2>&5
1180711821 ac_status=$?
1344113455 -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
1344213456 -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
1344313457 -e 's:$: $lt_compiler_flag:'`
13444 (eval echo "\"\$as_me:13445: $lt_compile\"" >&5)
13458 (eval echo "\"\$as_me:13459: $lt_compile\"" >&5)
1344513459 (eval "$lt_compile" 2>conftest.err)
1344613460 ac_status=$?
1344713461 cat conftest.err >&5
13448 echo "$as_me:13449: \$? = $ac_status" >&5
13462 echo "$as_me:13463: \$? = $ac_status" >&5
1344913463 if (exit $ac_status) && test -s "$ac_outfile"; then
1345013464 # The compiler can only warn and ignore the option if not recognized
1345113465 # So say no if there are warnings other than the usual output.
1370913723 -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
1371013724 -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
1371113725 -e 's:$: $lt_compiler_flag:'`
13712 (eval echo "\"\$as_me:13713: $lt_compile\"" >&5)
13726 (eval echo "\"\$as_me:13727: $lt_compile\"" >&5)
1371313727 (eval "$lt_compile" 2>conftest.err)
1371413728 ac_status=$?
1371513729 cat conftest.err >&5
13716 echo "$as_me:13717: \$? = $ac_status" >&5
13730 echo "$as_me:13731: \$? = $ac_status" >&5
1371713731 if (exit $ac_status) && test -s "$ac_outfile"; then
1371813732 # The compiler can only warn and ignore the option if not recognized
1371913733 # So say no if there are warnings other than the usual output.
1381313827 -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
1381413828 -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
1381513829 -e 's:$: $lt_compiler_flag:'`
13816 (eval echo "\"\$as_me:13817: $lt_compile\"" >&5)
13830 (eval echo "\"\$as_me:13831: $lt_compile\"" >&5)
1381713831 (eval "$lt_compile" 2>out/conftest.err)
1381813832 ac_status=$?
1381913833 cat out/conftest.err >&5
13820 echo "$as_me:13821: \$? = $ac_status" >&5
13834 echo "$as_me:13835: \$? = $ac_status" >&5
1382113835 if (exit $ac_status) && test -s out/conftest2.$ac_objext
1382213836 then
1382313837 # The compiler can only warn and ignore the option if not recognized
1612116135 lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
1612216136 lt_status=$lt_dlunknown
1612316137 cat > conftest.$ac_ext <
16124 #line 16125 "configure"
16138 #line 16139 "configure"
1612516139 #include "confdefs.h"
1612616140
1612716141 #if HAVE_DLFCN_H
1622116235 lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
1622216236 lt_status=$lt_dlunknown
1622316237 cat > conftest.$ac_ext <
16224 #line 16225 "configure"
16238 #line 16239 "configure"
1622516239 #include "confdefs.h"
1622616240
1622716241 #if HAVE_DLFCN_H
1855718571 -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
1855818572 -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
1855918573 -e 's:$: $lt_compiler_flag:'`
18560 (eval echo "\"\$as_me:18561: $lt_compile\"" >&5)
18574 (eval echo "\"\$as_me:18575: $lt_compile\"" >&5)
1856118575 (eval "$lt_compile" 2>conftest.err)
1856218576 ac_status=$?
1856318577 cat conftest.err >&5
18564 echo "$as_me:18565: \$? = $ac_status" >&5
18578 echo "$as_me:18579: \$? = $ac_status" >&5
1856518579 if (exit $ac_status) && test -s "$ac_outfile"; then
1856618580 # The compiler can only warn and ignore the option if not recognized
1856718581 # So say no if there are warnings other than the usual output.
1866118675 -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
1866218676 -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
1866318677 -e 's:$: $lt_compiler_flag:'`
18664 (eval echo "\"\$as_me:18665: $lt_compile\"" >&5)
18678 (eval echo "\"\$as_me:18679: $lt_compile\"" >&5)
1866518679 (eval "$lt_compile" 2>out/conftest.err)
1866618680 ac_status=$?
1866718681 cat out/conftest.err >&5
18668 echo "$as_me:18669: \$? = $ac_status" >&5
18682 echo "$as_me:18683: \$? = $ac_status" >&5
1866918683 if (exit $ac_status) && test -s out/conftest2.$ac_objext
1867018684 then
1867118685 # The compiler can only warn and ignore the option if not recognized
2023120245 -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
2023220246 -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
2023320247 -e 's:$: $lt_compiler_flag:'`
20234 (eval echo "\"\$as_me:20235: $lt_compile\"" >&5)
20248 (eval echo "\"\$as_me:20249: $lt_compile\"" >&5)
2023520249 (eval "$lt_compile" 2>conftest.err)
2023620250 ac_status=$?
2023720251 cat conftest.err >&5
20238 echo "$as_me:20239: \$? = $ac_status" >&5
20252 echo "$as_me:20253: \$? = $ac_status" >&5
2023920253 if (exit $ac_status) && test -s "$ac_outfile"; then
2024020254 # The compiler can only warn and ignore the option if not recognized
2024120255 # So say no if there are warnings other than the usual output.
2033520349 -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
2033620350 -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
2033720351 -e 's:$: $lt_compiler_flag:'`
20338 (eval echo "\"\$as_me:20339: $lt_compile\"" >&5)
20352 (eval echo "\"\$as_me:20353: $lt_compile\"" >&5)
2033920353 (eval "$lt_compile" 2>out/conftest.err)
2034020354 ac_status=$?
2034120355 cat out/conftest.err >&5
20342 echo "$as_me:20343: \$? = $ac_status" >&5
20356 echo "$as_me:20357: \$? = $ac_status" >&5
2034320357 if (exit $ac_status) && test -s out/conftest2.$ac_objext
2034420358 then
2034520359 # The compiler can only warn and ignore the option if not recognized
2253822552 -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
2253922553 -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
2254022554 -e 's:$: $lt_compiler_flag:'`
22541 (eval echo "\"\$as_me:22542: $lt_compile\"" >&5)
22555 (eval echo "\"\$as_me:22556: $lt_compile\"" >&5)
2254222556 (eval "$lt_compile" 2>conftest.err)
2254322557 ac_status=$?
2254422558 cat conftest.err >&5
22545 echo "$as_me:22546: \$? = $ac_status" >&5
22559 echo "$as_me:22560: \$? = $ac_status" >&5
2254622560 if (exit $ac_status) && test -s "$ac_outfile"; then
2254722561 # The compiler can only warn and ignore the option if not recognized
2254822562 # So say no if there are warnings other than the usual output.
2280622820 -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
2280722821 -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
2280822822 -e 's:$: $lt_compiler_flag:'`
22809 (eval echo "\"\$as_me:22810: $lt_compile\"" >&5)
22823 (eval echo "\"\$as_me:22824: $lt_compile\"" >&5)
2281022824 (eval "$lt_compile" 2>conftest.err)
2281122825 ac_status=$?
2281222826 cat conftest.err >&5
22813 echo "$as_me:22814: \$? = $ac_status" >&5
22827 echo "$as_me:22828: \$? = $ac_status" >&5
2281422828 if (exit $ac_status) && test -s "$ac_outfile"; then
2281522829 # The compiler can only warn and ignore the option if not recognized
2281622830 # So say no if there are warnings other than the usual output.
2291022924 -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
2291122925 -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
2291222926 -e 's:$: $lt_compiler_flag:'`
22913 (eval echo "\"\$as_me:22914: $lt_compile\"" >&5)
22927 (eval echo "\"\$as_me:22928: $lt_compile\"" >&5)
2291422928 (eval "$lt_compile" 2>out/conftest.err)
2291522929 ac_status=$?
2291622930 cat out/conftest.err >&5
22917 echo "$as_me:22918: \$? = $ac_status" >&5
22931 echo "$as_me:22932: \$? = $ac_status" >&5
2291822932 if (exit $ac_status) && test -s out/conftest2.$ac_objext
2291922933 then
2292022934 # The compiler can only warn and ignore the option if not recognized
3275432768 LLVM_ON_UNIX!$LLVM_ON_UNIX$ac_delim
3275532769 LLVM_ON_WIN32!$LLVM_ON_WIN32$ac_delim
3275632770 ARCH!$ARCH$ac_delim
32757 ENDIAN!$ENDIAN$ac_delim
3275832771 CC!$CC$ac_delim
3275932772 CFLAGS!$CFLAGS$ac_delim
3276032773 LDFLAGS!$LDFLAGS$ac_delim
3276532778 CPP!$CPP$ac_delim
3276632779 GREP!$GREP$ac_delim
3276732780 EGREP!$EGREP$ac_delim
32781 ENDIAN!$ENDIAN$ac_delim
3276832782 LLVM_CROSS_COMPILING!$LLVM_CROSS_COMPILING$ac_delim
3276932783 BUILD_CC!$BUILD_CC$ac_delim
3277032784 BUILD_EXEEXT!$BUILD_EXEEXT$ac_delim
493493 /* Installation prefix directory */
494494 #undef LLVM_PREFIX
495495
496 /* Define if this target is little endian */
497 #undef LSB_FIRST
498
496499 /* Define if the OS needs help to load dependent libraries for dlopen(). */
497500 #undef LTDL_DLOPEN_DEPLIBS
498501
509512
510513 /* Define to the system default library search path. */
511514 #undef LTDL_SYSSEARCHPATH
515
516 /* Define if this target is big endian */
517 #undef MSB_FIRST
512518
513519 /* Define if /dev/zero should be used when mapping RWX memory, or undefine if
514520 its not necessary */
2222 #include "llvm/Pass.h"
2323 #include "llvm/Support/DataTypes.h"
2424 #include "llvm/ADT/SmallVector.h"
25 #include "llvm/Config/config.h"
2526 #include
2627
2728 namespace llvm {
141142 bool isLittleEndian() const { return LittleEndian; }
142143 bool isBigEndian() const { return !LittleEndian; }
143144
145 /// Host endianness...
146 bool hostIsLittleEndian() const {
147 #ifdef LSB_FIRST
148 return true;
149 #else
150 return false;
151 #endif
152 }
153 bool hostIsBigEndian() const { return !hostIsLittleEndian(); }
154
144155 /// getStringRepresentation - Return the string representation of the
145156 /// TargetData. This representation is in the same format accepted by the
146157 /// string constructor above.
632632 switch (Ty->getTypeID()) {
633633 case Type::IntegerTyID: {
634634 unsigned BitWidth = cast(Ty)->getBitWidth();
635 GenericValue TmpVal = Val;
636 if (BitWidth <= 8)
637 *((uint8_t*)Ptr) = uint8_t(Val.IntVal.getZExtValue());
638 else if (BitWidth <= 16) {
639 *((uint16_t*)Ptr) = uint16_t(Val.IntVal.getZExtValue());
640 } else if (BitWidth <= 32) {
641 *((uint32_t*)Ptr) = uint32_t(Val.IntVal.getZExtValue());
642 } else if (BitWidth <= 64) {
643 *((uint64_t*)Ptr) = uint64_t(Val.IntVal.getZExtValue());
644 } else {
645 uint64_t *Dest = (uint64_t*)Ptr;
646 const uint64_t *Src = Val.IntVal.getRawData();
647 for (uint32_t i = 0; i < Val.IntVal.getNumWords(); ++i)
648 Dest[i] = Src[i];
635 unsigned StoreBytes = (BitWidth + 7)/8;
636 uint8_t *Src = (uint8_t *)Val.IntVal.getRawData();
637 uint8_t *Dst = (uint8_t *)Ptr;
638
639 if (getTargetData()->hostIsLittleEndian())
640 // Little-endian host - the source is ordered from LSB to MSB.
641 // Order the destination from LSB to MSB: Do a straight copy.
642 memcpy(Dst, Src, StoreBytes);
643 else {
644 // Big-endian host - the source is an array of 64 bit words ordered from
645 // LSW to MSW. Each word is ordered from MSB to LSB.
646 // Order the destination from MSB to LSB: Reverse the word order, but not
647 // the bytes in a word.
648 while (StoreBytes > sizeof(uint64_t)) {
649 StoreBytes -= sizeof(uint64_t);
650 // May not be aligned so use memcpy.
651 memcpy(Dst + StoreBytes, Src, sizeof(uint64_t));
652 Src += sizeof(uint64_t);
653 }
654
655 memcpy(Dst, Src + sizeof(uint64_t) - StoreBytes, StoreBytes);
649656 }
650657 break;
651658 }
682689 switch (Ty->getTypeID()) {
683690 case Type::IntegerTyID: {
684691 unsigned BitWidth = cast(Ty)->getBitWidth();
685 if (BitWidth <= 8)
686 Result.IntVal = APInt(BitWidth, *((uint8_t*)Ptr));
687 else if (BitWidth <= 16) {
688 Result.IntVal = APInt(BitWidth, *((uint16_t*)Ptr));
689 } else if (BitWidth <= 32) {
690 Result.IntVal = APInt(BitWidth, *((uint32_t*)Ptr));
691 } else if (BitWidth <= 64) {
692 Result.IntVal = APInt(BitWidth, *((uint64_t*)Ptr));
693 } else
694 Result.IntVal = APInt(BitWidth, (BitWidth+63)/64, (uint64_t*)Ptr);
692 unsigned LoadBytes = (BitWidth + 7)/8;
693
694 // An APInt with all words initially zero.
695 Result.IntVal = APInt(BitWidth, 0);
696
697 uint8_t *Src = (uint8_t *)Ptr;
698 uint8_t *Dst = (uint8_t *)Result.IntVal.getRawData();
699
700 if (getTargetData()->hostIsLittleEndian())
701 // Little-endian host - the destination must be ordered from LSB to MSB.
702 // The source is ordered from LSB to MSB: Do a straight copy.
703 memcpy(Dst, Src, LoadBytes);
704 else {
705 // Big-endian - the destination is an array of 64 bit words ordered from
706 // LSW to MSW. Each word must be ordered from MSB to LSB. The source is
707 // ordered from MSB to LSB: Reverse the word order, but not the bytes in
708 // a word.
709 while (LoadBytes > sizeof(uint64_t)) {
710 LoadBytes -= sizeof(uint64_t);
711 // May not be aligned so use memcpy.
712 memcpy(Dst, Src + LoadBytes, sizeof(uint64_t));
713 Dst += sizeof(uint64_t);
714 }
715
716 memcpy(Dst + sizeof(uint64_t) - LoadBytes, Src, LoadBytes);
717 }
695718 break;
696719 }
697720 case Type::FloatTyID:
0 ; RUN: llvm-as < %s -o - | lli -force-interpreter
1 ; PR1836
2
3 define i32 @main() {
4 entry:
5 %retval = alloca i32 ; [#uses=2]
6 %tmp = alloca i32 ; [#uses=2]
7 %x = alloca i75, align 16 ; [#uses=1]
8 %"alloca point" = bitcast i32 0 to i32 ; [#uses=0]
9 store i75 999, i75* %x, align 16
10 store i32 0, i32* %tmp, align 4
11 %tmp1 = load i32* %tmp, align 4 ; [#uses=1]
12 store i32 %tmp1, i32* %retval, align 4
13 br label %return
14
15 return: ; preds = %entry
16 %retval2 = load i32* %retval ; [#uses=1]
17 ret i32 %retval2
18 }