Make frontend endian-aware.

In many parts the DMD frontend assumes a little endian CPU. In some
parts there are checks for endianess but they are incomplete and the
used definition is wrong. (Test for endianess will be removed in dmd
2.062.)
In this commit I add the required #if's and also add a CMake test for
endianess because there is no single compiler definition to check for.
This commit is contained in:
kai
2013-01-21 08:41:21 +01:00
parent 9e9acb9c4b
commit 55560bf382
5 changed files with 121 additions and 0 deletions

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;