Hi Rainer,

> This will occur on any 32-bit target.  The following patch (using
> ssize_t instead) allowed the code to compile:

thanks, included your fix and attempted a more generic version of the
186 test.

I also continued debugging some fails further:

- Most of the MurmurHash fails are simply due to the wrong byte order
being asserted but I did not yet check whether multi-chunk hashes are
more complicated to get right - I suppose not, though.

- The regex searches are even documented to not work properly on
big-endian platforms. I still guess they could be fixed without too much
effort.

- Math unit tests fail due to lower precision than on other machines.
Maybe this is because I only tested using -O0.

@Iain: With the patch as it is - hoping no additional tab/space damage
:) - is there any chance of getting it upstream anytime soon?

Regards
 Robin
diff --git a/gcc/d/dmd/constfold.c b/gcc/d/dmd/constfold.c
index ddd356bb966..cb58d4b4f5b 100644
--- a/gcc/d/dmd/constfold.c
+++ b/gcc/d/dmd/constfold.c
@@ -1752,14 +1752,17 @@ UnionExp Cat(Type *type, Expression *e1, Expression *e2)
     }
     else if (e1->op == TOKint64 && e2->op == TOKstring)
     {
-        // Concatenate the strings
+        // [w|d]?char ~ string --> string
+        // We assume that we only ever prepend one char of the same type
+        // (wchar,dchar) as the string's characters.
+
         StringExp *es2 = (StringExp *)e2;
         size_t len = 1 + es2->len;
         unsigned char sz = es2->sz;
         dinteger_t v = e1->toInteger();
 
         void *s = mem.xmalloc((len + 1) * sz);
-        memcpy((char *)s, &v, sz);
+        Port::valcpy((char *)s, v, sz);
         memcpy((char *)s + sz, es2->string, es2->len * sz);
 
         // Add terminating 0
diff --git a/gcc/d/typeinfo.cc b/gcc/d/typeinfo.cc
index dac66acdcd4..21bc4d62a68 100644
--- a/gcc/d/typeinfo.cc
+++ b/gcc/d/typeinfo.cc
@@ -830,7 +830,7 @@ public:
 	flags |= ClassFlags::noPointers;
 
     Lhaspointers:
-	this->layout_field (size_int (flags));
+	this->layout_field (build_integer_cst (flags, d_uint_type));
 
 	/* void *deallocator;  */
 	tree ddtor = (cd->aggDelete)
@@ -886,7 +886,7 @@ public:
 	if (cd->isCOMinterface ())
 	  flags |= ClassFlags::isCOMclass;
 
-	this->layout_field (size_int (flags));
+	this->layout_field (build_integer_cst (flags));
 
 	/* void *deallocator;
 	   OffsetTypeInfo[] m_offTi;  (not implemented)
@@ -1019,7 +1019,7 @@ public:
     StructFlags::Type m_flags = 0;
     if (ti->hasPointers ())
       m_flags |= StructFlags::hasPointers;
-    this->layout_field (size_int (m_flags));
+    this->layout_field (build_integer_cst (m_flags, d_uint_type));
 
     /* void function(void*) xdtor;  */
     tree dtor = (sd->dtor) ? build_address (get_symbol_decl (sd->dtor))
@@ -1033,7 +1033,7 @@ public:
       this->layout_field (null_pointer_node);
 
     /* uint m_align;  */
-    this->layout_field (size_int (ti->alignsize ()));
+    this->layout_field (build_integer_cst (ti->alignsize (), d_uint_type));
 
     if (global.params.is64bit)
       {
@@ -1489,8 +1489,8 @@ create_typeinfo (Type *type, Module *mod)
 				      array_type_node, array_type_node,
 				      ptr_type_node, ptr_type_node,
 				      ptr_type_node, ptr_type_node,
-				      size_type_node, ptr_type_node,
-				      ptr_type_node, size_type_node,
+				      d_uint_type, ptr_type_node,
+				      ptr_type_node, d_uint_type,
 				      ptr_type_node, argtype, argtype, NULL);
 	    }
 	  t->vtinfo = TypeInfoStructDeclaration::create (t);
diff --git a/gcc/testsuite/gdc.dg/runnable.d b/gcc/testsuite/gdc.dg/runnable.d
index e36a2585027..8d9a5868831 100644
--- a/gcc/testsuite/gdc.dg/runnable.d
+++ b/gcc/testsuite/gdc.dg/runnable.d
@@ -890,12 +890,17 @@ struct S186
     }
 }
 
+static if (size_t.sizeof == 8)
+     size_t checkval = 0x0200000000000002;
+static if (size_t.sizeof == 4)
+     size_t checkval = 0x02000002;
+
 void check186(in S186 obj, byte fieldB)
 {
     assert(obj.fieldA == 2);
     assert(obj.fieldB == 0);
     assert(obj.fieldC == 0);
-    assert(obj._complete == 2);
+    assert(obj._complete == checkval);
     assert(fieldB == 0);
 }
 
