On Fri, 15 Mar 2019 at 16:50, Robin Dapp <rd...@linux.ibm.com> wrote:
>
> Hi,
>
> during the last few days I tried to get D running on s390x (apparently
> the first Big Endian platform to try it?).  I did not yet go through the
> code systematically and add a version(SystemZ) in every place where it
> might be needed but rather tried to fix test failures as they arose.
>

HPPA has been somewhat ported, which is BigEndian as well.  But I've
not done any testing beyond just the druntime unittests.

I still have an image available locally and a little more free time
now, so can kickstart a rebuild and start looking at the other
testsuite parts, as the same endian problems should show themselves up
there as well.

>
> After enabling the architecture in the configure files and adding TLS
> support (see initial.diff) the test suite showed 200 something failures.
>

Thanks, I was unsure what to do with the s390 port regarding TLS.

> Including big endian handling in some test cases (tests.diff), the
> number of failures went down to ~130.
>

The changes so far look reasonable, although the version conditions
are LittleEndian and BigEndian.

> Some more involved cases are left: dmd/constfold.c handles
>
>   'a' ~ "abc"
>
> but fails because 'a' is treated as int64 and only the first bytes
> are memcpy'd into the result buffer.  When using a similar logic as
> used for
>
>   "abc" ~ a.
>
> This works but seems a rather hacky approach (cat.diff).
>

Port::valcpy was introduced precisely for the lack of endian-neutral
code in the dmd front-end, so it looks reasonable to me.  I'll send it
upstream if you have no objection to that.

> An even more hacky fix I applied for libdruntime/rt/aaA.d (align.diff)
> where algn = 0 is passed to the talign function.  I suppose it shouldn't
> ever be called with algn = 0 but the alignment should be set somewhere
> else initially?
>

Alignment is written to TypeInfo, I don't think it should ever be
zero.  That would mean that it isn't being generated by the compiler,
or read by the library correctly, so something else is amiss.

> Another problem is printing of characters.  std.uni.isGraphical returns
> false for standard ASCII characters because of the trie traversal or
> rather the final lookup in memory via PackedPtr
>
>   cast(inout(T))(cast(U*) origin)[idx]
>
> This gets the first byte but should get the last byte on Big Endian. A
> simple
>
> +   ubyte[] buf = nativeToLittleEndian (origin[idx]);
> +   auto val = cast(inout(T))(buf.peek!U());
>
> helps here, but has two problems:
>
>  - peek!U() apparently does not work in CTFE and subsequently all
> compile-time unit tests fail.
>  - simpleIndex() is called in other places and also does the wrong thing
>
>   return cast(T)((origin[q] >> bits*r) & mask)
>
> Refraining from peek!... I tried working around it by extracting bytes
> and reversing the order but this seems to hacky to create a diff :)
> I got it to work for test28.d:test39() but the unit tests still fail.
>
> Is there a way to debug the compile-time unit tests easily? What's the
> preferred method to do "the right thing" even at compile time? Any other
> things that should be looked at? Any comments to the diffs so far?
>

There's pragma(msg) that can be used in user code.

i.e:
    int foo() { return 42; }
    enum A = foo();
    pragma(msg, A);  // Prints '42' at compile-time.

Otherwise, it's just stepping through CTFE in the compiler front-end
(dmd/dinterpret.c, entrypoint is interpret), and using e->toChars() /
s->toChars() to get the string representation of intermediate
expressions/values.

--
Iain

Reply via email to