mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-11 18:33:14 +01:00
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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user