@@ -907,7 +912,7 @@ void test186a(size_t val)
     assert(obj.fieldA == 2);
     assert(obj.fieldB == 0);
     assert(obj.fieldC == 0);
-    assert(obj._complete == 2);
+    assert(obj._complete == checkval);
 
     obj = S186(val);
     check186(obj, obj.fieldB);
@@ -915,12 +920,12 @@ void test186a(size_t val)
     assert(obj.fieldA == 2);
     assert(obj.fieldB == 0);
     assert(obj.fieldC == 0);
-    assert(obj._complete == 2);
+    assert(obj._complete == checkval);
 }
 
 void test186()
 {
-    test186a(2);
+    test186a(checkval);
 }
 
 /******************************************/
diff --git a/gcc/testsuite/gdc.dg/simd.d b/gcc/testsuite/gdc.dg/simd.d
index 812b36649aa..7d0aa0168c0 100644
--- a/gcc/testsuite/gdc.dg/simd.d
+++ b/gcc/testsuite/gdc.dg/simd.d
@@ -1576,7 +1576,10 @@ ubyte[16] foounsto()
 void testOPvecunsto()
 {
     auto a = foounsto();
-    assert(a == [0, 0, 64, 65, 0, 0, 64, 65, 0, 0, 64, 65, 0, 0, 64, 65]);
+    version(LittleEndian)
+        assert(a == [0, 0, 64, 65, 0, 0, 64, 65, 0, 0, 64, 65, 0, 0, 64, 65]);
+    version(BigEndian)
+        assert(a == [65, 64, 0, 0, 65, 64, 0, 0, 65, 64, 0, 0, 65, 64, 0, 0]);
 }
 
 /*****************************************/
diff --git a/gcc/testsuite/gdc.test/runnable/mars1.d b/gcc/testsuite/gdc.test/runnable/mars1.d
index 1f4e55d9ac4..91d93dbf81e 100644
--- a/gcc/testsuite/gdc.test/runnable/mars1.d
+++ b/gcc/testsuite/gdc.test/runnable/mars1.d
@@ -238,13 +238,13 @@ void test13023(ulong n)
 
 struct U { int a; union { char c; int d; } long b; }
 
-U f = { b:3, d:2, a:1 };
+U f = { b:3, d:0x22222222, a:1 };
 
 void testU()
 {
     assert(f.b == 3);
-    assert(f.d == 2);
-    assert(f.c == 2);
+    assert(f.d == 0x22222222);
+    assert(f.c == 0x22);
     assert(f.a == 1);
     assert(f.sizeof == 16);
     assert(U.sizeof == 16);
diff --git a/gcc/testsuite/gdc.test/runnable/test12.d b/gcc/testsuite/gdc.test/runnable/test12.d
index 7656de70af6..db9b45cea61 100644
--- a/gcc/testsuite/gdc.test/runnable/test12.d
+++ b/gcc/testsuite/gdc.test/runnable/test12.d
@@ -624,7 +624,10 @@ int hoge(S29 s) {
     char[10] b;
     printf("%x\n", s);
     sprintf(b.ptr, "%x", s);
-    assert(b[0 .. 7] == "4030201");
+    version(LittleEndian)
+        assert(b[0 .. 7] == "4030201");
+    version(BigEndian)
+        assert(b[0 .. 7] == "1020304");
     return 0;
 }
 
diff --git a/gcc/testsuite/gdc.test/runnable/test23.d b/gcc/testsuite/gdc.test/runnable/test23.d
index ee17be0b00f..eac2b20b7dd 100644
--- a/gcc/testsuite/gdc.test/runnable/test23.d
+++ b/gcc/testsuite/gdc.test/runnable/test23.d
@@ -565,7 +565,10 @@ void test25()
 
   auto str3 = cast(wchar[3])("defghi");
   writefln("str3: ", (cast(char[])str3).length , " : ", (cast(char[])str3));
-  assert(cast(char[])str3 == "d\000e\000f\000"c);
+  version(LittleEndian)
+      assert(cast(char[])str3 == "d\000e\000f\000"c);
+  version(BigEndian)
+      assert(cast(char[])str3 == "\000d\000e\000f"c);
 }
 
 /*******************************************/
diff --git a/gcc/testsuite/gdc.test/runnable/test4.d b/gcc/testsuite/gdc.test/runnable/test4.d
index f008da6da72..ff6f6d407ed 100644
--- a/gcc/testsuite/gdc.test/runnable/test4.d
+++ b/gcc/testsuite/gdc.test/runnable/test4.d
@@ -254,6 +254,16 @@ else version(ARM)
     assert(TRECT6.BottomRight.offsetof == 16);
     assert(TRECT6.foo2.offsetof == 24);
 }
