Merge pull request #268 from redstar/endian

Make frontend endian-aware.
This commit is contained in:
Kai Nacke
2013-01-21 00:11:32 -08:00
5 changed files with 121 additions and 0 deletions

View File

@@ -278,6 +278,19 @@ else()
set(EXTRA_CXXFLAGS "-fexceptions")
endif()
#
# Check endianess.
# There is no realiable way to delegate the work to the compiler.
# E.g. gcc up to version 4.6 defines __LITTLE_ENDIAN, but not 4.7
#
include(TestBigEndian)
test_big_endian(BIGENDIAN)
if(${BIGENDIAN})
add_definitions(-D__BIG_ENDIAN__)
else()
add_definitions(-D__LITTLE_ENDIAN__)
endif()
#
# Set up the main ldc/ldc2 target.
#

View File

@@ -1628,7 +1628,16 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2)
size_t len = (t->ty == tn->ty) ? 1 : utf_codeLength(sz, v);
s = mem.malloc((len + 1) * sz);
if (t->ty == tn->ty)
#if IN_LLVM
#if __LITTLE_ENDIAN__
memcpy((unsigned char *)s, &v, sz);
#else
memcpy((unsigned char *)s,
(unsigned char *)&v + (sizeof(dinteger_t) - sz), sz);
#endif
#else
memcpy((unsigned char *)s, &v, sz);
#endif
else
utf_encode(sz, s, v);
@@ -1752,7 +1761,16 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2)
s = mem.malloc((len + 1) * sz);
memcpy(s, es1->string, es1->len * sz);
if (homoConcat)
#if IN_LLVM
#if __LITTLE_ENDIAN__
memcpy((unsigned char *)s + (sz * es1->len), &v, sz);
#else
memcpy((unsigned char *)s + (sz * es1->len),
(unsigned char *)&v + (sizeof(dinteger_t) - sz), sz);
#endif
#else
memcpy((unsigned char *)s + (sz * es1->len), &v, sz);
#endif
else
utf_encode(sz, (unsigned char *)s + (sz * es1->len), v);
@@ -1776,7 +1794,16 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2)
dinteger_t v = e1->toInteger();
s = mem.malloc((len + 1) * sz);
#if IN_LLVM
#if __LITTLE_ENDIAN__
memcpy((unsigned char *)s, &v, sz);
#else
memcpy((unsigned char *)s,
(unsigned char *)&v + (sizeof(dinteger_t) - sz), sz);
#endif
#else
memcpy((unsigned char *)s, &v, sz);
#endif
memcpy((unsigned char *)s + sz, es2->string, es2->len * sz);
// Add terminating 0

View File

@@ -990,7 +990,16 @@ Expression *ctfeCat(Type *type, Expression *e1, Expression *e2)
if (es2e->op != TOKint64)
return EXP_CANT_INTERPRET;
dinteger_t v = es2e->toInteger();
#if IN_LLVM
#if __LITTLE_ENDIAN__
memcpy((unsigned char *)s + i * sz, &v, sz);
#else
memcpy((unsigned char *)s + i * sz,
(unsigned char *)&v + (sizeof(dinteger_t) - sz), sz);
#endif
#else
memcpy((unsigned char *)s + i * sz, &v, sz);
#endif
}
// Add terminating 0
@@ -1020,7 +1029,16 @@ Expression *ctfeCat(Type *type, Expression *e1, Expression *e2)
if (es2e->op != TOKint64)
return EXP_CANT_INTERPRET;
dinteger_t v = es2e->toInteger();
#if IN_LLVM
#if __LITTLE_ENDIAN__
memcpy((unsigned char *)s + (es1->len + i) * sz, &v, sz);
#else
memcpy((unsigned char *)s + (es1->len + i) * sz,
(unsigned char *) &v + (sizeof(dinteger_t) - sz), sz);
#endif
#else
memcpy((unsigned char *)s + (es1->len + i) * sz, &v, sz);
#endif
}
// Add terminating 0

View File

@@ -544,20 +544,46 @@ bool Module::read(Loc loc)
inline unsigned readwordLE(unsigned short *p)
{
#if IN_LLVM
#if __LITTLE_ENDIAN__
return *p;
#else
return (((unsigned char *)p)[1] << 8) | ((unsigned char *)p)[0];
#endif
#else
#if LITTLE_ENDIAN
return *p;
#else
return (((unsigned char *)p)[1] << 8) | ((unsigned char *)p)[0];
#endif
#endif
}
inline unsigned readwordBE(unsigned short *p)
{
#if IN_LLVM
#if __BIG_ENDIAN__
return *p;
#else
return (((unsigned char *)p)[0] << 8) | ((unsigned char *)p)[1];
#endif
#else
return (((unsigned char *)p)[0] << 8) | ((unsigned char *)p)[1];
#endif
}
inline unsigned readlongLE(unsigned *p)
{
#if IN_LLVM
#if __LITTLE_ENDIAN__
return *p;
#else
return ((unsigned char *)p)[0] |
(((unsigned char *)p)[1] << 8) |
(((unsigned char *)p)[2] << 16) |
(((unsigned char *)p)[3] << 24);
#endif
#else
#if LITTLE_ENDIAN
return *p;
#else
@@ -566,14 +592,26 @@ inline unsigned readlongLE(unsigned *p)
(((unsigned char *)p)[2] << 16) |
(((unsigned char *)p)[3] << 24);
#endif
#endif
}
inline unsigned readlongBE(unsigned *p)
{
#if IN_LLVM
#if __BIG_ENDIAN__
return *p;
#else
return ((unsigned char *)p)[3] |
(((unsigned char *)p)[2] << 8) |
(((unsigned char *)p)[1] << 16) |
(((unsigned char *)p)[0] << 24);
#endif
#else
return ((unsigned char *)p)[3] |
(((unsigned char *)p)[2] << 8) |
(((unsigned char *)p)[1] << 16) |
(((unsigned char *)p)[0] << 24);
#endif
}
#if IN_LLVM

View File

@@ -35,29 +35,54 @@ hash_t calcHash(const char *str, size_t len)
case 2:
hash *= 37;
#if IN_LLVM
#if __LITTLE_ENDIAN__
hash += *(const uint16_t *)str;
#else
hash += str[0] * 256 + str[1];
#endif
#else
#if LITTLE_ENDIAN
hash += *(const uint16_t *)str;
#else
hash += str[0] * 256 + str[1];
#endif
#endif
return hash;
case 3:
hash *= 37;
#if IN_LLVM
#if __LITTLE_ENDIAN__
hash += (*(const uint16_t *)str << 8) +
((const uint8_t *)str)[2];
#else
hash += (str[0] * 256 + str[1]) * 256 + str[2];
#endif
#else
#if LITTLE_ENDIAN
hash += (*(const uint16_t *)str << 8) +
((const uint8_t *)str)[2];
#else
hash += (str[0] * 256 + str[1]) * 256 + str[2];
#endif
#endif
return hash;
default:
hash *= 37;
#if IN_LLVM
#if __LITTLE_ENDIAN__
hash += *(const uint32_t *)str;
#else
hash += ((str[0] * 256 + str[1]) * 256 + str[2]) * 256 + str[3];
#endif
#else
#if LITTLE_ENDIAN
hash += *(const uint32_t *)str;
#else
hash += ((str[0] * 256 + str[1]) * 256 + str[2]) * 256 + str[3];
#endif
#endif
str += 4;
len -= 4;