+else version(SystemZ)
+{
+    assert(TRECT6.Left.offsetof == 8);
+    assert(TRECT6.Top.offsetof == 12);
+    assert(TRECT6.Right.offsetof == 16);
+    assert(TRECT6.Bottom.offsetof == 20);
+    assert(TRECT6.TopLeft.offsetof == 8);
+    assert(TRECT6.BottomRight.offsetof == 16);
+    assert(TRECT6.foo2.offsetof == 24);
+}
 else
 {
     assert(TRECT6.Left.offsetof == 4);
diff --git a/libphobos/configure.tgt b/libphobos/configure.tgt
index 0471bfd816b..4ea91c949d7 100644
--- a/libphobos/configure.tgt
+++ b/libphobos/configure.tgt
@@ -32,6 +32,8 @@ case "${target}" in
 	;;
   x86_64-*-netbsd* | i?86-*-netbsd*)
 	;;
+  s390*-linux*)
+	;;
   *)
 	UNSUPPORTED=1
 	;;
diff --git a/libphobos/libdruntime/core/sys/posix/fcntl.d b/libphobos/libdruntime/core/sys/posix/fcntl.d
index 817790ab7eb..4665f3abcb0 100644
--- a/libphobos/libdruntime/core/sys/posix/fcntl.d
+++ b/libphobos/libdruntime/core/sys/posix/fcntl.d
@@ -120,6 +120,13 @@ version (CRuntime_Glibc)
     enum F_SETLK        = 6;
     enum F_SETLKW       = 7;
   }
+  else version (SystemZ)
+  {
+    static assert(off_t.sizeof == 8);
+    enum F_GETLK        = 5;
+    enum F_SETLK        = 6;
+    enum F_SETLKW       = 7;
+  }
   else
   static if ( __USE_FILE_OFFSET64 )
   {
diff --git a/libphobos/libdruntime/core/sys/posix/sys/stat.d b/libphobos/libdruntime/core/sys/posix/sys/stat.d
index 8c78ba677a4..fbd556a4ac8 100644
--- a/libphobos/libdruntime/core/sys/posix/sys/stat.d
+++ b/libphobos/libdruntime/core/sys/posix/sys/stat.d
@@ -741,12 +741,12 @@ version (CRuntime_Glibc)
             alias __ino_t = c_ulong;
             alias __ino64_t = ulong;
             alias __mode_t = uint;
-            alias __nlink_t = uint;
+            alias __nlink_t = ulong;
             alias __uid_t = uint;
             alias __gid_t = uint;
             alias __off_t = c_long;
             alias __off64_t = long;
-            alias __blksize_t = int;
+            alias __blksize_t = c_long;
             alias __blkcnt_t = c_long;
             alias __blkcnt64_t = long;
             alias __timespec = timespec;
diff --git a/libphobos/libdruntime/rt/sections_elf_shared.d b/libphobos/libdruntime/rt/sections_elf_shared.d
index d4e1ff07699..5cc7a866fcb 100644
--- a/libphobos/libdruntime/rt/sections_elf_shared.d
+++ b/libphobos/libdruntime/rt/sections_elf_shared.d
@@ -978,7 +978,10 @@ struct tls_index
     }
 }
 
+import gcc.builtins;
+
 extern(C) void* __tls_get_addr(tls_index* ti) nothrow @nogc;
+extern(C) void* __tls_get_addr_internal(tls_index* ti) nothrow @nogc;
 
 /* The dynamic thread vector (DTV) pointers may point 0x8000 past the start of
  * each TLS block. This is at least true for PowerPC and Mips platforms.
@@ -1012,6 +1015,8 @@ else version (MIPS32)
     enum TLS_DTV_OFFSET = 0x8000;
 else version (MIPS64)
     enum TLS_DTV_OFFSET = 0x8000;
+else version (SystemZ)
+    enum TLS_DTV_OFFSET = 0x0;
 else
     static assert( false, "Platform not supported." );
 
@@ -1022,5 +1027,13 @@ void[] getTLSRange(size_t mod, size_t sz) nothrow @nogc
 
     // base offset
     auto ti = tls_index(mod, 0);
-    return (__tls_get_addr(&ti)-TLS_DTV_OFFSET)[0 .. sz];
+
+    version (SystemZ)
+      {
+          auto idx = cast(void *)__tls_get_addr_internal(&ti)
+              + cast(ulong)__builtin_thread_pointer ();
+          return idx[0 .. sz];
+      }
+    else
+        return (__tls_get_addr(&ti)-TLS_DTV_OFFSET)[0 .. sz];
 }
diff --git a/libphobos/src/std/outbuffer.d b/libphobos/src/std/outbuffer.d
index 1d594982cc1..e9301181640 100644
--- a/libphobos/src/std/outbuffer.d
+++ b/libphobos/src/std/outbuffer.d
@@ -408,11 +408,17 @@ class OutBuffer
   {
     OutBuffer buf = new OutBuffer();
     "hello"w.copy(buf);
-    assert(buf.toBytes() == "h\x00e\x00l\x00l\x00o\x00");
+    version(LittleEndian)
+        assert(buf.toBytes() == "h\x00e\x00l\x00l\x00o\x00");
+    version(BigEndian)
+        assert(buf.toBytes() == "\x00h\x00e\x00l\x00l\x00o");
   }
   {
     OutBuffer buf = new OutBuffer();
     "hello"d.copy(buf);
-    assert(buf.toBytes() == "h\x00\x00\x00e\x00\x00\x00l\x00\x00\x00l\x00\x00\x00o\x00\x00\x00");
+    version(LittleEndian)
+        assert(buf.toBytes() == "h\x00\x00\x00e\x00\x00\x00l\x00\x00\x00l\x00\x00\x00o\x00\x00\x00");
+    version(BigEndian)
+        assert(buf.toBytes() == "\x00\x00\x00h\x00\x00\x00e\x00\x00\x00l\x00\x00\x00l\x00\x00\x00o");
   }
 }
diff --git a/libphobos/src/std/uni.d b/libphobos/src/std/uni.d
index 5f24ad16be5..baee073bfc2 100644
--- a/libphobos/src/std/uni.d
+++ b/libphobos/src/std/uni.d
@@ -770,6 +770,8 @@ version (X86)
     enum hasUnalignedReads = true;
 else version (X86_64)
     enum hasUnalignedReads = true;
+else version (SystemZ)
+    enum hasUnalignedReads = true;
 else
     enum hasUnalignedReads = false; // better be safe then sorry
 
@@ -1245,8 +1247,13 @@ pure nothrow:
 
         T opIndex(size_t idx) inout
         {
-            return __ctfe ? simpleIndex(idx) :
+            T ret;
+            version (LittleEndian)
+                ret = __ctfe ? simpleIndex(idx) :
                 cast(inout(T))(cast(U*) origin)[idx];
+            else
+                ret = simpleIndex (idx);
+            return ret;
         }
 
         static if (isBitPacked!T) // lack of user-defined implicit conversion
@@ -1259,10 +1266,15 @@ pure nothrow:
 
         void opIndexAssign(TypeOfBitPacked!T val, size_t idx)
         {
-            if (__ctfe)
-                simpleWrite(val, idx);
-            else
-                (cast(U*) origin)[idx] = cast(U) val;
+          version (LittleEndian)
+            {
+              if (__ctfe)
+                  simpleWrite(val, idx);
+              else
+                  (cast(U*) origin)[idx] = cast(U) val;
+            }
+          else
+              simpleWrite(val, idx);
         }
     }
     else
diff --git a/libphobos/src/std/xml.d b/libphobos/src/std/xml.d
index 770c56fdbfb..a0c5349d013 100644
--- a/libphobos/src/std/xml.d
+++ b/libphobos/src/std/xml.d
@@ -2192,6 +2192,8 @@ private
         catch (Err e) { fail(e); }
     }
 
+    import core.sys.posix.sys.types : ssize_t;
+
     void checkChars(ref string s) @safe pure // rule 2
     {
         // TO DO - Fix std.utf stride and decode functions, then use those
@@ -2201,8 +2203,8 @@ private
         mixin Check!("Chars");
 
         dchar c;
-        int n = -1;
-        foreach (int i,dchar d; s)
+        ssize_t n = -1;
+        foreach (size_t i,dchar d; s)
         {
             if (!isChar(d))
             {
@@ -2238,8 +2240,11 @@ private
         mixin Check!("Name");
 
         if (s.length == 0) fail();
-        int n;
-        foreach (int i,dchar c;s)
+        ssize_t n;
+        // i must not be smaller than size_t because size_t is used internally
+        // in aApply.d and it will be cast e.g. to (int *) which fails on
+        // big-endian machines.
+        foreach (size_t i,dchar c;s)
         {
             if (c == '_' || c == ':' || isLetter(c)) continue;
             if (i == 0) fail();
diff --git a/libphobos/testsuite/libphobos.typeinfo/struct-align.d b/libphobos/testsuite/libphobos.typeinfo/struct-align.d
new file mode 100644
index 00000000000..72866517481
--- /dev/null
+++ b/libphobos/testsuite/libphobos.typeinfo/struct-align.d
@@ -0,0 +1,13 @@
+module structalign;
+
+void main ()
+{
+    struct K { int *a; };
+    K k;
+    auto ti = typeid (k);
+
+    assert (ti.flags () == 1);
+
+    auto ti2 = typeid (k.a);
+    assert (ti.talign () == ti2.talign ());
+}

Reply via email to